GEF 扩展开发指南:用 Python API 快速打造自定义 GDB 命令、上下文面板与架构支持
网络安全开发工具【免费下载链接】gefGEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs reverse engineers on Linux项目地址https://gitcode.com/gh_mirrors/gef/gef点击查看免费下载本文基于 GEF 官方文档 docs/api.md 与核心实现 gef.py系统讲解如何把 GEF 当作库来使用在几分钟内编写并加载自定义 GDB 命令、注册随断点事件刷新的上下文面板Context Pane、用parse_arguments装饰器规范地解析命令行参数以及通过继承Architecture类为新目标架构添加支持。读完本文你可以脱离 GEF 内置命令集独立扩展出贴合自身逆向工作流的调试工具。GEF 的扩展定位一个电池齐备的调试环境 命令开发框架GEFGDB Enhanced Features的定位是构建在 GDB 之上的现代化调试环境面向 Linux 平台的漏洞利用开发者与逆向工程师。但正如 docs/api.md 开篇所述它最重要的价值之一是提供了一整套原语primitives让开发者能够快速创建自己的 GDB 命令——This page intends to summarize how to create advanced GDB commands in moments usingGEFas a library.从源码结构看这一设计体现在 gef.py 的全局命令注册表__registered_commands__gef.py#L163以及Gef.load()的加载逻辑中每次加载时GEF 会将注册表中的类实例化并挂载到 GDB同时自动为其创建别名gef.py#L11443-L11478。此外社区还有一个官方托管外部脚本的仓库gef-extras用于存放可贡献的扩展脚本与自定义架构实现本文不展开但其目录结构scripts/、archs/与本文各节的扩展方式一一对应。快速开始最小可用的自定义命令骨架docs/api.md 给出了创建名为newcmd的 GEF 命令的最基本骨架register class NewCommand(GenericCommand): Dummy new command. _cmdline_ newcmd _syntax_ f{_cmdline_} # optionally # _examples_ [f{_cmdline_} arg1 ..., ] # _aliases_ [alias_to_cmdline, ] only_if_gdb_running # not required, ensures that the debug session is started def do_invoke(self, argv): # lets say we want to print some info about the architecture of the current binary print(fgef.arch{gef.arch}) # or showing the current $pc print(fgef.arch.pc{gef.arch.pc:#x})加载与调用同样简单gef➤ source /path/to/newcmd.py [] Loading NewCommand gef➤ newcmd gef.arch__main__.X86_64 object at 0x7fd5583571c0 gef.arch.pc0x55555555a7d0源码级解析register与GenericCommand到底做了什么骨架中每个部分都能在 gef.py 中找到对应实现理解它们能帮助你写出更健壮的命令register装饰器gef.py#L5294-L5314对GenericCommand子类执行三项检查——必须具有_cmdline_属性、必须实现do_invoke方法、且_cmdline_不能与已注册命令重名重名会抛出AlreadyRegisteredException通过检查后加入全局注册表。因此文档中命令名冲突这类问题在注册阶段就会被拦截。GenericCommand基类gef.py#L5317-L5383它继承自gdb.Command并在__init_subclass__中强制要求子类定义_cmdline_与_syntax_缺失时直接抛NotImplementedError。_syntax_不只是文档构造器会将其拼进命令的__doc__供 GDB 的 help 菜单自动展示。调用链与异常兜底invoke()方法负责把原始参数字符串经gdb.string_to_argv()拆分后交给你的do_invoke(argv)它还会用bufferize包装输出并统一捕获异常——非 debug 模式下输出Command name failed to execute properly的警告debug 模式下则通过show_last_exception()展示完整堆栈甚至可通过gef.propagate_debug_exception设置让异常向上抛出gef.py#L5360-L5376。注释中特别建议自定义命令捕获具体异常而非泛型Exception以便 GEF 的异常处理机制正常工作。命令级配置项GenericCommand还提供settings机制——通过self[setting_name]读取以{cmdline}.为前缀的配置键gef.py#L5391-L5411这意味着你的自定义命令也可以拥有自己的gef配置项与内置命令享受同一套配置体系。让新命令常驻CLI 加载与~/.gdbinit自定义命令文件既可以在 GDB 提示符下临时加载gef➤ source /path/to/newcmd.py也可以写入~/.gdbinit使其随 GDB 启动自动加载echo source /path/to/newcmd.py ~/.gdbinit一个值得注意的细节旧版文档推荐的register_external_command()在源码中已被标记为deprecated并明确提示 Useregister(), and inherit fromGenericCommandinsteadgef.py#L5271-L5274。新写的扩展请一律使用register。自定义上下文面板Context Pane当你希望某段逻辑像命令一样执行但在每次断点、单步等 break 类事件后自动刷新并显示为 GEF context 输出的一部分时官方提供了register_external_context_pane()函数。docs/api.md 中的示例是一个调试计时器面板__start_time__ int(time.time()) def wasted_time_debugging(): gef_print(You have wasted {} seconds!.format(int(time.time()) - __start_time__)) def wasted_time_debugging_title(): return wasted:time:debugging:{}.format(int(time.time()) - __start_time__) register_external_context_pane(wasted_time_debugging, wasted_time_debugging, wasted_time_debugging_title)加载方式与命令相同gef➤ source /path/to/custom_context_pane.py。之后每次停下时你会在 context 输出的底部附近看到新面板面板之间的顺序可以通过 GEF 的 context 配置调整。同一个文件中也可以同时注册 Command 和 Context Pane。Context Pane API 参数说明该 API 对参数类型要求严格docs/api.md 给出的签名为def register_external_context_pane( name: str, context_callback: Callable[None,[]], context_callback_title: Callable[str, []], condition_callback: Optional[Callable[bool, []]] None ) - None各参数含义参数说明name作为面板设置名settings name使用的字符串context_callback使用gef_print()输出面板内容的函数context_callback_title返回标题字符串的函数返回None则不显示标题condition_callback可选返回布尔值决定本次是否显示该面板对照源码gef.py#L5227-L5253其实际形参名为pane_name/display_pane_function/pane_title_function/condition文档 docstring 还给出了一个更贴近实战的用法示例仅在当前指令是系统调用时显示一个面板——def only_syscall(): return gef_current_instruction(gef.arch.pc).is_syscall() def display_pane(): gef_print(Wow, I am a context pane!) def pane_title(): return example:pane register_external_context_pane(example_pane, display_pane, pane_title, only_syscall)从源码结构看注册过程比注册一个回调要多做一件事register_external_context_pane会委托给gef.gdb.add_context_pane()gef.py#L11419-L11441后者会自动把面板名空格替换为下划线追加到context.layout配置项的末尾——这正是文档所说面板顺序可在 GEF context 配置中修改的机制context.layout是一个空格分隔的面板名序列调整它的顺序与取舍即可控制面板布局。若面板名已存在注册会被跳过并给出重复告警。Context Layout Mapping API另一个更底层的 API 是为已存在的面板注册新的布局映射用于接管现有面板的显示逻辑def register_external_context_layout_mapping( current_pane_name: str, display_pane_function: Callable[[], None], pane_title_function: Callable[[], Optional[str]], condition: Optional[Callable[[], bool]] None ) - Nonecurrent_pane_name必须是布局配置中已注册的面板名display_pane_function使用gef_print()输出面板内容pane_title_function返回标题字符串返回None则不显示标题condition可选谓词函数返回True时才显示面板内容与标题返回False时整个面板被跳过。从源码看register_external_context_layout_mappinggef.py#L5256-L5265是add_context_pane内部调用的底层入口后者先改写context.layout再转入该函数完成映射注册因此它不会像register_external_context_pane那样自动追加新的 layout 项——它只负责已有面板名的显示逻辑替换。GEF API 核心原语比 GDB 原生接口更 Pythonic 的写法GEF API 的设计目标是提供比原生 GDB Python API 更简洁的接口。查看任意函数的完整帮助可以直接在 GDB/GEF 中用嵌入式 Python 解释器的helpgef➤ pi help(Architecture)甚至在 GDB 外部gdb -q -ex pi help(hexdump) -ex quitdocs/api.md 给出两个基本示例读取内存并十六进制转储对应源码hexdump位于 gef.py#L2213Memory.read位于 gef.py#L12209parse_address位于 gef.py#L4516后者支持$pc、*0x4000、符号名等多种 GDB 地址表达式形式gef ➤ pi print(hexdump( gef.memory.read(parse_address($pc), length0x20 ))) 0x0000000000000000 f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 ....1.I..^H..H.. 0x0000000000000010 f0 50 54 4c 8d 05 66 0d 01 00 48 8d 0d ef 0c 01 .PTL..f...H.....获取内存布局gef.memory.maps返回Section对象列表实现见 gef.py#L12274gef ➤ pi print(\n.join([ f{x.page_start:#x} - {x.page_end:#x} for x in gef.memory.maps])) 0x555555554000 - 0x555555558000 0x555555558000 - 0x55555555c000 0x55555555c000 - 0x5555555575000 0x5555555576000 - 0x5555555577000 0x5555555577000 - 0x5555555578000 0x5555555578000 - 0x555555559a000 0x7ffff7cd8000 - 0x7ffff7cda000 [...]简化命令编写的装饰器API 还提供了一批装饰器来简化命令的编写实现集中在 gef.py#L400-L469 的 Decorators 区段only_if_gdb_running仅在存在活动调试会话时执行否则输出 No debugging session active 警告gef.py#L403-L413only_if_gdb_target_local仅在本地目标非 GDBremote远程调试时执行远程会话下输出 This command cannot work for remote sessions. 警告gef.py#L416-L426此外还有deprecated为即将移除的命令附加弃用警告、experimental_feature提示功能不稳定、only_if_events_supported检查 GDB 事件支持情况等。输出方面面板与命令中应统一使用gef_print()gef.py#L236而非裸print以保证 GEF 的样式与缓冲机制一致。使用parse_arguments规范解析命令参数当命令需要结构化参数时parse_arguments装饰器是基于argparse的官方方案parse_arguments( {required_argument_1: DefaultValue1, ...}, {--optional-argument-1: DefaultValue1, ...} )它会在调用do_invoke前完成参数解析并把结果存入kwargs[arguments]——因此被装饰函数的签名必须包含*args, **kwargs。参数类型直接从默认值推断唯一的例外是布尔值默认值True对应argparse的store_true动作。几个关键行为细节均可在 gef.py#L495-L566 的实现中得到确认整型默认值会启用int_wrapperint(x, 0)意味着0x7fff这样的十六进制输入也能被正确解析可变数量参数把默认值写成tuple或list即启用nargs*元素类型取可迭代对象第一个元素的类型注意默认值列表不能为空否则无法推断类型可选参数同样支持列表值此时会注册为actionappend可多次出现累积短/长选项组合参数名可以是(--long-argument, -l)这样的元组。# 可变数量参数 选项示例 parse_arguments( {instructions: [nop, int3, hlt], }, {--arch: x64, } ) # 组合选项标志示例 parse_arguments( {}, {(--long-argument, -l): value, } )文档中的完整示例class MyCommand(GenericCommand): [...] parse_arguments({foo: [1,]}, {--bleh: , (--blah, -l): False}) def do_invoke(self, argv, *args, **kwargs): args kwargs[arguments] if args.foo 1: ... if args.blah True: ...当用户输入gef➤ mycommand --blah 3 14 159 2653函数内即可使用args.foo [3, 14, 159, 2653] # a List(int) from user input args.bleh # the default value args.blah True # set to True because user input declared the option (would have been False otherwise)注意源码中一个容易踩坑的细节对可选参数而言布尔默认值的语义与出现即置位相关——store_true/store_false的选择由默认值决定默认False→store_true因此用户声明了该选项才表现为Truegef.py#L548-L551。为新架构添加支持为 GEF 添加新架构支持的官方路径是继承Architecture类基类实现见 gef.py#L2624社区各架构的参考实现集中在gef-extras仓库的archs/目录。更精确的架构匹配可以通过静态方法supports_gdb_arch()完成基类声明于 gef.py#L2672它接收唯一参数gdb_strGDB 报告的目标架构名str类型返回值语义为——True当前Architecture类支持该目标二进制False明确不支持None跳过本次判定让 GEF 继续用默认方式推断架构。文档给出的典型例子是 ARM Cortex-M——某些目标如armv7m应当优先使用 Cortex-M 实现而非通用 ARM 实现staticmethod def supports_gdb_arch(gdb_arch: str) - Optional[bool]: return bool(re.search(^armv.*-m$, gdb_arch))进一步参考完整 API 参考GEF 提供的全部类与函数的自动生成文档位于 docs/api/gef.md配合仓库中的 API 测试如tests/api/gef_arch.py、tests/api/gef_memory.py、tests/api/gef_session.py等可以验证各原语的实际行为与边界条件命令与函数式扩展除GenericCommand外register同样支持注册GenericFunction需_function_属性与invoke方法见 gef.py#L5306-L5312适合封装不面向命令行的公共逻辑供其他命令复用调试扩展本身自定义命令抛出的异常可借助 GEF 的gef.show_last_exception等机制排查仓库的 docs/deprecated.md 记录了已废弃 API 的迁移建议写扩展前建议先确认所用 API 未进入弃用清单。按骨架 → 注册 → 参数解析 → 上下文面板 → 架构扩展的顺序实践下来你就拥有了与 GEF 内置命令同等地位的扩展能力可source加载、可~/.gdbinit常驻、拥有自动生成的 help 语法与独立的命令级配置项。赞分享网络安全开发工具【免费下载链接】gefGEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs reverse engineers on Linux项目地址https://gitcode.com/gh_mirrors/gef/gef点击查看免费下载相关推荐GEF扩展开发指南打造你的专属调试命令GEF扩展开发指南打造你的专属调试命令 前言 GEF作为GDB的增强工具不仅提供了丰富的调试功能更重要的是它允许开发者快速创建自定义命令。本文将深入讲解如网络安全开发工具股票K线预测准确率85%Kronos开源模型把行情翻译成机器语言5分钟带你跑通第一个预测股票K线预测准确率85%Kronos开源模型把行情翻译成机器语言5分钟带你跑通第一个预测 凌晨一点你盯着满屏红绿K线又一次被自己的判断打脸说突破它阴人工智能大模型基础模型预训练金融科技「生化环材四天王」的由来张雪峰.skill天坑专业论的完整逻辑「生化环材四天王」的由来张雪峰.skill天坑专业论的完整逻辑 张雪峰.skillzhangxuefeng skill是一个开源的认知操作系统把高考志愿AI 技能交互助手上一篇如何用Ice重塑macOS菜单栏从杂乱到整洁的效率革命下一篇ADCSKiller实战教程从零开始利用ESC1和ESC8漏洞获取域管理员权限创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

文件上传方案选型指南:SCP/SFTP/FTP/HTTP/Rsync深度对比

文件上传方案选型指南:SCP/SFTP/FTP/HTTP/Rsync深度对比

1. 本地文件上传到服务器:不是“选一个工具就行”,而是“按场景配方案”你有没有过这种经历:凌晨两点,线上服务突然报错,急需把修复后的配置文件推上去;或者刚写完一段Python脚本,想立刻在远程服…

2026/9/25 9:34:37 阅读更多 →
桂亦威律师涉税刑事案件辩护服务性价比怎么样

桂亦威律师涉税刑事案件辩护服务性价比怎么样

凌晨时分,写字楼里还有一盏灯亮着。一家民营企业的会议室桌上,摊着三年来的账册和一纸刚送达的文书,老板盯着文书上的字句,久久没有说话。那一刻他才真正明白:税务问题走到深处,牵动的不只是补税金额&#…

2026/9/25 9:33:36 阅读更多 →
河南靠谱的发电机出租服务公司推荐

河南靠谱的发电机出租服务公司推荐

行业普遍踩坑痛点梳理在河南地区找发电机出租服务的企业,几乎都踩过这些实打实的坑: 临时用电成本过高:工地、市政抢修等短期项目想自己买发电机,少则几万多则几十万的投入,后续设备闲置、存放保养还要额外花钱&#x…

2026/9/25 9:33:36 阅读更多 →

最新新闻

从免费CRM到独立部署:小团队搭建私人CRM网站全记录

从免费CRM到独立部署:小团队搭建私人CRM网站全记录

上个月我终于把客户资料从微信聊天记录、Excel表格和记事本里统一搬了出来,全部塞进了一套自己部署的CRM系统里。项目代号DeskcommCRM,听起来像个大厂产品,其实是我基于开源组件和一台轻量云服务器搭起来的私人客户关系管理网站。到今天跑了1…

2026/9/25 12:52:24 阅读更多 →
逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现

逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现

逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现 【免费下载链接】tftpd64 The working repository of the famous TFTP server. 项目地址: https://gitcode.com/gh_mirrors/tf/tftpd64 Tftpd64 是 Windows 平台上最著名的 TFT…

2026/9/25 12:52:24 阅读更多 →
Large Language Models for Summarizing Czech Historical Documents and Beyond

Large Language Models for Summarizing Czech Historical Documents and Beyond

文章主要内容与创新点总结 一、主要内容 本文聚焦捷克语文本摘要任务,尤其是历史文献摘要这一研究缺口,展开了系统性研究,具体内容如下: 研究背景:文本摘要旨在精简文本同时保留核心信息,当前该领域研究多集中于英语等资源丰富语言,而捷克语(尤其是历史捷克语)因语言…

2026/9/25 12:52:24 阅读更多 →
Windows 8.1原版镜像下载与校验:MSDN正式版、SHA1验证及UEFI/GPT安装指南

Windows 8.1原版镜像下载与校验:MSDN正式版、SHA1验证及UEFI/GPT安装指南

隔三差五就有人来问我:网上那些 Windows 8.1 纯净版、完美优化版、一键装机版,到底能不能用?我的回答一直没变——如果你需要的是一个稳定的 Windows 8.1 镜像下载,就老老实实找微软官方原版,尤其是带 MSDN 正式版字样…

2026/9/25 12:52:24 阅读更多 →
自建CRM系统全攻略:从LNMP架构到数据安全运维

自建CRM系统全攻略:从LNMP架构到数据安全运维

先说个背景。去年团队规模从三个人扩到十来个人的时候,我们做的第一件事不是换办公室,而是认真解决客户信息管理的问题。之前客户资料全躺在个人微信、Excel 表格和邮箱里,每个人记法还不一样,有人记在备注里,有人单独建了个文档&…

2026/9/25 12:52:24 阅读更多 →
开放式代码评审实践:让每一行代码都被认真读过

开放式代码评审实践:让每一行代码都被认真读过

1. 开放式代码评审:让每一行代码都被认真读过先聊个场景。你花了几个小时写了一个功能,提交了合并请求,两天后评审人才姗姗来迟,留下一句“LGTM”就合入了。你心里清楚,这份代码里有几处设计瑕疵,有些边界条…

2026/9/25 12:51:23 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →