ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

x64dbg 引用视图命令 refget 完全指南:从引用地址回读到脚本自动化实战

x64dbg 引用视图命令 refget 完全指南:从引用地址回读到脚本自动化实战 x64dbg 引用视图命令 refget 完全指南从引用地址回读到脚本自动化实战【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg导读refget是 x64dbg 调试器中用于从引用视图Reference View中按索引回读地址的命令常与refinit初始化引用视图和refadd向引用视图添加条目组合使用是脚本与自动化工作流中从搜索结果回读目标地址的标准手段。阅读本文后你将掌握引用视图三条命令的完整语法、参数语义、$result结果变量的使用方式以及它们与 x64dbg 内置搜索命令如findall、refstr等共享同一底层数据结构的实现原理并能在实际调试场景中直接编写可运行的脚本示例。refget按索引读取引用地址refget命令用于从当前的引用视图中取出指定索引行号对应的地址并把结果写入$result变量。它是 x64dbg 命令参考GUI 章节 中引用视图Reference View相关的三条命令之一与 refinit、refadd 构成完整的工作流。语法与参数refget arg1参数类型说明arg1整数表达式要读取的引用地址的从零开始zero-based的索引即引用视图中的行号arg1不限于字面量可以是任意合法的 x64dbg 表达式参见 表达式文档例如寄存器、变量或算术表达式refget 0 ; 读取第 0 行 refget 5 ; 读取第 5 行 refget $result ; 读取 $result 变量所指向的那一行 refget count-1 ; 读取最后一行假设变量 count 保存了总行数结果变量命令执行后$result变量被设置为所请求引用的地址成功$result 指定索引处的地址值失败索引越界、参数缺失或无法解析等$result0。因此脚本中可以通过判断$result 0来区分读取成功与失败refget 0 cmp $result, 0 je .notfound完整工作流refinit → refadd → refget单独使用refget没有意义它读取的是当前引用视图中的内容。引用视图的生命周期由 refinit 与 refadd 建立和维护。refinit初始化引用视图refinit [arg1]arg1可选新引用视图的标题支持字符串格式化不传标题时源码中会使用默认标题 Script见 cmd-gui.cpp 中GuiTranslateText(QT_TRANSLATE_NOOP(DBG, Script))。该命令不设置任何结果变量。调用后引用视图被重置为一个两列表格列标题为 Address 和 Data行数清零。refadd向引用视图添加条目refadd arg1 [arg2]arg1要放入引用视图的地址支持表达式arg2显示在地址之后的文本支持字符串格式化该命令不设置任何结果变量。注意文档明确要求在使用refadd之前必须先调用refinit。不过从源码实现看cbInstrRefadd在检测到bRefinit标志为 false 时会自动调用cbInstrRefinit完成初始化见 cmd-gui.cpp因此漏调refinit一般不会导致崩溃但为了行为可控仍建议按文档约定先初始化。一个可运行的完整脚本示例// 1. 初始化引用视图标题支持字符串格式化 refinit My finds at {a:entrypoint} // 2. 向引用视图添加条目地址 说明文本 refadd 0x401000 {a:0x401000} refadd 0x401050 {disasm0x401050} refadd rcx candidate: {x:rcx} // 3. 按索引回读地址 refget 1 // 此时 $result 应为 0x401050 // 4. 遍历引用视图 refget 0 mov $addr, $result在上面的示例中arg2使用了字符串格式化{a:...}输出带模块信息的地址描述{disasm...}输出该地址的反汇编文本{x:...}输出十六进制值。格式化语法详见字符串格式化文档。源码级原理命令背后的实现链路三条命令在调试器核心中的实现位于 src/dbg/commands/cmd-gui.cpp命令注册表在 src/dbg/x64dbg.cpp 中通过dbgcmdnew完成注册。refget 的内部流程cbInstrRefGetcmd-gui.cpp的实现要点校验参数数量IsArgumentsLessThan(argc, 2)少于 2 个参数直接返回失败通过valfromstring(argv[1], row, false)将索引参数解析为整数行号调用桥接函数GuiReferenceGetCellContent(int(row), 0)取出第 0 列Address 列的单元格文本内容——注意这里取回的是格式化后的字符串如00401050再用valfromstring(content, addr, false)把该文本重新解析回整数地址调用varset($result, addr, false)写入$result变量通过BridgeFree(content)释放桥接层分配的字符串内存。从中可以推断两点实现细节refget读取的是第 0 列Address 列而非第 1 列Data 列与文档取回引用地址的语义一致由于地址以文本形式存储再回读索引超出实际行数时GuiReferenceGetCellContent返回的内容为空或无效valfromstring解析失败后$result保持为0这与文档失败时返回 0的描述吻合。refinit / refadd 如何构造视图cbInstrRefinitcmd-gui.cpp调用一组桥接函数搭建视图骨架GuiReferenceInitialize(title) // 创建/重置引用视图并设置标题 GuiReferenceAddColumn(sizeof(duint)*2, Address) // 第 0 列宽度为一个指针的 2 倍十六进制地址 GuiReferenceAddColumn(0, Data) // 第 1 列宽度自适应 GuiReferenceSetRowCount(0) // 清空行数 GuiReferenceReloadData() // 通知 GUI 刷新cbInstrRefaddcmd-gui.cpp则先解析地址再取当前行数GuiReferenceGetRowCount()作为新行索引分别写入两列第 0 列用sprintf_s(addr_text, %p, addr)格式化为指针文本第 1 列用stringformatinline(argv[2])完成字符串格式化后写入。桥接层与 GUI 侧上述GuiReference*系列函数是调试器核心与 GUI 进程之间的桥接接口声明与导出位于 src/bridge/bridgemain.h 与 src/bridge/bridgemain.cpp。从函数签名看GuiReferenceGetCellContent(int row, int col)返回char*调用方负责释放这也解释了refget实现中为何需要BridgeFree。引用视图在搜索命令中的复用引用视图并非脚本专用——x64dbg 的大量搜索命令find、findall、refstr、findasm等都以同一套GuiReference*桥接接口把结果填充进引用视图。以 src/dbg/commands/cmd-searching.cpp 为例多个搜索实现都遵循如下模式见该文件第 191-230、345-417、487-620 行等处GuiReferenceInitialize(title) // 设置结果标题 GuiReferenceAddColumn(2 * sizeof(duint), ...) // 地址列 GuiReferenceAddColumn(0, ...) // 数据/反汇编列 ... GuiReferenceSetCellContent(refCount, 0, addrText) // 逐行写入这意味着任何向引用视图输出结果的命令其结果显示后都可以用refget在脚本中按行号回读地址。例如// 先执行一次搜索如 findall 或 refstr结果填充到引用视图 findall 0x401000, 0x402000, 41424344 // 然后按索引读取搜索结果中的第一条地址 refget 0 // $result 第一条匹配的地址这一设计让refget成为脚本衔接GUI 搜索结果与后续自动化处理的关键桥梁。常见问题与使用建议Q1refget返回 0 一定是失败吗不绝对。索引 0 对应的地址本身理论上可以为 0但实践中调试器地址很少为 0因此$result 0通常仍可作为失败判据最稳妥的做法是先用refadd记录行数并用cmp校验索引是否越界。Q2索引从 0 开始还是从 1 开始从 0 开始。cbInstrRefGet直接把argv[1]作为GuiReferenceGetCellContent的行号参数传入而行号是GuiReferenceSetCellContent写入时使用的index由GuiReferenceGetRowCount()自增得到因此第一条记录是行 0。Q3refget能在脚本中用于遍历整个视图吗可以。配合循环与变量参见 变量文档按索引递增调用即可注意在循环开始前保存行数快照避免在遍历过程中视图被其他命令重置。Q4为什么refadd的文档要求先调用refinit虽然源码中cbInstrRefadd对未初始化的情况做了自动补救但显式调用refinit可以让你同时指定标题并确保视图状态可预期是更规范、更利于脚本可读性的做法。参考资源命令官方文档refget、refadd、refinit命令列表总览GUI 命令索引核心实现src/dbg/commands/cmd-gui.cpp桥接接口src/bridge/bridgemain.cpp 与 src/bridge/bridgemain.h复用引用视图的搜索命令实现src/dbg/commands/cmd-searching.cpp配套语法字符串格式化、表达式【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表