在尝试回答另一个问题时,我尝试设置一个Python脚本来自动提取程序集执行跟踪。但是,我真的对此脚本不满意,我想知道如何对其进行改进。

首先,这里是脚本:



import gdb

gdb.execute('break main')
gdb.execute('run')

while (True):
    gdb.write (gdb.execute('x /i $pc', to_string=True).rstrip('\n'), gdb.STDOUT)
    gdb.execute('stepi', to_string=False)
    gdb.flush ()


然后执行:

$> gdb -x ./script.py ./main 1> log.txt


我要解决的问题如下:


首先,while(True)绝对不能令人满意。我想在达到断点或退出时停止或暂停循环。将其保存到文件比将gdb重定向到文件要好得多。
最后,能够与该软件进行交互,并通过stdout馈送它也是我们想要的。 >因此,如果您知道如何以任何方式改进此脚本,我将很感兴趣。

评论

为什么不使用PIN,Valgrind或DynamoRio?

如果足够,为什么不使用gdb呢?此外,PIN仅适用于Intel体系结构,DynamoRio未包装用于Debian,并且Valgrind的执行是仿真的,可能会有所偏差。
您是否看到一种简单的方法,您的脚本不仅可以记录指令,而且还可以访问存储器(读取和写入),包括访问值?
stackoverflow.com/questions/8841373/…

#1 楼

您的问题确实似乎是“如何使用GDB获取指令跟踪”。除了在GDB内使用Python外,使用Python似乎是偶然的。

GDB通过record命令对指令跟踪具有本机支持。使用命令record full将记录对进程状态的所有更改,甚至允许进行反向调试(即,后退和回放)。

您可以在此处找到更多信息:
https:// sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html

另外,如果您希望使用Python-inside-GDB执行单步执行和指令跟踪,则最好最好使用Breakpoint类并使用不会停止UI的internal断点。在具有可变宽度指令(i386,amd64)的体系结构上,您将需要计算当前指令的大小。您还需要解决所有的跳转和调用目标。

如果您查看GDB源代码,您将看到它们在事件循环中的工作方式,并且未在Python API中公开。搜索用于STEP_OVER_NONE指令的stepi(仅执行一条机器指令)。

如果您愿意,可以在GDB中使用gdb.Breakpointgdb.FinishBreakpoint类型进行此操作。但是,最终您需要解析指令宽度(在x86等可变宽度指令ISA上),并提取跳转和调用目标。 GDB的Python API不支持单步断点,也不解析下一条指令地址。您可以使用Capstone和Unicorn轻松地完成这两项工作。

评论


但是请注意,gdb记录当前有一些主要限制,例如没有AVX:stackoverflow.com/questions/43750603/gdb-reverse-debugging-avx2

– Ciro Santilli郝海东冠状病六四事件法轮功
17-10-10在7:26