在第一次调用函数之前,GDB 中的断点命中了 144 次

逆向工程 二元分析 数据库
2021-07-02 20:41:35

我正在处理逆向工程挑战并有一个二进制文件。我知道如何在执行 strcmp 后通过更改指令流来获取标志,因此我跳转到打印标志的函数。但是,当我在 strcmp 上设置断点时,它在程序中第一次调用 strcmp 之前被命中了 144 次。

例如,程序要求用户输入两次,并且在每次 scanf() 之后调用 strcmp。该程序要您输入两个密码来获取标志。在最初的 strcmp 之前,我必须在 strcmp 处通过 144 个中断,我无法弄清楚为什么 objdump 的结果只调用了我上面提到的两次 strcmp。如有必要,我可以共享 objdump,但有人知道为什么会这样吗?我是否缺少有关在 GDB 中进行调试的内容?有没有办法在我没有看到的二进制文件中隐藏执行此操作的代码?

我知道在“初始调用”之前是 144 次,因为我继续 144 次中断,然后程序最终要求我输入第一个输入(密码)。

1个回答

需要考虑到许多内部函数也使用strcmp例如在这个二进制文件中strcmp我的机器上第一次点击看起来像这样

─────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────
 ► f 0     7ffff7df2990 strcmp
   f 1     7ffff7ddb5a6 dl_main+1670
   f 2     7ffff7df079e _dl_sysdep_start+1006
   f 3     7ffff7ddaae8 _dl_start+648
   f 4     7ffff7ddaae8 _dl_start+648
   f 5     7ffff7dd9c28 _dl_start_user
   f 6                1
   f 7     7fffffffe340
   f 8                0
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Breakpoint strcmp
pwndbg> dumpargs
 rdi = 0x400238 ◂— '/lib64/ld-linux-x86-64.so.2'
 rsi = 0x7ffff7dd9794 ◂— insb   byte ptr [rdi], dx /* 'ld-linux-x86-64.so.2' */
...

通过回溯dl_main调用strcmp来匹配加载器路径来判断类似地,当解析库时,其他调用来自加载程序。

─────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────
 ► f 0     7ffff7df2990 strcmp
   f 1     7ffff7de9845 _dl_name_match_p+21
   f 2     7ffff7de15c9 _dl_map_object+137
   f 3     7ffff7de5fc0 openaux+48
   f 4     7ffff7de8644 _dl_catch_error+116
   f 5     7ffff7de622f _dl_map_object_deps+607
   f 6     7ffff7ddc6c2 dl_main+6050
   f 7     7ffff7df079e _dl_sysdep_start+1006
   f 8     7ffff7ddaae8 _dl_start+648
   f 9     7ffff7ddaae8 _dl_start+648
   f 10     7ffff7dd9c28 _dl_start_user
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Breakpoint strcmp
pwndbg> dumpargs
 rdi = 0x4003d9 ◂— insb   byte ptr [rdi], dx /* 'libc.so.6' */
 rsi = 0x7ffff7ffe700 ◂— 0x0

根据您系统上的配置(例如加载程序和库),此调用次数可能是可变的。

另一件要注意的事情是,在我的情况下,二进制文件的 GOT 解析为

[0x601038] strcmp@GLIBC_2.2.5 -> 0x7ffff7ac9520 (__strcmp_sse2_unaligned) ◂— mov    eax, edi

这与我们在上面的断点中遇到的函数不同。

如果您只想停止从二进制文件调用的那些,请在调用站点上设置断点。

0x40090d    call   strcmp@plt <0x400630>
0x400961    call   strcmp@plt <0x400630>