
网络安全开发工具【免费下载链接】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),仅供参考