当程序打开特定文件时gdb中断

背后的故事:在strace下运行程序时,我注意到'/ dev / urandom'正在被open 。 我想知道这个调用来自哪里(这不是程序本身的一部分,它是系统的一部分)。

所以,使用gdb,我打算catch syscall open (使用catch syscall open )程序执行时, open调用发出,所以我可以看到一个回溯。 问题是open被称为很多 ,像几百倍,所以我不能缩小打开/ dev / urandom的具体调用。 我应该如何去缩小具体的电话? 有没有一种方法来过滤参数,如果是的话,我怎么做一个系统调用

任何build议都会有所帮助 – 也许我正在做的这一切都是错误的。

Solutions Collecting From Web of "当程序打开特定文件时gdb中断"

GDB是一个非常强大的工具,但有一点学习曲线。

基本上,你想设置一个条件断点。

首先使用-i标志strace或objdump -d来查找打开函数的地址,或者在实际的链中找到某些东西,比如在plt中。

在这个地址设置一个断点(如果你有调试符号,你可以使用这些符号,省略*,但我假设你不这样做 – 尽管如果没有别的东西,你可能会有它们的库函数。

 break * 0x080482c8 

接下来你需要使它有条件

(理想情况下,您可以将字符串参数与所需的字符串进行比较,在尝试的最初几分钟内,我没有得到这个工作)

让我们希望我们可以假设这个字符串是程序中的某个常量,或者是它加载的一个库。 你可以查看/ proc / pid / maps来得知什么是加载和在哪里,然后使用grep来验证字符串实际上是在一个文件中,objdump -s找到它的地址,gdb来验证你已经实际上通过将地图的高部分与文件的低部分结合在一起,在内存中找到了它。 (编辑:它可能比使用/ proc / pid / maps更容易在可执行文件上使用ldd)

接下来,您需要了解您正在处理的平台的abi,具体说明如何通过参数。 最近我一直在使用arm,这是非常好的,因为前几个参数只是进入寄存器r0,r1,r2 …等等。x86有点不太方便 – 看起来他们在栈上,即* ($ esp + 4),*($ esp + 8),*($ esp + 12)。

因此,我们假设我们在x86上,并且我们想要检查esp + 4中的第一个参数是否等于我们为了捕获它传递的常量而找到的地址。 只有esp + 4是一个指向字符指针的指针。 所以我们需要对它进行解引用来进行比较。

 cond 1 *(char **)($esp+4)==0x8048514 

然后你可以打字跑步,并希望最好的

如果你捕捉到了断点的条件,并用信息寄存器和x命令来检查内存是否正确,那么你可以使用return命令渗透备份调用堆栈,直到找到你认识的东西。

(改编自问题编辑)

克里斯的回答之后 ,这里是最终得到我所寻找的过程:

(我试图找到什么函数调用“/ dev / urandom”上的open系统调用)

  1. 在可执行文件上使用ldd来查找加载的库
  2. grep通过每个lib(shell命令)寻找“urandom”
  3. 在十六进制编辑器中打开库文件并查找字符串的地址
  4. 找出参数是如何通过系统调用(对于打开,文件是第一个参数。在x86_64它是通过rdi传递 – 你的里程可能会有所不同
  5. 现在我们可以设置条件断点: break open if $rdi == _addr_
  6. 运行程序,等待休息
  7. 运行bt来查看回溯

毕竟,我发现glib的g_random_int()和g_rand_new()使用urandom。 Gtk +和ORBit正在调用这些函数 – 如果有人好奇的话。

像Andre Puel一样说:

break open if strcmp($rdi,"/dev/urandom") == 0

可以做这个工作。