Skip to content

GDB 利用 Python 扩展 GEF 插件

前言

例子:在开了 PIE 的程序下,如何根据偏移量可以设置断点。每一次都要先用 vmmap 查找基址,然后加起来,然后开断点。往往要加很多断点,并且要调试很多遍,如果每次都是手动会非常麻烦,因此能否写一个命令,参数是偏移量,自动地寻找 PIE 基地址,然后在偏移位置加断点呢。

步骤

1. 先熟悉GEF,了解是否有别人已经写好可以利用的方法。在这个例子中,我们要找基址,有两点思想。

  • 首先是猜和观察,看看有哪条命令可能会利用到我们想要的功能。我是根据 GEF 可以打印堆的信息来进行查找的,查找 tcache bins,很快就找到了方法,获取地址有现成方法 get_process_map()
  • 要及时输出调试。从一开始就要输出,然后才有底。比如当我找到了 get_process_map(),在该函数末尾把结果 print 一下,然后在 gdb 里面调用 heap bins(查看 heap 的命令),这时就会输出 get_process_map() 的返回内容,因此就知道这个函数会返回哪些东西了。

2. 之后就可以写脚本了,参考 GEF 的官方文档给出的模板,很简单,最终结果在下面。

# 只给出了关键的部分
class Break_in_pie(GenericCommand):
    def do_invoke(self, argv):
        save_map = get_process_maps()

        index = 0
        while True:
            base_addr = save_map[index].page_start
            index += 1
            if base_addr > 0x100000000000 :
                break

        real_addr = int(base_addr)
        # 表示偏移量的参数是十六进制还是十进制
        if argv[0][1] == 'x':
            real_addr = real_addr + int(argv[0], 16)
        else:
            real_addr = real_addr + int(argv[0], 10)
        gdb.execute('break *' + str(real_addr))
        return

register_external_command(Break_in_pie())

细节

  • 利用GEF,要利用写好的命令,里面写好的方法也是可以利用的
  • 参数列表就是 do_invoke(self, argv) 的 argv

参考文档

1. Python 扩展 GDB: https://segmentfault.com/a/1190000005718889
2. GEF 官方文档: https://gef.readthedocs.io/en/master/api/

Comments