在GDB中的第一条机器代码指令处停止

在GDB中的第一条机器代码指令处停止,gdb,reverse-engineering,Gdb,Reverse Engineering,在将可执行文件加载到gdb之后,如何在执行第一条指令之前在入口点中断 我正在分析的可执行文件是一个经过加密的恶意软件,因此break main绝对不起任何作用。使用info files命令可能会为您提供一个可以破解的地址: (gdb) info files ... Entry point: 0x80000000 ... (gdb) break *0x80000000 (gdb) run “b\u start”或“b start”可能有效,也可能无效。如果没有,请使用re

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


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

使用
info files
命令可能会为您提供一个可以破解的地址:

(gdb) info files
    ...
    Entry point: 0x80000000
    ...
(gdb) break *0x80000000
(gdb) run
b\u start
”或“
b start
”可能有效,也可能无效。如果没有,请使用readelf/objdump查找入口点地址并使用“
b*0x

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

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

>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 ()

这项技术已被starti淘汰,但如果您仍使用较旧的GDB,它将非常有用

更简单的解决方案是利用失败的副作用设置断点:

$ 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
$gdb/bin/true
正在从/bin/true…读取符号(未找到调试符号)…已完成。
(gdb)b*0
断点1位于0x0
(gdb)r
正在启动程序:/bin/true
警告:
无法插入断点1。
无法访问地址0x0处的内存
(gdb)disas
函数_start的汇编程序代码转储:
=>0xf7fdd800:mov eax,esp
0xf7fdd802:调用0xf7fe2160
汇编程序转储结束。
(gdb)d 1#删除故障断点
(您需要删除无效断点,然后才能继续或单步执行。)


想法来源于。

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

$ 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
$gdb/bin/true
正在从/bin/true…读取符号(未找到调试符号)…已完成。
(gdb)斯塔蒂
正在启动程序:/bin/true
程序停止。
/lib/ld linux.so.2的_start()中的0xf7fdd800
(gdb)x/5i$pc
=>0xf7fdd800:mov eax,esp
0xf7fdd802:调用0xf7fe2160
0xf7fdd807:mov edi,eax
0xf7fdd809:调用0xf7fdd7f0
0xf7fdd80e:添加ebx,0x1f7e6

奇怪的是,它在头文件中指定的入口点中断,反汇编看起来不错,但直接反汇编可执行文件会显示垃圾。但是你回答了这个问题顺便说一句,很荣幸从Hex Rays的一个家伙那里得到答案
\u init
from
cru/init first.c
似乎在
\u start
或GCC 4.8 glibc 2.19 Ubuntu 14.04中的入口地址之前运行,当我尝试
b\u init;在GDB中运行
。发生了什么事?在问:即使它能工作,它也可能不是动态链接的可执行文件中的第一条用户空间指令。动态链接器首先运行。对于
lldb
,请参阅:related:对于由
fasm/dev/stdin测试生成的简单ELF(如果我理解正确),这实际上不适用于我。根据,对于某些程序,加载地址与虚拟地址不同。在程序运行之前,显示的地址是根据程序的虚拟地址,不一定是加载地址。是的,根据我的经验,在启动
gdb
之后,它显示
0x10e0
。我设置了一个断点,运行,但它无法插入断点。但此时,
i files
显示
0x5550e0
作为入口点。对于一些没有节的精心编制的文件(例如,使用upx生成的文件),它不起作用。一般情况下,您必须手动从
readelf-h$binary
输出复制入口点地址。有趣的是,在解决方案出现之前,我无法在Go应用程序的GDB中使用断点。任何其他方法都不起作用。对我来说也很有效,但是即使是
stepi
也失败了,所以我还必须使用
delete breakpoints
来继续操作。@Ped7g您可以删除设置为失败的确切断点,在上面的示例中,它应该是
d1
。不需要全部删除。这个答案应该以某种方式传播,因为这是GDB8.1版本中最简洁的解决方案。