x64dbg 的 gpa 命令实战:获取 DLL 导出函数地址的完整指南
x64dbg 的 gpa 命令实战获取 DLL 导出函数地址的完整指南【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbggpaGet Process Address是 x64dbg 内置的一条实用命令用于获取已加载 DLL 中导出函数Export的地址。无论是定位kernel32:LoadLibraryW、ntdll.dll:NtQueryInformationProcess这类系统 API还是在脚本中动态解析导出地址gpa都是最直接的入口。读完本文你将掌握gpa的完整语法、$result返回值语义以及它背后module:export表达式解析与转发导出Forwarded Export解析的底层原理可直接在命令行和脚本中灵活使用。命令概述一行命令取到导出地址gpa是 x64dbg 内置调试命令之一命令注册于 src/dbg/x64dbg.cppdbgcmdnew(gpa, cbInstrGpa, true); //get proc address其功能正如命令注释所写——get proc address获取 DLL 内部某个导出函数的地址。它本质上是一条对API 表达式解析的薄封装把用户传入的导出名以及可选的 DLL 名拼装成模块名:导出名形式的表达式交给 x64dbg 的表达式解析器求值再把结果写入$result变量。同时它也被列入脚本命令表 src/dbg/script_commands.txt因此既能在命令行窗口使用也能在 x64dbg 脚本中调用。语法与参数gpa ExportName [DLLName]参数含义是否必填arg1导出Export名称必填arg2DLL 名称可选arg1导出名要查找的导出函数名称例如LoadLibraryW、VirtualAlloc、NtQueryInformationProcess。导出名不区分大小写底层按大小写不敏感方式匹配。arg2DLL 名可选限定在哪个模块中查找。若省略x64dbg 会枚举当前已加载的所有模块逐个查找匹配的导出若提供了 DLL 名则只在指定模块中解析。返回值$result 变量gpa执行结束后会设置$result变量找到导出$result被设置为该导出函数的实际加载地址虚拟地址未找到导出$result被设置为0。因此脚本中惯用的判断写法是gpa LoadLibraryW kernel32 cmp $result, 0 ; 为 0 表示未找到源码剖析cbInstrGpa 的实现gpa的实际处理函数是cbInstrGpa定义在 src/dbg/commands/cmd-misc.cpp完整实现如下bool cbInstrGpa(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) return false; char newcmd[deflen] ; if(argc 3) sprintf_s(newcmd, \%s\:%s, argv[2], argv[1]); else sprintf_s(newcmd, %s, argv[1]); duint result 0; if(!valfromstring(newcmd, result, false)) return false; varset($RESULT, result, false); return true; }这段代码揭示了gpa的完整工作流程参数检查通过IsArgumentsLessThan(argc, 2)确保至少提供了导出名命令本身算argv[0]导出名是argv[1]。拼装表达式如果提供了 DLL 名argc 3拼装为DLL名:导出名的形式例如kernel32:LoadLibraryW——用双引号包裹模块名是为了防止模块名中出现空格或特殊字符破坏表达式语法如果省略 DLL 名则直接把导出名作为表达式传入。表达式求值调用valfromstring解析该字符串得到地址result。写入结果通过varset($RESULT, result, false)将地址写入$result变量。函数声明位于 src/dbg/commands/cmd-misc.h。可以看出gpa是命令行语法糖它让用户免去手写kernel32:LoadLibraryW这种带引号的表达式直接以gpa LoadLibraryW kernel32更自然地表达取某模块某导出地址。底层原理valapifromstring 支持的寻址语法gpa的真正解析逻辑位于表达式求值链路中的valapifromstringsrc/dbg/value.cpp。该函数是 x64dbg 表达式系统解析 API 地址的统一入口在valfromstring的解析顺序中优先级很高位于插件回调之后、标签与符号解析之前见 src/dbg/value.cpp。理解它就等于掌握了gpa以及一切模块:导出表达式的所有能力边界。1. 显式格式模块:导出冒号:是最明确的定界符。Windows 文件路径中不能包含:详见 MSDN 命名约定因此它不会与路径冲突gpa LoadLibraryW kernel32 ; 内部拼装为 kernel32:LoadLibraryW模块名部分还支持以下特殊写法写法含义:导出名模块名为空解析当前反汇编视图选中模块的导出模块:base/模块:imagebase/模块:header获取模块加载基址模块:entrypoint/模块:entry/模块:oep/模块:ep获取模块入口点模块:$RVA模块基址 指定 RVA$前缀模块:#FileOffset把文件偏移转换为虚拟地址#前缀例如在gpa中省略第二个参数、直接写gpa VirtualAlloc时x64dbg 会走无模块名分支枚举所有已加载模块查找该导出并对命中结果按规则优先返回 kernel32 的导出其余命中会打印到日志窗口见 src/dbg/value.cpp。2. 兼容格式模块.导出与?分隔符kernel32.GetProcAddress这种点号格式同样受支持为兼容 OllyDbg 风格的 API 表达式通过strstr(name, ..) ? strchr(name, .) : strrchr(name, .)定位定界符模块?导出使用?作为定界符时禁用转发导出解析resolveForwards false用于获取导出表项本身的原始地址而不是转发目标地址。3. 序号导出模块:序号除了按名称查找valapifromstring还支持按导出序号寻址模块:0x1A按十六进制序号查找默认 16 进制模块:.26带.前缀表示十进制序号模块:0特例返回模块基址。底层通过modInfo-exportOrdinalBase换算序号在导出表中的索引见 src/dbg/value.cpp。转发导出与 API Set 解析gpa解析到的地址未必是导出表里写的那个地址。MODINFO::getProcAddresssrc/dbg/module.cpp在处理命中项时会检查转发导出forwarded export如果某导出项被标记为转发如forwardName形如KERNEL32.HeapAlloc它会递归解析到真正的目标模块与目标导出若目标属于api-*/ext-*前缀的 API Set 虚拟模块还会先通过resolveApiSetForward解析 API Set 重定向。转发深度由maxForwardDepth控制逐层递减防止死循环。这意味着在 Windows 10 上执行gpa CreateFileW api-ms-win-core-file-l1-1-0得到的将是重定向后的真实实现地址通常是KERNELBASE.dll中的实现这正是逆向分析时需要的实际调用目标。实战示例命令行窗口直接使用在调试会话中gpa依赖调试上下文必须在调试状态下使用命令窗口输入gpa LoadLibraryW kernel32执行后日志无输出成功时不打印但$result已被设置为kernel32.dll中LoadLibraryW的地址可用var $result查看。在脚本中使用由于gpa在 src/dbg/script_commands.txt 中被标记为脚本命令可直接写入脚本gpa NtQueryInformationProcess ntdll.dll cmp $result, 0 je notfound log NtQueryInformationProcess {$result} notfound: log export not found典型场景是脚本先取GetProcAddress之类关键 API 的地址再结合SetBPX下条件断点或与call等脚本命令配合完成动态调用。在表达式中直接使用等价写法gpa只是表达式语法的一层封装任何需要地址的场景都可以直接写表达式kernel32:LoadLibraryW ; 冒号定界 kernel32.HeapAlloc ; 点号定界OllyDbg 风格 kernel32:0x1A ; 序号寻址实际上 x64dbg 内部代码也大量采用这一表达式例如loadlib命令加载 DLL 前先解析kernel32:LoadLibraryW取得函数地址src/dbg/commands/cmd-misc.cppgetcommandline相关逻辑解析kernelBase:GetCommandLineA与kernel32:GetCommandLineAsrc/dbg/debugger.cpp。可见module:export表达式是整个调试器内部公用的寻址机制gpa只是把它开放给了用户。注意事项与限制必须在调试状态下使用valapifromstring首先检查DbgIsDebugging()未调试时直接返回失败src/dbg/value.cpp模块必须已加载gpa查找的是进程当前已加载模块的导出表ModBaseFromName找不到目标模块时解析失败返回 0尚未加载的 DLL 可先用loadlib加载失败时$result为 0当导出不存在、模块未加载或参数不足时cbInstrGpa返回false且$result保持0脚本务必对0做防御判断省略 DLL 名时的多命中不指定模块会枚举所有模块命中多个时优先返回 kernel32 的导出其余命中会打印到日志可通过日志观察候选地址src/dbg/value.cpp无参数时静默失败只输入gpa不带任何参数会被参数检查直接拦截IsArgumentsLessThan不会产生任何输出。小结gpa以极简的接口导出名 可选模块名封装了 x64dbg 强大的 API 表达式解析能力从模块:导出、点号兼容格式、序号寻址到转发导出与 API Set 重定向其底层valapifromstringMODINFO::getProcAddress构成了完整的导出寻址链路。掌握gpa不仅能在命令行和脚本中快速取得 API 地址更理解了整个 x64dbg 表达式系统中module:export语法的运作机理是逆向调试中高频、实用的基础技能。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →