能否在GDB内部向C程序发送二进制数据?
在GDB内部直接输入原始二进制字节的方法
针对你需要在GDB调试时向程序发送原始字节(而非被解析为ASCII的转义序列)的需求,以下是几个实用方案:
方案一:利用GDB内置Python API直接写入进程输入
当程序停在read调用的断点处时,执行以下GDB命令:
python import gdb; gdb.inferiors()[0].write(b"\x41\x42\x43\x44\x00\xFF")
- 原理:GDB的Python API允许直接与被调试进程(inferior)交互,
write方法接收原生bytes对象,可发送任意二进制数据,包括空字节\x00、高字节\xFF等终端无法直接输入的内容。 - 注意:如果程序在执行
read前未暂停,可先添加断点b read,再执行上述命令(命令中已包含continue来恢复程序运行)。
方案二:启动程序时通过进程替换注入输入
在GDB中直接执行run命令,结合Shell进程替换生成原始输入:
run < <(python3 -c 'print(b"\x41\x42\x43\x44\xAB".decode("latin-1"), end="")')
- 原理:借助bash的进程替换特性,让程序的标准输入直接来自Python脚本的输出。用
latin-1编码解码bytes可以保留所有字节的原始值,避免字符编码转换导致的数据失真。
方案三:直接修改栈缓冲区内存(绕过read调用)
如果测试场景不强制要求通过read函数接收输入,可直接修改栈上的user_buffer:
- 先获取缓冲区地址:
p &user_buffer - 用
memcpy填充数据:
call memcpy(&user_buffer, "\x41\x42\x43\x44", 4)
或者直接通过内存赋值:
set {unsigned char[24]} 0x7fffffffeabc = {0x41, 0x42, 0x43, 0x44, 0xFF, 0x00}
- 替换命令中的
0x7fffffffeabc为实际的user_buffer地址即可。
为什么直接输入\x41无效?
GDB的交互式输入会经过终端的字符解析,输入的\x41会被当作四个独立的ASCII字符(反斜杠、x、4、1)处理,而非单个十六进制字节0x41,因此必须通过上述方法绕开终端的字符转义逻辑。
内容的提问来源于stack exchange,提问作者the_endian
相关产品推荐
相关产品推荐

