需要考虑到许多内部函数也使用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>