同一个功能不同的反汇编?

逆向工程 拆卸 数据库 转储
2021-06-24 00:47:39

我有这个代码:

#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
};

我用gcc -g 3arg.cpp. objdump -d -M intel a.out. 在输出中,只有一个名为的函数_init,它的反汇编如下:

00000000004003e0 <_init>:
  4003e0:       48 83 ec 08             sub    rsp,0x8
  4003e4:       48 8b 05 0d 0c 20 00    mov    rax,QWORD PTR [rip+0x200c0d]        # 600ff8 <_DYNAMIC+0x1d0>
  4003eb:       48 85 c0                test   rax,rax
  4003ee:       74 05                   je     4003f5 <_init+0x15>
  4003f0:       e8 3b 00 00 00          call   400430 <__gmon_start__@plt>
  4003f5:       48 83 c4 08             add    rsp,0x8
  4003f9:       c3                      ret

这是gdb输出:

$ gdb -q a.out
Reading symbols from a.out...done.
(gdb) disassemble _init
Dump of assembler code for function _init:
   0x00000000004003e0 <+0>:  sub    $0x8,%rsp
   0x00000000004003e4 <+4>:  mov    0x200c0d(%rip),%rax        # 0x600ff8
   0x00000000004003eb <+11>: test   %rax,%rax
   0x00000000004003ee <+14>: je     0x4003f5 <_init+21>
   0x00000000004003f0 <+16>: callq  0x400430 <__gmon_start__@plt>
   0x00000000004003f5 <+21>: add    $0x8,%rsp
   0x00000000004003f9 <+25>: retq   
End of assembler dump.
(gdb) break _init
Breakpoint 1 at 0x4003e0
(gdb) run
Starting program: [redacted]/a.out 

Breakpoint 1, _init (argc=1, argv=0x7fffffffdf68, envp=0x7fffffffdf78) at ../csu/init-first.c:52
52  ../csu/init-first.c: No such file or directory.
(gdb) disassemble _init
Dump of assembler code for function _init:
=> 0x00007ffff7a36c20 <+0>:  push   %r13
   0x00007ffff7a36c22 <+2>:  push   %r12
   0x00007ffff7a36c24 <+4>:  mov    %edi,%r12d
   0x00007ffff7a36c27 <+7>:  push   %rbp
   0x00007ffff7a36c28 <+8>:  mov    %rsi,%rbp
   0x00007ffff7a36c2b <+11>: push   %rbx
[etc.]

为什么上次拆机不一样?它甚至不是以不同方式反汇编的相同数据(如在断点被击中时将objdump输出与gdb命令输出进行比较时所见x/10b $rip)。如果是不同的_init功能:

  • 如何在objdump输出中看到的断点和第一个反汇编中的断点gdb
  • 为什么gdb说断点 1 是0x4003e0在一个不同的函数然后停止?
1个回答

要到达您的_init功能,只需继续执行即可。这将在预定位置再次停止。

    gdb -q test.out
    Reading symbols from test.out...done.
    (gdb) b _init
    Breakpoint 1 at 0x4003e0
    (gdb) run
    Starting program: /home/[censored]/stk/test.out 

    Breakpoint 1, _init (argc=1, argv=0x7fffffffe008, envp=0x7fffffffe018) at ../csu/init-first.c:52
    52  ../csu/init-first.c: No such file or directory.
    (gdb) bt
    #0  _init (argc=1, argv=0x7fffffffe008, envp=0x7fffffffe018) at ../csu/init-first.c:52
    #1  0x00007ffff7dea0fd in call_init (l=0x7ffff7ff74c0, argc=argc@entry=1, argv=argv@entry=0x7fffffffe008, env=env@entry=0x7fffffffe018) at dl-init.c:64
    #2  0x00007ffff7dea223 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=<optimized out>) at dl-init.c:36
    #3  _dl_init (main_map=0x7ffff7ffe1c8, argc=1, argv=0x7fffffffe008, env=0x7fffffffe018) at dl-init.c:126
    #4  0x00007ffff7ddb30a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
    #5  0x0000000000000001 in ?? ()
    #6  0x00007fffffffe364 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) c
    Continuing.

    Breakpoint 1, 0x00000000004003e0 in _init ()
    (gdb) bt
    #0  0x00000000004003e0 in _init ()
    #1  0x0000000000400593 in __libc_csu_init ()
    #2  0x00007ffff7a36e55 in __libc_start_main (main=0x40052d <main>, argc=1, argv=0x7fffffffe008, init=0x400560 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdff8)
        at libc-start.c:246
    #3  0x0000000000400469 in _start ()
    (gdb) info shared
    From                To                  Syms Read   Shared Object Library
    0x00007ffff7ddaae0  0x00007ffff7df54e0  Yes         /lib64/ld-linux-x86-64.so.2
    0x00007ffff7a344a0  0x00007ffff7b79583  Yes         /lib/x86_64-linux-gnu/libc.so.6
    (gdb) x/10i $pc
=> 0x4003e0 <_init>:    sub    $0x8,%rsp
   0x4003e4 <_init+4>:  mov    0x200c0d(%rip),%rax        # 0x600ff8
   0x4003eb <_init+11>: test   %rax,%rax
   0x4003ee <_init+14>: je     0x4003f5 <_init+21>
   0x4003f0 <_init+16>: callq  0x400430 <__gmon_start__@plt>
   0x4003f5 <_init+21>: add    $0x8,%rsp
   0x4003f9 <_init+25>: retq 
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>         
    breakpoint already hit 2 times
1.1                         y     0x00000000004003e0 <_init>
1.2                         y     0x00007ffff7a36c20 in _init at ../csu/init-first.c:52

根据共享库的信息,它第一次停在 的地址区libc.so,看起来也有_init功能,导致gdb在那里也设置了这个断点(见清单末尾的断点定义)。

如果要在特定地址中设置断点,可以使用

 b *address

符号。如果您想在特定源文件中的特定函数上设置断点,您可以使用类似

(gdb) break test.c:call1

同样的事情在这里讨论得更深入一点

祝你好运。