-
-
Save SeeFlowerX/de28ab532c86c447de687441ea22ba87 to your computer and use it in GitHub Desktop.
gdb 下断点脚本,就是调用一下 gdb.execute,仅供参考
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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