背景故事:在strace
下运行程序时,我注意到'/ dev / urandom'正在open
编辑。我想知道这个电话来自哪里(它不是程序本身的一部分,它是系统的一部分)。
所以,使用gdb,我试图在发出catch syscall open
调用时断开(使用open
)程序执行,所以我可以看到一个回溯。问题是open
被称为 alot ,就像几百次一样,所以我无法缩小打开/ dev / urandom的特定调用。我该如何缩小特定电话的范围?有没有办法按参数过滤,如果有,我该如何为系统调用做?
任何建议都会有所帮助 - 也许我说这一切都错了。
答案 0 :(得分:14)
GDB是一个非常强大的工具,但有一点学习曲线。
基本上,您需要设置条件断点。
首先使用-i标志来strace或objdump -d来查找open函数的地址,或更实际地找到那里的东西,例如在plt中。
在该地址设置一个断点(如果你有调试符号,你可以使用它们,省略*,但我假设你没有 - 尽管如果没别的话,你可能会将它们用于库函数。< / p>
break * 0x080482c8
接下来你需要让它成为条件
(理想情况下,您可以将字符串参数与所需的字符串进行比较。我在尝试的前几分钟内没有让它工作)
我们希望我们可以假设字符串是程序中的某个常量或它加载的库之一。您可以查看/ proc / pid / maps以了解加载的内容和位置,然后使用grep验证字符串实际上是在文件中,objdump -s查找它的地址,gdb验证你是否已经实际上通过将地图的高位部分与文件的低部分组合在内存中找到它。 (编辑:在可执行文件上使用ldd可能比在/ proc / pid / maps中查找更容易)
接下来,您将需要了解您正在处理的平台的abi,特别是如何传递参数。我最近一直在研究arm,这非常好,因为前几个参数只是进入寄存器r0,r1,r2 ......等等.x86不太方便 - 看起来它们会进入堆栈,即* ($ esp + 4),*($ esp + 8),*($ esp + 12)。
所以让我们假设我们在x86上,我们想要检查esp + 4中的第一个参数是否等于我们试图捕获它的常量所找到的地址。只有,esp + 4是指向一个char指针的指针。所以我们需要取消引用它进行比较。
cond 1 *(char **)($esp+4)==0x8048514
然后您可以输入运行并希望获得最佳
如果你发现你的断点条件,并查看信息寄存器和x命令检查内存似乎是正确的,那么你可以使用return命令渗透备份调用堆栈,直到找到你认识的东西。
答案 1 :(得分:3)
(改编自问题编辑)
关注Chris's answer,这个过程最终让我得到了我想要的东西:
(我试图找到哪些函数在“/ dev / urandom”上调用open
系统调用)
grep
通过每个lib(shell命令)寻找'urandom'rdi
- 您的里程可能会有所不同break open if $rdi == _addr_
bt
以查看回溯毕竟,我发现glib的g_random_int()和g_rand_new()使用urandom。 Gtk +和ORBit正在调用这些函数 - 如果有人好奇的话。