ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

x64dbg argumentlist 命令详解:在引用视图中列出与脚本化遍历用户自定义参数

x64dbg argumentlist 命令详解:在引用视图中列出与脚本化遍历用户自定义参数 x64dbg argumentlist 命令详解在引用视图中列出与脚本化遍历用户自定义参数【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg导读argumentlist是 x64dbg 用户数据库User Database系列命令之一用于在**引用视图Reference View**中集中列出当前调试会话里所有用户自定义的参数argument区间并以$result变量返回参数数量方便脚本继续处理。本文以官方命令文档 argumentlist.md 为主体结合 x64dbg 源码cmd-user-database.cpp、argument.h、argument.cpp与表达式函数实现exprfunc.cpp完整讲解命令用法、底层数据结构和脚本化遍历方案让读者既能上手操作也能理解其实现原理。一、命令速览argumentlist是用户数据库命令组中的一员。该命令组用于操作调试器持久化的用户标注数据官方索引见 docs/commands/user-database/index.rst其中与 argument 相关的命令共有四条命令作用argumentadd添加一个参数区间起始地址、结束地址argumentdel按地址删除一个参数argumentlist在引用视图中列出全部参数argumentclear清除所有模块中的全部参数这些命令在调试器启动时注册于 src/dbg/x64dbg.cppdbgcmdnew(argumentadd, cbInstrArgumentAdd, true); //add argument dbgcmdnew(argumentdel, cbInstrArgumentDel, true); //delete argument dbgcmdnew(argumentlist, cbInstrArgumentList, true); //list arguments dbgcmdnew(argumentclear, cbInstrArgumentClear, false); //delete all arguments注意dbgcmdnew的第三个参数为true时表示该命令可在脚本中注册使用argumentclear传false即它不用于脚本注册场景。基本用法argumentlistarguments参数argumentlist没有任何参数直接执行即可。result结果执行后$result变量会被设置为用户自定义参数的总数量如果没有参数$result为 0同时在日志中输出No arguments。实际输出效果执行命令后引用视图被重置并以 Arguments 为标题显示 4 列内容Start参数区间的起始地址End参数区间的结束地址Disassembly (Start)起始地址处的反汇编指令Label/Comment起始地址对应的标签若无标签则显示注释。视图每行还会附带一个 Delete 命令内部执行argumentdel $0其中$0为当前行地址可直接在引用视图中对某一项发起删除。二、源码级解析argumentlist 是如何工作的命令的核心实现位于 src/dbg/commands/cmd-user-database.cpp 的cbInstrArgumentList函数其执行流程如下初始化引用视图通过GuiReferenceInitialize、GuiReferenceAddColumn建立上述 4 列并把行数清零枚举参数先以ArgumentEnum(0, cbsize)获取所需缓冲区大小若无参数则打印No arguments并提前返回分配内存并填充使用MemoryARGUMENTSINFO*分配缓冲区再次调用ArgumentEnum填充数据计算条目数count cbsize / sizeof(ARGUMENTSINFO)逐行写入视图对每条参数分别取出start、end地址并通过GuiGetDisassembly、LabelGet、CommentGet补充反汇编、标签或注释内容设置$resultvarset($result, count, false)将参数总数写入结果变量附加删除命令并刷新GuiReferenceAddCommand(..., argumentdel $0)后GuiReferenceReloadData()刷新视图。其中ArgumentEnum定义于 src/dbg/argument.cpp它直接委托给内部容器Arguments::Enum(List, Size)负责以ARGUMENTSINFO数组的形式导出全部参数。底层数据结构每条参数在内存中对应 src/dbg/argument.h 定义的ARGUMENTSINFO结构体struct ARGUMENTSINFO { duint modhash; // 所属模块的哈希用于定位模块 duint start; // 参数区间起始地址 duint end; // 参数区间结束地址 bool manual; // 是否由用户手动添加区别于自动分析 duint instructioncount; // 区间内指令数 std::string mod() const { return ModNameFromHash(modhash); } };参数数据集中存放在内部容器Arguments静态实例arguments见 argument.cpp中。相关操作函数均在 argument.h 声明ArgumentAdd(Start, End, Manual, InstructionCount)新增参数内部会先校验起始地址可读MemIsValidReadPtr见 argument.cppArgumentDelete(Address)按地址删除参数见 argument.cppArgumentGet / ArgumentGetInfo按地址查询参数信息ArgumentOverlaps / ArgumentDelRange区间重叠判断与区间删除ArgumentClear清空全部参数ArgumentEnum枚举导出参数列表ArgumentCacheSave / ArgumentCacheLoad参数的数据库持久化存取。也就是说argumentlist本质上是把ArgumentEnum的结果通过 GUI 桥接层GuiReference*系列渲染到引用视图并把枚举计数回写到$result。三、配合引用视图表达式函数在脚本中遍历参数原文档特别指出引用视图的内容可以在脚本中用ref.addr表达式函数 进行迭代。argumentlist执行后引用视图中的每一行都对应一条参数记录因此可以结合ref.count()与ref.addr(i)逐条读取。表达式函数实现这两个函数注册于 src/dbg/expressionfunctions.cppRegisterEasy(ref.count, refcount); RegisterEasy(ref.addr,ref, refaddr);其实现位于 src/dbg/exprfunc.cppduint refcount() { return GuiReferenceGetRowCount(); } duint refaddr(duint row) { auto content GuiReferenceGetCellContent(int(row), 0); duint addr 0; valfromstring(content, addr, false); BridgeFree(content); return addr; }ref.count()直接返回引用视图当前的行数与$result在数值上一致都是参数总数ref.addr(i)读取引用视图第i行第 0 列即 Start 列的地址字符串解析为duint地址后返回。由于参数列表的 Start 列正是参数起始地址脚本拿到后即可对每条参数做进一步处理。官方脚本示例原文完整继承在脚本.txt 脚本由scriptload加载执行中可这样遍历引用视图中的全部参数i 0 loop: addr ref.addr(i) log reference {d:i} {p:addr} i cmp i, ref.count() jne loop脚本逻辑说明i 0初始化行索引addr ref.addr(i)取第i行的起始地址log reference {d:i} {p:addr}以十进制打印行号、以指针格式打印地址i递增cmp i, ref.count()与jne loop形成循环直到遍历完所有行。该写法同样适用于其他填充引用视图的命令如commentlist、labellist、functionlist等参见 docs/commands/user-database/是 x64dbg 脚本中处理引用数据的通用套路。四、与 argument 家族命令的配合使用要理解argumentlist的输入输出需要掌握其配套命令官方文档同样位于 docs/commands/user-database/。argumentadd —— 添加参数参数arg1为参数区间起始地址arg2为参数区间结束地址结果不设置任何结果变量。源码实现见 cmd-user-database.cpp两个地址都会经valfromstring解析因此支持表达式随后调用ArgumentAdd(start, end, true)Manual置true表示用户手动添加。添加成功后打印Argument added!并刷新所有视图。argumentdel —— 删除参数参数arg1为参数区间内的任意地址结果不设置任何结果变量。实现见 cmd-user-database.cpp内部调用ArgumentDelete(addr)成功则打印Argument deleted!。正如上文所述argumentlist的引用视图行内 Delete 命令正是包装为argumentdel $0。argumentclear —— 清空全部参数参数无结果不设置任何结果变量。对应ArgumentClear(false)一次性删除所有模块中的全部参数。典型工作流// 1. 定义参数区间 argumentadd 0x401000, 0x4012FF // 2. 列出全部参数引用视图中查看$result 记录数量 argumentlist log total arguments: {d:$result} // 3. 脚本遍历引用视图处理每条参数 i 0 loop: addr ref.addr(i) log argument start {p:addr} i cmp i, ref.count() jne loop // 4. 按需删除/清空 argumentdel 0x401050 // 删除包含该地址的参数区间 argumentclear // 或一键清空五、注意事项与使用限制引用视图是单例的执行argumentlist会覆盖引用视图的当前内容其他引用类命令同理。若需保留数据应先用ref.get/ 循环脚本把数据读出。$result与ref.count()两者数值一致但$result是命令结束时的一次性快照若之后引用视图被其他命令改写ref.count()会反映新内容而$result不变。地址必须可读添加参数时ArgumentAdd会通过MemIsValidReadPtr校验起始地址可读非法地址将导致Failed to add argument。删除依据为区间包含argumentdel接受区间内任意地址即可命中删除底层通过VaKey(Address, Address)查找所在区间无需精确给出起始地址。持久化参数属于用户数据库的一部分可通过dbsave/dbload见 docs/commands/user-database/dbsave.md、docs/commands/user-database/dbload.md随数据库文件保存和加载底层由ArgumentCacheSave / ArgumentCacheLoad支撑。六、小结argumentlist虽是一个无参的简单命令却是 x64dbg 用户数据库中查看参数类标注的核心入口它把内部Arguments容器中的数据通过引用视图呈现给用户用$result暴露数量并以ref.addr/ref.count表达式函数向脚本开放逐行访问能力。结合argumentadd、argumentdel、argumentclear即可完成参数标注的增删查清全流程配合官方脚本示例可方便地对参数列表做自动化分析处理。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表