如何监视放入标准输出缓冲区的内容,并在特定字符串存储在管道中时中断? [英] How can I monitor what's being put into the standard out buffer and break when a specific string is deposited in the pipe?
问题描述
在Linux中,使用C / C ++代码,使用gdb,如何添加一个gdb断点来扫描传入的字符串,以打破特定的字符串?
我没有访问特定库的代码,但是我想要在该库发送特定字符串到标准输出时立即断开,以便我可以返回堆栈和调查我的代码调用库的一部分。当然,我不想等到发生缓冲区冲洗。这可以做吗?也许在 libstdc ++
?
所以你可以在任何东西写到stdout时断开。该方法基本上涉及在 write
syscall上设置断点,条件是第一个参数为 1
(即STDOUT) 。在注释中,还有一个提示,您可以如何检查 write
调用的字符串参数。
x86 32位模式
我想出了以下内容,并使用gdb 7.0.1-debian测试过它。它似乎工作得很好。 $ esp + 8
包含指向传递给写入
的字符串的内存位置的指针,因此首先将它强制转换为一个整数,然后到 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
以外的函数可用于上述片段:
编辑:我喜欢这个问题,并找到了后续的答案。我决定对其进行博文。
In Linux, with C/C++ code, using gdb, how can you add a gdb breakpoint to scan the incoming strings in order to break on a particular string?
I don't have access to a specific library's code, but I want to break as soon as that library sends a specific string to standard out so I can go back up the stack and investigate the part of my code that is calling the library. Of course I don't want to wait until a buffer flush occurs. Can this be done? Perhaps a routine in libstdc++
?
This question might be a good starting point: how can I put a breakpoint on "something is printed to the terminal" in gdb?
So you could at least break whenever something is written to stdout. The method basically involves setting a breakpoint on the write
syscall with a condition that the first argument is 1
(i.e. STDOUT). In the comments, there is also a hint as to how you could inspect the string parameter of the write
call as well.
x86 32-bit mode
I came up with the following and tested it with gdb 7.0.1-debian. It seems to work quite well. $esp + 8
contains a pointer to the memory location of the string passed to write
, so first you cast it to an integral, then to a pointer to char
. $esp + 4
contains the file descriptor to write to (1 for STDOUT).
$ gdb break write if 1 == *(int*)($esp + 4) && strcmp((char*)*(int*)($esp + 8), "your string") == 0
x86 64-bit mode
If your process is running in x86-64 mode, then the parameters are passed through scratch registers %rdi
and %rsi
$ gdb break write if 1 == $rdi && strcmp((char*)($rsi), "your string") == 0
Note that one level of indirection is removed since we're using scratch registers rather than variables on the stack.
Variants
Functions other than strcmp
can be used in the above snippets:
strncmp
is useful if you want match the firstn
number of characters of the string being writtenstrstr
can be used to find matches within a string, since you can't always be certain that the string you're looking for is at the beginning of string being written through thewrite
function.
Edit: I enjoyed this question and finding it's subsequent answer. I decided to do a blog post about it.
这篇关于如何监视放入标准输出缓冲区的内容,并在特定字符串存储在管道中时中断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!