一个GDB调试技巧:修改程序的标准输入

想有没有一种方式能一边使用GDB调试程序,一边在需要的时候通过标准输入传递构造好的恶意数据(通常含有各种特殊字符,如\x01\x02\x03等),这样可以实时知道恶意数据输入后,程序的状态、执行过程。而不是执行exp,把程序弄崩溃,利用core file还原崩溃现场。

想了好几种方式,最后是利用GDB的call命令来调用函数修改被调试程序的标准输入,这样程序可以从我们指定的文件里读取特殊字符。

写了个GDB Python插件,代码在:https://github.com/Ovi3/pstdio

使用例子

编译测试用的程序。read.c

#include "stdio.h"

int main(void){
        char buf[32];
        char buf1[32];
        int len;
        len = read(0, buf, 32);
        buf[len] = 0;
        write(1, buf, len);

        len = read(0, buf1, 32);
        buf1[len] = 0;
        write(1, buf1, len);

        return 0;
}

编译:gcc -o read read.c
安装pstdio:

git clone https://github.com/Ovi3/pstdio.git ~/pstdio
echo "source ~/pstdio/pstdio.py" >> ~/.gdbinit

开始调试gdb -q read

先看下帮助文档:pstdio help

snipaste20170614_011330.png

调试执行到call <read@plt>之前,执行(有两个反斜杆)

pstdio data /x \\x41\\x42\\x43\\x44\\x01\\x02\\x03\\x04

接着执行ni单步执行call <read@plt>后,数据就会被写入。

snipaste20170614_012101.png
snipaste20170614_012143.png

或者在/path/to/data文件里存数据,接着执行pstdio file /path/to/data,再单步到call <read@plt>,文件里的数据就会被写入。

snipaste20170614_012344.png

程序在重新运行后,或者在执行pstdio reset后,程序的标准输入就会恢复,也就是数据从屏幕上输入。

snipaste20170614_012454.png

参考资料

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 79,666评论 12 120
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 131,934评论 20 560
  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 9,329评论 0 20
  • 昨夜无眠。 在现在这个互联网世界,我经常会遇到各种各样的大牛,看他们过那种自由自在,令我神往的生活,然后看看现在的...
    水浅_bling阅读 265评论 1 4
  • 2015年《琅琊榜》热播之时,我就被宗主梅长苏迷倒。过年时陪着老妈又看了几集《琅琊榜》,又一次看到了高颜值的梅宗主...
    Amy的随笔阅读 168评论 0 0