【问题标题】:where is the C language global array located in its disassembly codeC 语言全局数组在其反汇编代码中的位置在哪里
【发布时间】:2014-10-08 07:52:21
【问题描述】:

我写了一个非常简单的C代码如下:

int data_items[] = {3,67,32,4,89,6,34,2,9,0};

int max(int* pt)
{
  int val = *pt;
  while(*pt != 0)
  {
    if (*pt > val)
    {
      val = *pt;
    }
    ++pt;
  }
  return val;
}

int main()
{

  max(data_items);

  return 0;
}

然后我用 gcc 编译它:

gcc main.c

然后拆解它:

objdump -d a.out

最后我得到了汇编代码:

a.out:     file format elf64-x86-64


Disassembly of section .init:

00000000004003a8 <_init>:
  4003a8:   48 83 ec 08             sub    $0x8,%rsp
  4003ac:   48 8b 05 45 0c 20 00    mov    0x200c45(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
  4003b3:   48 85 c0                test   %rax,%rax
  4003b6:   74 05                   je     4003bd <_init+0x15>
  4003b8:   e8 33 00 00 00          callq  4003f0 <__gmon_start__@plt>
  4003bd:   48 83 c4 08             add    $0x8,%rsp
  4003c1:   c3                      retq   

Disassembly of section .plt:

00000000004003d0 <__libc_start_main@plt-0x10>:
  4003d0:   ff 35 32 0c 20 00       pushq  0x200c32(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  4003d6:   ff 25 34 0c 20 00       jmpq   *0x200c34(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  4003dc:   0f 1f 40 00             nopl   0x0(%rax)

00000000004003e0 <__libc_start_main@plt>:
  4003e0:   ff 25 32 0c 20 00       jmpq   *0x200c32(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  4003e6:   68 00 00 00 00          pushq  $0x0
  4003eb:   e9 e0 ff ff ff          jmpq   4003d0 <_init+0x28>

00000000004003f0 <__gmon_start__@plt>:
  4003f0:   ff 25 2a 0c 20 00       jmpq   *0x200c2a(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  4003f6:   68 01 00 00 00          pushq  $0x1
  4003fb:   e9 d0 ff ff ff          jmpq   4003d0 <_init+0x28>

Disassembly of section .text:

0000000000400400 <_start>:
  400400:   31 ed                   xor    %ebp,%ebp
  400402:   49 89 d1                mov    %rdx,%r9
  400405:   5e                      pop    %rsi
  400406:   48 89 e2                mov    %rsp,%rdx
  400409:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  40040d:   50                      push   %rax
  40040e:   54                      push   %rsp
  40040f:   49 c7 c0 b0 05 40 00    mov    $0x4005b0,%r8
  400416:   48 c7 c1 40 05 40 00    mov    $0x400540,%rcx
  40041d:   48 c7 c7 28 05 40 00    mov    $0x400528,%rdi
  400424:   e8 b7 ff ff ff          callq  4003e0 <__libc_start_main@plt>
  400429:   f4                      hlt    
  40042a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

0000000000400430 <deregister_tm_clones>:
  400430:   b8 8f 10 60 00          mov    $0x60108f,%eax
  400435:   55                      push   %rbp
  400436:   48 2d 88 10 60 00       sub    $0x601088,%rax
  40043c:   48 83 f8 0e             cmp    $0xe,%rax
  400440:   48 89 e5                mov    %rsp,%rbp
  400443:   77 02                   ja     400447 <deregister_tm_clones+0x17>
  400445:   5d                      pop    %rbp
  400446:   c3                      retq   
  400447:   b8 00 00 00 00          mov    $0x0,%eax
  40044c:   48 85 c0                test   %rax,%rax
  40044f:   74 f4                   je     400445 <deregister_tm_clones+0x15>
  400451:   5d                      pop    %rbp
  400452:   bf 88 10 60 00          mov    $0x601088,%edi
  400457:   ff e0                   jmpq   *%rax
  400459:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000400460 <register_tm_clones>:
  400460:   b8 88 10 60 00          mov    $0x601088,%eax
  400465:   55                      push   %rbp
  400466:   48 2d 88 10 60 00       sub    $0x601088,%rax
  40046c:   48 c1 f8 03             sar    $0x3,%rax
  400470:   48 89 e5                mov    %rsp,%rbp
  400473:   48 89 c2                mov    %rax,%rdx
  400476:   48 c1 ea 3f             shr    $0x3f,%rdx
  40047a:   48 01 d0                add    %rdx,%rax
  40047d:   48 d1 f8                sar    %rax
  400480:   75 02                   jne    400484 <register_tm_clones+0x24>
  400482:   5d                      pop    %rbp
  400483:   c3                      retq   
  400484:   ba 00 00 00 00          mov    $0x0,%edx
  400489:   48 85 d2                test   %rdx,%rdx
  40048c:   74 f4                   je     400482 <register_tm_clones+0x22>
  40048e:   5d                      pop    %rbp
  40048f:   48 89 c6                mov    %rax,%rsi
  400492:   bf 88 10 60 00          mov    $0x601088,%edi
  400497:   ff e2                   jmpq   *%rdx
  400499:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004004a0 <__do_global_dtors_aux>:
  4004a0:   80 3d e1 0b 20 00 00    cmpb   $0x0,0x200be1(%rip)        # 601088 <__TMC_END__>
  4004a7:   75 11                   jne    4004ba <__do_global_dtors_aux+0x1a>
  4004a9:   55                      push   %rbp
  4004aa:   48 89 e5                mov    %rsp,%rbp
  4004ad:   e8 7e ff ff ff          callq  400430 <deregister_tm_clones>
  4004b2:   5d                      pop    %rbp
  4004b3:   c6 05 ce 0b 20 00 01    movb   $0x1,0x200bce(%rip)        # 601088 <__TMC_END__>
  4004ba:   f3 c3                   repz retq 
  4004bc:   0f 1f 40 00             nopl   0x0(%rax)

00000000004004c0 <frame_dummy>:
  4004c0:   48 83 3d 58 09 20 00    cmpq   $0x0,0x200958(%rip)        # 600e20 <__JCR_END__>
  4004c7:   00 
  4004c8:   74 1e                   je     4004e8 <frame_dummy+0x28>
  4004ca:   b8 00 00 00 00          mov    $0x0,%eax
  4004cf:   48 85 c0                test   %rax,%rax
  4004d2:   74 14                   je     4004e8 <frame_dummy+0x28>
  4004d4:   55                      push   %rbp
  4004d5:   bf 20 0e 60 00          mov    $0x600e20,%edi
  4004da:   48 89 e5                mov    %rsp,%rbp
  4004dd:   ff d0                   callq  *%rax
  4004df:   5d                      pop    %rbp
  4004e0:   e9 7b ff ff ff          jmpq   400460 <register_tm_clones>
  4004e5:   0f 1f 00                nopl   (%rax)
  4004e8:   e9 73 ff ff ff          jmpq   400460 <register_tm_clones>

00000000004004ed <max>:
  4004ed:   55                      push   %rbp
  4004ee:   48 89 e5                mov    %rsp,%rbp
  4004f1:   48 89 7d e8             mov    %rdi,-0x18(%rbp)
  4004f5:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  4004f9:   8b 00                   mov    (%rax),%eax
  4004fb:   89 45 fc                mov    %eax,-0x4(%rbp)
  4004fe:   eb 19                   jmp    400519 <max+0x2c>
  400500:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  400504:   8b 00                   mov    (%rax),%eax
  400506:   3b 45 fc                cmp    -0x4(%rbp),%eax
  400509:   7e 09                   jle    400514 <max+0x27>
  40050b:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  40050f:   8b 00                   mov    (%rax),%eax
  400511:   89 45 fc                mov    %eax,-0x4(%rbp)
  400514:   48 83 45 e8 04          addq   $0x4,-0x18(%rbp)
  400519:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  40051d:   8b 00                   mov    (%rax),%eax
  40051f:   85 c0                   test   %eax,%eax
  400521:   75 dd                   jne    400500 <max+0x13>
  400523:   8b 45 fc                mov    -0x4(%rbp),%eax
  400526:   5d                      pop    %rbp
  400527:   c3                      retq   

0000000000400528 <main>:
  400528:   55                      push   %rbp
  400529:   48 89 e5                mov    %rsp,%rbp
  40052c:   bf 60 10 60 00          mov    $0x601060,%edi
  400531:   e8 b7 ff ff ff          callq  4004ed <max>
  400536:   b8 00 00 00 00          mov    $0x0,%eax
  40053b:   5d                      pop    %rbp
  40053c:   c3                      retq   
  40053d:   0f 1f 00                nopl   (%rax)

0000000000400540 <__libc_csu_init>:
  400540:   41 57                   push   %r15
  400542:   41 89 ff                mov    %edi,%r15d
  400545:   41 56                   push   %r14
  400547:   49 89 f6                mov    %rsi,%r14
  40054a:   41 55                   push   %r13
  40054c:   49 89 d5                mov    %rdx,%r13
  40054f:   41 54                   push   %r12
  400551:   4c 8d 25 b8 08 20 00    lea    0x2008b8(%rip),%r12        # 600e10 <__frame_dummy_init_array_entry>
  400558:   55                      push   %rbp
  400559:   48 8d 2d b8 08 20 00    lea    0x2008b8(%rip),%rbp        # 600e18 <__init_array_end>
  400560:   53                      push   %rbx
  400561:   4c 29 e5                sub    %r12,%rbp
  400564:   31 db                   xor    %ebx,%ebx
  400566:   48 c1 fd 03             sar    $0x3,%rbp
  40056a:   48 83 ec 08             sub    $0x8,%rsp
  40056e:   e8 35 fe ff ff          callq  4003a8 <_init>
  400573:   48 85 ed                test   %rbp,%rbp
  400576:   74 1e                   je     400596 <__libc_csu_init+0x56>
  400578:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  40057f:   00 
  400580:   4c 89 ea                mov    %r13,%rdx
  400583:   4c 89 f6                mov    %r14,%rsi
  400586:   44 89 ff                mov    %r15d,%edi
  400589:   41 ff 14 dc             callq  *(%r12,%rbx,8)
  40058d:   48 83 c3 01             add    $0x1,%rbx
  400591:   48 39 eb                cmp    %rbp,%rbx
  400594:   75 ea                   jne    400580 <__libc_csu_init+0x40>
  400596:   48 83 c4 08             add    $0x8,%rsp
  40059a:   5b                      pop    %rbx
  40059b:   5d                      pop    %rbp
  40059c:   41 5c                   pop    %r12
  40059e:   41 5d                   pop    %r13
  4005a0:   41 5e                   pop    %r14
  4005a2:   41 5f                   pop    %r15
  4005a4:   c3                      retq   
  4005a5:   66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  4005ac:   00 00 00 00 

00000000004005b0 <__libc_csu_fini>:
  4005b0:   f3 c3                   repz retq 

Disassembly of section .fini:

00000000004005b4 <_fini>:
  4005b4:   48 83 ec 08             sub    $0x8,%rsp
  4005b8:   48 83 c4 08             add    $0x8,%rsp
  4005bc:   c3                      retq   

我的问题是,在主要功能中:

  40052c:   bf 60 10 60 00          mov    $0x601060,%edi

地址 $0x601060 应该是 C 代码中数组 data_items 的地址。但是我在汇编代码中找不到data_items数组值,它在哪里?

顺便说一下,在max函数代码中:

4004f1: 48 89 7d e8             mov    %rdi,-0x18(%rbp)

我确实认为堆栈应该是:

mov %rdi, -0x8(%rbp)

为什么编译器会在堆栈中造成一些漏洞?

我的系统是 Ubuntu 14.04 LTS。

【问题讨论】:

  • 全局数组初始化器通常位于.data 部分。也许您的反汇编程序没有显示该部分?

标签: c assembly


【解决方案1】:

objdump -d 只反汇编可执行文件中应该有代码的部分。

使用objdump -D反汇编所有部分,你会发现:

Disassembly of section .data:

08049760 <__data_start>:
        ...

08049780 <data_items>:
 8049780:       03 00                   add    (%eax),%eax
 8049782:       00 00                   add    %al,(%eax)
 8049784:       43                      inc    %ebx
 8049785:       00 00                   add    %al,(%eax)
 8049787:       00 20                   add    %ah,(%eax)
 8049789:       00 00                   add    %al,(%eax)
 804978b:       00 04 00                add    %al,(%eax,%eax,1)
 804978e:       00 00                   add    %al,(%eax)

那是你的数组。 objdump 将尝试将其反汇编为机器码,因此汇编没有意义)。

【讨论】:

  • 它工作正常。你能解释一下为什么 mov %rdi,-0x18(%rbp) 会跳过一些堆栈空间吗?
  • @Dan 该问题与 SO 上的许多现有问题重复(stackoverflow.com/questions/19128291/… 不是完美的重复,但应该让您走上正轨)。如果您想回答所有问题,每个问题只输入一个问题(并在提问之前搜索网站以查找现有答案)。
【解决方案2】:

如果你运行nm a.out,你会看到0x601060data_items的地址。

【讨论】:

    【解决方案3】:

    当涉及到运行时反汇编时,gdb 本身可以非常方便:

    (gdb) break main
    Breakpoint 1 at 0x4004f3
    (gdb) break max
    Breakpoint 2 at 0x4004b8
    (gdb) run
    Starting program: /home/dtarcatu/workspace/ctest/a.out 
    
    Breakpoint 1, 0x00000000004004f3 in main ()
    (gdb) disas
    Dump of assembler code for function main:
       0x00000000004004ef <+0>: push   %rbp
       0x00000000004004f0 <+1>: mov    %rsp,%rbp
    => 0x00000000004004f3 <+4>: mov    $0x601040,%edi
       0x00000000004004f8 <+9>: callq  0x4004b4 <max>
       0x00000000004004fd <+14>:    mov    $0x0,%eax
       0x0000000000400502 <+19>:    pop    %rbp
       0x0000000000400503 <+20>:    retq   
    End of assembler dump.
    (gdb) x 0x601040
    0x601040 <data_items>:  0x00000003
    (gdb) x /10d 0x601040
    0x601040 <data_items>:  3   67  32  4
    0x601050 <data_items+16>:   89  6   34  2
    0x601060 <data_items+32>:   9   0
    

    现在关于你的堆栈纪律困境,我不确定我能想出一个很好的答案,但我认为它与 x86-64 red zone optimization 有关。

    (gdb) c
     Continuing.
    
    Breakpoint 2, 0x00000000004004b8 in max ()
    (gdb) disas
    Dump of assembler code for function max:
       0x00000000004004b4 <+0>: push   %rbp
       0x00000000004004b5 <+1>: mov    %rsp,%rbp
    => 0x00000000004004b8 <+4>: mov    %rdi,-0x18(%rbp)
       0x00000000004004bc <+8>: mov    -0x18(%rbp),%rax
       0x00000000004004c0 <+12>:    mov    (%rax),%eax
       0x00000000004004c2 <+14>:    mov    %eax,-0x4(%rbp)
       0x00000000004004c5 <+17>:    jmp    0x4004e0 <max+44>
       0x00000000004004c7 <+19>:    mov    -0x18(%rbp),%rax
       0x00000000004004cb <+23>:    mov    (%rax),%eax
       0x00000000004004cd <+25>:    cmp    -0x4(%rbp),%eax
       0x00000000004004d0 <+28>:    jle    0x4004db <max+39>
       0x00000000004004d2 <+30>:    mov    -0x18(%rbp),%rax
       0x00000000004004d6 <+34>:    mov    (%rax),%eax
       0x00000000004004d8 <+36>:    mov    %eax,-0x4(%rbp)
       0x00000000004004db <+39>:    addq   $0x4,-0x18(%rbp)
       0x00000000004004e0 <+44>:    mov    -0x18(%rbp),%rax
       0x00000000004004e4 <+48>:    mov    (%rax),%eax
       0x00000000004004e6 <+50>:    test   %eax,%eax
       0x00000000004004e8 <+52>:    jne    0x4004c7 <max+19>
       0x00000000004004ea <+54>:    mov    -0x4(%rbp),%eax
       0x00000000004004ed <+57>:    pop    %rbp
       0x00000000004004ee <+58>:    retq   
    End of assembler dump.
    (gdb) ni
    0x00000000004004bc in max ()
    (gdb) print $rbp
    $1 = (void *) 0x7fffffffdf10
    (gdb) print $rsp
    $2 = (void *) 0x7fffffffdf10
    

    -0x18(%rbp) 位置肯定在红色区域内。我不确定编译器是如何使用它的,但它可能可以做任何它想要的黑客攻击。您的本地 int 似乎稍后会存储在 -0x4(%rbp),所以我猜 -0x18(%rbp) 只是某种临时缓冲区。

    【讨论】:

      【解决方案4】:

      您还可以要求编译器输出其发出的汇编代码。请注意,您的程序中没有可观察到的副作用,因此编译器可以将其优化为 nop - 或在编译时计算最大值等。

      但是,使用 (GCC 4.9.1 Debian/x86-64) 编译您的代码

       gcc -fverbose-asm -O -S main.c
      

      我得到一个文件 main.s 包含(前后有几行):

          .globl  max
          .type   max, @function
      max:
      .LFB0:
          .file 1 "main.c"
          .loc 1 4 0
          .cfi_startproc
      .LVL0:
          .loc 1 5 0
          movl    (%rdi), %eax    # *pt_5(D), val
      .LVL1:
          .loc 1 6 0
          testl   %eax, %eax  # val
          je  .L2 #,
          movl    %eax, %edx  # val, val
      .L3:
          cmpl    %edx, %eax  # val, val
          cmovl   %edx, %eax  # val,, val, val
      .LVL2:
          .loc 1 12 0
          addq    $4, %rdi    #, pt
      .LVL3:
          .loc 1 6 0
          movl    (%rdi), %edx    # MEM[base: pt_8, offset: 0B], val
          testl   %edx, %edx  # val
          jne .L3 #,
      .L2:
          .loc 1 15 0
          rep ret
          .cfi_endproc
      .LFE0:
          .size   max, .-max
          .globl  main
          .type   main, @function
      main:
      .LFB1:
          .loc 1 18 0
          .cfi_startproc
          .loc 1 20 0
          movl    $data_items, %edi   #,
          call    max #
      .LVL4:
          .loc 1 23 0
          movl    $0, %eax    #,
          ret
          .cfi_endproc
      .LFE1:
          .size   main, .-main
          .globl  data_items
          .data
          .align 32
          .type   data_items, @object
          .size   data_items, 40
      data_items:
          .long   3
          .long   67
          .long   32
          .long   4
          .long   89
          .long   6
          .long   34
          .long   2
          .long   9
          .long   0
          .text
      

      所以你看到 data_items 进入 data 部分(因为 .data 指令)

      顺便说一句,GCC 通常会发出一个由as 汇编器转换为包含object codeELF 文件main.o 的汇编器文件。该目标文件包含relocation 指令和几个部分,稍后由ld linker 处理。

      【讨论】:

        猜你喜欢
        • 2015-02-19
        • 1970-01-01
        • 1970-01-01
        • 2014-08-16
        • 2015-10-31
        • 2023-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多