编写gdb插件快速计算地址信息

· 2025-09-05 12:00 · 6 阅读

原创 c0ny1 2025-09-05 12:00 中国香港

debug过程中一键获取地址信息

 

0x00 背景

 

作为一张二进制白纸,有时候不得不查看一些地址的各类信息。比如:

  1. 该地址在哪一个段呢? .bss还是.data

  2. 某个值是在堆还是栈?

  3. 这个地址对应IDA/ghidra的地址是多少?

  4. 该地址所属的映射文件是哪一个?

  5. ......

 

每次都要不断的执行命令,然后盯着屏幕的一长串地址列表看目标在那个范围。

网上找了一圈也没找到合适插件,还是自己浅浅搓一个吧。

0x01 梳理

要回答上面的问题,我们其实只需要获取到如下3类信息。

  1. 1. 基地 + 偏移

  2. 2. 段名

  3. 3. 所属映射文件

翻了一下文档Python API (Debugging with GDB)[1]发现除了没有合适的api直接获取,看样子只能通过内置的命令获取(有点不优雅)。

info filesinfo proc mappings

0x02 实现

获取info proc mappings命令结果后,遍历出目标地址所在地址范围。objfile列就是目标地址所属映射文件,而基地址+偏移可以按照如下公式计算。

基址 = Start Addr偏移 = 目标地址 - 基址

段的信息,可以从info files信息进行提取。根据地址所在的范围,提取对应的段名。

完整代码如下

import reimport gdbclassAddrInfo(gdb.Command):    PLUGIN_NAME = "AddrInfo"    VERSION = "1.0"    def__init__(self):        super(AddrInfo, self).__init__("addrinfo", gdb.COMMAND_USER)    definvoke(self, arg, from_tty):        arg = arg.strip()        ifnot arg:            print("Usage: addrinfo <address>")            print("Example: addrinfo 0x7ffff7dd18c0")            return        try:            address = int(gdb.parse_and_eval(arg))        except Exception:            print(f"Error: Invalid address format: '{arg}'")            print("Usage: addrinfo <address>")            print("Make sure the address is valid in the current debug context.")            return        try:            base_addr, start, end, offset, perms, objfile = self.find_mapping(address)            seg_name, seg_start, seg_end = self.find_section(address)            if base_addr isnotNone:                print(f'''{self.PLUGIN_NAME} {self.VERSION}Address:  {hex(address)} [{hex(start)} - {hex(end)}Base:     {hex(base_addr)}Offset:   {hex(offset)}Section:  {seg_name} [{hex(seg_start)} - {hex(seg_end)}]Perms:    {perms}ObjFile:  {objfile}''')            else:                print(f"Address {hex(address)} does not belong to any known mapped region.")        except Exception as e:            print(f"Error during processing: {e}")        # 遍历段名    deffind_section(self, addr):        output = gdb.execute("info files", to_string=True)        pattern = re.compile(r"0x([0-9a-f]+)\s*-\s*0x([0-9a-f]+)\s+is\s+(\S+)")        matches = pattern.findall(output)        # 正则匹配,第3列是段名        for start, end, name in matches:            start = int(start, 16)            end = int(end, 16)            if start <= addr < end:                return name, start, end        returnNoneNoneNone    deffind_mapping(self, addr):        mappings = gdb.execute("info proc mappings", to_string=True).splitlines()        for line in mappings:            parts = line.strip().split()            iflen(parts) < 2:                continue            try:                start = int(parts[0], 16)                end = int(parts[1], 16)            except ValueError:                continue            if start <= addr < end:                base_addr = start                offset = addr - start                perms = parts[4iflen(parts) > 4else"?"                objfile = parts[5iflen(parts) > 5else"?"                return base_addr, start, end, offset, perms, objfile        returnNoneNoneNoneNoneNoneNoneAddrInfo()

 

若后续有新的功能或者为了适配更多的gdb版本,会在下面地址更新。主要还是看有没有实用价值吧,毕竟目前只是用来玩玩具。

https://github.com/c0ny1/gdb-addrinfo

 

0x03 使用

临时安装

(gdb) source AddrInfo.py

永久安装,在文件~/.gdbinit的末尾添加如下命令。

source /yourpath/AddrInfo.py

然后就可以愉快玩耍了

引用链接

[1] Python API (Debugging with GDB): https://sourceware.org/gdb/current/onlinedocs/gdb.html/Python-API.html

 

阅读原文

跳转微信打开