关于逆向工程:从GDB中的第一条机器代码指令开始

Stopping at the first machine code instruction in GDB

将可执行文件加载到gdb中后,如何在执行第一条指令之前在入口点处中断?

我正在分析的可执行文件是一种经过加密的恶意软件,因此break main绝对不执行任何操作。


info files命令可能会为您提供一个可以中断的地址:

1
2
3
4
5
6
(gdb) info files
    ...
    Entry point: 0x80000000
    ...
(gdb) break *0x80000000
(gdb) run


从GDB 8.1开始,有一个特殊的命令:starti。 GDB会话示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) starti
Starting program: /bin/true

Program stopped.
0xf7fdd800 in _start () from /lib/ld-linux.so.2
(gdb) x/5i $pc
=> 0xf7fdd800 <_start>: mov    eax,esp
   0xf7fdd802 <_start+2>:       call   0xf7fe2160 <_dl_start>
   0xf7fdd807 <_dl_start_user>: mov    edi,eax
   0xf7fdd809 <_dl_start_user+2>:       call   0xf7fdd7f0
   0xf7fdd80e <_dl_start_user+7>:       add    ebx,0x1f7e6


此黑客已被starti淘汰,但如果您使用较旧的GDB,则很有用。

明智的解决方案是利用失败的副作用来设置断点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) b *0
Breakpoint 1 at 0x0
(gdb) r
Starting program: /bin/true
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x0

(gdb) disas
Dump of assembler code for function _start:
=> 0xf7fdd800 <+0>:     mov    eax,esp
   0xf7fdd802 <+2>:     call   0xf7fe2160 <_dl_start>
End of assembler dump.

(gdb) d 1       # delete the faulty breakpoint

(您需要delete无效的断点,然后才能继续或单步执行。)

从RE.SE的答案中得到的想法。


" b _start"或" b start"可能会或可能不会工作。 如果不是,请使用readelf / objdump找出入口点地址,然后使用" b *0x"。


After loading an executable into gdb, how do I break at the entry point, before the first instruction is executed?

您可以找到在int main()set backtrace past-main on之前调用的函数,并在找到它们之后在它们上设置断点并重新启动程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>gdb  -q  main
Reading symbols from /home/main...done.
(gdb) set backtrace past-main on
(gdb) b main
Breakpoint 1 at 0x40058a: file main.cpp, line 25.
(gdb) r
Starting program: /home/main

Breakpoint 1, main () at main.cpp:25
25        a();
(gdb) bt
#0  main () at main.cpp:25
#1  0x0000003a1d81ed1d in __libc_start_main () from /lib64/libc.so.6
#2  0x0000000000400499 in _start ()
(gdb) b _start
Breakpoint 2 at 0x400470
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/main

Breakpoint 2, 0x0000000000400470 in _start ()