理解 gdb 输出

逆向工程 拆卸 数据库 小精灵
2021-07-04 08:13:07

所以我在搞乱 gdb 并遇到了一些很有趣的事情。我将以下代码运行到 gdb 中:

int i, g = 1;
for (i = 0; i < 100; i++)
          g++;

在执行之前,disas main产生:

   0x000000000000064a <+0>: push   %rbp
   0x000000000000064b <+1>: mov    %rsp,%rbp
   0x000000000000064e <+4>: sub    $0x10,%rsp
   0x0000000000000652 <+8>: movl   $0x1,-0x4(%rbp)
   0x0000000000000659 <+15>:    movl   $0x0,-0x8(%rbp)
   0x0000000000000660 <+22>:    jmp    0x66a <main+32>
   0x0000000000000662 <+24>:    addl   $0x1,-0x4(%rbp)
   0x0000000000000666 <+28>:    addl   $0x1,-0x8(%rbp)
   0x000000000000066a <+32>:    cmpl   $0x63,-0x8(%rbp)
   0x000000000000066e <+36>:    jle    0x662 <main+24>
   0x0000000000000670 <+38>:    mov    -0x4(%rbp),%eax
   ...

有趣的是,在run之后,事情看起来不一样了:

   0x000055555555464a <+0>: push   %rbp
   0x000055555555464b <+1>: mov    %rsp,%rbp
   0x000055555555464e <+4>: sub    $0x10,%rsp
   0x0000555555554652 <+8>: movl   $0x1,-0x4(%rbp)
   0x0000555555554659 <+15>:    movl   $0x0,-0x8(%rbp)
   0x0000555555554660 <+22>:    jmp    0x55555555466a <main+32>
   0x0000555555554662 <+24>:    addl   $0x1,-0x4(%rbp)
   0x0000555555554666 <+28>:    addl   $0x1,-0x8(%rbp)
   0x000055555555466a <+32>:    cmpl   $0x63,-0x8(%rbp)
   0x000055555555466e <+36>:    jle    0x555555554662 <main+24>
   0x0000555555554670 <+38>:    mov    -0x4(%rbp),%eax
   ...

这里发生了什么?为什么执行前地址不同?

编辑:

info proc 映射的输出

      Start Addr           End Addr       Size     Offset objfile
  0x555555554000     0x555555555000     0x1000        0x0 /tmp/test
  0x555555754000     0x555555755000     0x1000        0x0 /tmp/test
  0x555555755000     0x555555756000     0x1000     0x1000 /tmp/test
  0x7ffff7a21000     0x7ffff7bcf000   0x1ae000        0x0 /usr/lib/libc-2.26.so
  0x7ffff7bcf000     0x7ffff7dce000   0x1ff000   0x1ae000 /usr/lib/libc-2.26.so
  0x7ffff7dce000     0x7ffff7dd2000     0x4000   0x1ad000 /usr/lib/libc-2.26.so
  0x7ffff7dd2000     0x7ffff7dd4000     0x2000   0x1b1000 /usr/lib/libc-2.26.so
  0x7ffff7dd4000     0x7ffff7dd8000     0x4000        0x0 
  0x7ffff7dd8000     0x7ffff7dfd000    0x25000        0x0 /usr/lib/ld-2.26.so
  0x7ffff7fcc000     0x7ffff7fce000     0x2000        0x0 
  0x7ffff7ff7000     0x7ffff7ffa000     0x3000        0x0 [vvar]
  0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
  0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x24000 /usr/lib/ld-2.26.so
  0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x25000 /usr/lib/ld-2.26.so
  0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
  0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]

维护信息部分

file type elf64-x86-64.
 [0]     0x00000238->0x00000254 at 0x00000238: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
 [1]     0x00000254->0x00000274 at 0x00000254: .note.ABI-tag ALLOC LOAD READONLY DATA HAS_CONTENTS
 [2]     0x00000274->0x00000298 at 0x00000274: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
 [3]     0x00000298->0x000002b4 at 0x00000298: .gnu.hash ALLOC LOAD READONLY DATA HAS_CONTENTS
 [4]     0x000002b8->0x00000360 at 0x000002b8: .dynsym ALLOC LOAD READONLY DATA HAS_CONTENTS
 [5]     0x00000360->0x000003e4 at 0x00000360: .dynstr ALLOC LOAD READONLY DATA HAS_CONTENTS
 [6]     0x000003e4->0x000003f2 at 0x000003e4: .gnu.version ALLOC LOAD READONLY DATA HAS_CONTENTS
 [7]     0x000003f8->0x00000418 at 0x000003f8: .gnu.version_r ALLOC LOAD READONLY DATA HAS_CONTENTS
 [8]     0x00000418->0x000004f0 at 0x00000418: .rela.dyn ALLOC LOAD READONLY DATA HAS_CONTENTS
 [9]     0x000004f0->0x00000508 at 0x000004f0: .rela.plt ALLOC LOAD READONLY DATA HAS_CONTENTS
 [10]     0x00000508->0x0000051f at 0x00000508: .init ALLOC LOAD READONLY CODE HAS_CONTENTS
 [11]     0x00000520->0x00000540 at 0x00000520: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS
 [12]     0x00000540->0x00000702 at 0x00000540: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
 [13]     0x00000704->0x0000070d at 0x00000704: .fini ALLOC LOAD READONLY CODE HAS_CONTENTS
 [14]     0x00000710->0x00000718 at 0x00000710: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS
 [15]     0x00000718->0x0000074c at 0x00000718: .eh_frame_hdr ALLOC LOAD READONLY DATA HAS_CONTENTS
 [16]     0x00000750->0x00000840 at 0x00000750: .eh_frame ALLOC LOAD READONLY DATA HAS_CONTENTS
 [17]     0x00200de0->0x00200de8 at 0x00000de0: .init_array ALLOC LOAD DATA HAS_CONTENTS
 [18]     0x00200de8->0x00200df0 at 0x00000de8: .fini_array ALLOC LOAD DATA HAS_CONTENTS
 [19]     0x00200df0->0x00200fd0 at 0x00000df0: .dynamic ALLOC LOAD DATA HAS_CONTENTS
 [20]     0x00200fd0->0x00201000 at 0x00000fd0: .got ALLOC LOAD DATA HAS_CONTENTS
 [21]     0x00201000->0x00201020 at 0x00001000: .got.plt ALLOC LOAD DATA HAS_CONTENTS
 [22]     0x00201020->0x00201030 at 0x00001020: .data ALLOC LOAD DATA HAS_CONTENTS
 [23]     0x00201030->0x00201038 at 0x00001030: .bss ALLOC
 [24]     0x00000000->0x00000011 at 0x00001030: .comment READONLY HAS_CONTENTS
1个回答

好像搬迁如果您查看第一个列表中的地址,您会注意到这些地址异常低。这可能是因为 gdb 在那里显示文件偏移量(尽管我不知道为什么会出现这种情况)。

当您运行文件时,加载器启动并将节映射到程序的虚拟地址空间,这就是0x0000555555554000节偏移量的来源。

您可以使用maint info sections. 您可以info proc mappings在运行时获取有关实际映射内存部分的信息

编辑:

根据上面命令的输出,一切似乎都很好。

[12]     0x00000540->0x00000702 at 0x00000540: .text ALLOC LOAD READONLY CODE HAS_CONTENTS

这一行表明.text您的代码部分从文件偏移 0x540 开始,并在包含代码的 0x702 结束。如果您将它与从偏移量 0x64a 开始的第一次反汇编进行比较,这是一个不错的选择。

0x555555554000     0x555555555000     0x1000        0x0 /tmp/test

这一行表明可执行文件本身被映射到基地址0x555555554000鉴于之前的偏移量,这意味着您的主要功能应该在0x555555554000 + 0x64a. 您的第二次拆解证实了这一点。