扩展 GDB - 高亮显示反汇编中的 call 语句

本文介绍了如何使用GDB的Python扩展编写filter-calls命令,该命令简化了在大型反汇编代码中查找函数调用的过程,包括高亮显示call语句和可选地显示所有代码行。
摘要由CSDN通过智能技术生成

在用 GDB 调试 CSAPP bomblab 时,当反汇编代码稍微具备点规模,例如超过10行,直接翻译为C语言的难度就增加了,此时考虑先找到调用的函数,然后再梳理 if/else/for循环 的执行流。函数体内调用了其他函数,也就是找到带有 call 的汇编指令,人工找还是有点繁琐了。

GDB 支持 Python 扩展, 通过和 ChatGPT 的结对编程, 可以写出函数来实现这一功能:默认仅列出 call 语句,bing保持高亮; 如果带有第二个参数 True, 则显示全部的反汇编代码,并且 call 之外的汇编不要有高亮。效果如下:
在这里插入图片描述
~/.gdbinit 中对应的配置:

python
import gdb
import subprocess
import os
import re

# 定义 ANSI 颜色代码
ANSI_COLOR_BLUE = "\033[34m"
ANSI_COLOR_GREEN = "\033[32m"
ANSI_COLOR_RED = "\033[31m"
ANSI_COLOR_RESET = "\033[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'(\bcall\b)', 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

为了说明效果,再看一个:
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gdb反汇编函数或程序时,每一条汇编指令都会显示对应的地址。可以通过以下步骤查看语句对应的地址: 1. 在gdb加载需要反汇编的程序或函数。 2. 使用命令“disassemble”或“disas”反汇编程序或函数。 3. 查找需要的语句,对应的地址通常在语句前面。 4. 如果需要查看特定地址的语句,可以使用命令“x/i <address>”查看该地址上的指令。 例如,假设我们要查看函数“test”的反汇编结果,并找到其一条语句的地址。在gdb,我们可以执行以下命令: ``` (gdb) disassemble test Dump of assembler code for function test: 0x00000000004004c0 <+0>: push %rbp 0x00000000004004c1 <+1>: mov %rsp,%rbp 0x00000000004004c4 <+4>: movl $0x0,-0x4(%rbp) 0x00000000004004cb <+11>: movl $0x1,-0x8(%rbp) 0x00000000004004d2 <+18>: movl $0x2,-0xc(%rbp) 0x00000000004004d9 <+25>: mov -0x8(%rbp),%eax 0x00000000004004dc <+28>: mov -0xc(%rbp),%edx 0x00000000004004df <+31>: add %edx,%eax 0x00000000004004e1 <+33>: mov %eax,-0x10(%rbp) 0x00000000004004e4 <+36>: nop 0x00000000004004e5 <+37>: pop %rbp 0x00000000004004e6 <+38>: retq End of assembler dump. ``` 在反汇编结果,每一条指令前面都有一个地址,例如第一条指令的地址是“0x00000000004004c0”。如果我们想要查看地址为“0x00000000004004df”处的指令,可以使用命令“x/i 0x00000000004004df”,结果应该是: ``` (gdb) x/i 0x00000000004004df 0x4004df: 01 d0 add %edx,%eax ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值