在用 GDB 调试 CSAPP bomblab 时,当反汇编代码稍微具备点规模,例如超过10行,直接翻译为C语言的难度就增加了,此时考虑先找到调用的函数,然后再梳理 if/else/for循环 的执行流。函数体内调用了其他函数,也就是找到带有
GDB 支持 Python 扩展, 通过和 ChatGPT 的结对编程, 可以写出函数来实现这一功能:默认仅列出 call 语句,bing保持高亮; 如果带有第二个参数
python import gdb import subprocess import os import re # 定义 ANSI 颜色代码 ANSI_COLOR_BLUE = " 33[34m" ANSI_COLOR_GREEN = " 33[32m" ANSI_COLOR_RED = " 33[31m" ANSI_COLOR_RESET = " 33[0m" # 定义一个新的GDB命令 filter-calls class FilterCalls(gdb.Command): def __init__(self): super(FilterCalls, self).__init__("filter-calls", gdb.COMMAND_USER) def invoke(self, arg, from_tty): # 解析参数 args = gdb.string_to_argv(arg) if len(args) not in [1, 2]: raise gdb.GdbError('Usage: filter-calls <function> [True/False]') # 设置参数 function_name = args[0] show_all_lines = False if len(args) == 2: show_all_lines = args[1].lower() == 'true' # 创建一个临时文件 tmp_file = subprocess.check_output(["mktemp", "/tmp/gdb-XXXXXX.txt"]).decode('utf-8').strip() # 重定向GDB的输出到临时文件 gdb.execute("set logging overwrite on") gdb.execute("set logging file " + tmp_file) gdb.execute("set logging redirect on") gdb.execute("set logging on") gdb.execute("disassemble " + function_name) gdb.execute("set logging off") # 读取临时文件并过滤出包含 'call' 的行 with open(tmp_file, 'r') as f: for line in f: if 'call' in line: # 为地址、'call'关键字和函数名添加颜色 colored_line = re.sub(r'(0x[0-9a-f]+)', ANSI_COLOR_BLUE + r'1' + ANSI_COLOR_RESET, line) colored_line = re.sub(r'(call)', ANSI_COLOR_GREEN + r'1' + ANSI_COLOR_RESET, colored_line) colored_line = re.sub(r'(<.*?>)', ANSI_COLOR_RED + r'1' + ANSI_COLOR_RESET, colored_line) print(colored_line.strip()) elif show_all_lines: print(line.strip()) # 删除临时文件 os.remove(tmp_file) # 注册这个新命令 FilterCalls() end
为了说明效果,再看一个: