Skip to content

Instantly share code, notes, and snippets.

@SeeFlowerX
Last active March 8, 2023 13:46
Show Gist options
  • Save SeeFlowerX/de28ab532c86c447de687441ea22ba87 to your computer and use it in GitHub Desktop.
Save SeeFlowerX/de28ab532c86c447de687441ea22ba87 to your computer and use it in GitHub Desktop.
gdb 下断点脚本,就是调用一下 gdb.execute,仅供参考
import re
# GDB Python SDK
import gdb
# -------- for type hint --------
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from gef import *
# -------- for type hint --------
class LibModule:
def __init__(self, name: str, path: str, base: int, end: int) -> None:
self.name = name
self.path = path
self.base = base
self.end = end
def add(self, offset: int):
return self.base + offset
def find_module(module_name: str):
'''
这里没有做缓存
每次都从 gef.memory.maps 查找以确保地址是最新的
'''
modules = {} # type: Dict[str, LibModule]
for section in gef.memory.maps:
if isinstance(section.path, str) is False:
continue
if section.path == '':
continue
if module_name == section.path.split('/')[-1]:
if module_name in modules:
if section.page_start < modules[module_name].base:
modules[module_name].base = section.page_start
else:
# 每个分段不会重叠为前提
modules[module_name].end = section.page_start
else:
modules[module_name] = LibModule(
module_name,
section.path,
section.page_start,
section.page_end,
)
if module_name in modules:
return modules[module_name]
else:
assert False, f'can not find {module_name}'
def main():
# 先忽略相关信号
gdb.execute("handle SIGSEGV nostop pass")
gdb.execute("handle SIGQUIT nostop nopass")
gdb.execute("handle SIG35 nostop nopass")
print('handle signal end')
# 先获取模块信息 计算偏移对应的实际地址
libxxx = find_module('libxxx.so')
dump_breakpoint = libxxx.add(0x7F36C)
canary_breakpoint = libxxx.add(0x7F380)
# 设置某个断点执行到一定次数的时候 才真正断下来
# https://stackoverflow.com/questions/2956889/how-to-make-a-gdb-breakpoint-only-break-after-the-point-is-reached-a-given-numbe
# 首先下断点
breakpoint_info = gdb.execute(f'b *0x{dump_breakpoint:x}', to_string=True).strip()
# Breakpoint 1 at 0x76f398836c
breakpoint_id = re.match('Breakpoint (\d+) at .+', breakpoint_info)
if breakpoint_id is None:
print(f'get breakpoint_id failed ===>{breakpoint_info}<===')
return
print(breakpoint_info)
# 下面命令的意思是 dump_breakpoint 这个断点经过 50 次之后才会真正断下
gdb.execute(f'ignore {breakpoint_id.group(1)} 50')
print(f'canary breakpoint here, copy it => b *0x{canary_breakpoint:x}')
# - 先复制上面的 canary断点命令
# - 本脚本执行完成后 手动输入 r 继续执行
# - 等待断下 然后执行前面复制的 canary断点命令
# <---------------- 使用说明 ---------------->
#
# 通过脚本设置断点 需要搭配最新版 gef.py 使用 供参考
#
# 本脚本是在 attach 成功之后执行 请视情况修改编写脚本
#
# source breakpoint_helper.py
#
# <---------------- 使用说明 ---------------->
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment