一尘不染

当在管道中放置特定的字符串时,如何监视放入标准输出缓冲区的内容并中断?

linux

在Linux中,使用gdb的C / C ++代码,如何添加gdb断点来扫描传入的字符串以中断特定的字符串?

我无权访问特定库的代码,但是我想在该库将特定字符串发送到标准输出后立即中断,以便我可以返回堆栈并研究调用该库的代码部分。当然,我不想等到缓冲区刷新发生。能做到吗?也许是例行公事libstdc++


阅读 192

收藏
2020-06-07

共1个答案

一尘不染

这个问题可能是一个很好的起点:如何在gdb中的“将某些内容打印到终端”上设置断点?

因此,无论何时将任何内容写入标准输出,您都至少可以中断。该方法主要涉及write在第一个参数为1(即STDOUT)的条件下在syscall上设置断点。在注释中,还提示您如何检查write调用的字符串参数。

x86 32位模式

我提出了以下内容,并使用gdb 7.0.1-debian对其进行了测试。看来效果很好。$esp + 8包含指向传递给字符串的内存位置的指针write,因此首先将其转换为整数,然后转换为的指针char$esp + 4包含要写入的文件描述符(对于STDOUT为1)。

$ gdb break write if 1 == *(int*)($esp + 4) && strcmp((char*)*(int*)($esp + 8), "your string") == 0

x86 64位模式

如果您的进程以x86-64模式运行,则参数将通过暂存器传递,%rdi并且%rsi

$ gdb break write if 1 == $rdi && strcmp((char*)($rsi), "your string") == 0

请注意,由于我们使用暂存器而不是堆栈中的变量,因此删除了一层间接。

变体

strcmp以上代码段中可以使用的功能除外:

  • strncmp如果您想匹配n所写字符串的第一个字符数,则很有用
  • strstr 可用于查找字符串中的匹配项,因为您始终不能确定要查找的字符串位于通过函数写入的字符串的 开头write

编辑: 我喜欢这个问题,并找到它的后续答案。我决定写一篇关于它的博客文章

2020-06-07