ARTICLE DETAIL

资讯详情

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

x64dbg dec 命令详解:通用自减指令的语法、实现原理与脚本实战

x64dbg dec 命令详解:通用自减指令的语法、实现原理与脚本实战 x64dbg dec 命令详解通用自减指令的语法、实现原理与脚本实战【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbgdec是 x64dbg 调试器命令行体系中面向通用运算分类的自减命令用于将某个目标变量、寄存器或可写表达式的值减少 1。本文以官方命令参考文档 docs/commands/general-purpose/dec.md 为核心结合src/dbg下命令注册、命令分发与表达式解析的源码实现系统讲解dec的语法、参数约束、底层调用链、与inc/add/sub等同类命令的关系并给出可直接用于脚本与自动化调试的实战示例。读完本文你将能够准确地在命令行与脚本环境中使用dec完成计数器递减、循环遍历与寄存器微调等操作。dec 命令速览功能与语法dec是 decrease 的缩写语义与 C 语言中的自减运算一致把目标值减 1。命令参考文档对其核心契约描述得非常精简功能Decrease a value将某个值减少 1。参数arg1指定操作目标Destination。结果该命令本身不设置任何文档化的结果变量This command does not set any result variables。因此最基本的调用形式只有一条dec arg1例如若要令变量count的值减 1dec count从命令注册表可以确认dec与inc、add、sub、mul、div等同属通用目的general purpose命令族在 src/dbg/x64dbg.cpp#L110-L127 中统一注册dbgcmdnew(inc, cbInstrInc, false); dbgcmdnew(dec, cbInstrDec, false); dbgcmdnew(add, cbInstrAdd, false); dbgcmdnew(sub, cbInstrSub, false);注册时第二个参数为 false说明dec并非仅限调试会话debug-only使用——即使当前没有附加调试进程命令行与脚本中依然可以执行dec来操作变量。参数详解Destination 可以是哪些目标arg1是dec唯一且必填的参数其类型在参考文档中仅标注为 Destination。结合 x64dbg 的赋值机制valsetscalar/varnew/handleAssignment可以从实现上推断arg1支持以下可写目标用户变量通过var命令创建的脚本变量例如dec myvar。寄存器dec eax、dec rcx等寄存器名称在 x64dbg 中同样作为可赋值对象处理可以推断其会被表达式解析器识别并回写。可求值的赋值表达式任何能作为赋值左侧lvalue解析并支持写回的表达式。值得注意的一个边界若arg1本身是一个纯值例如直接写dec 100因为目标不可写命令将失败并报出Invalid variable ...之类的错误。这一行为与同文件中的ReadWriteVariable辅助函数src/dbg/commands/cmd-general-purpose.cpp#L9-L37所体现的校验逻辑一致先尝试解析目标若目标是一个已存在的值不可写则判定为非法目的地。源码级实现从 cbInstrDec 到自减表达式dec的完整执行链路可以拆成三段每一段都有清晰的源码对应。第一段命令回调 cbInstrDecdec的实际处理函数定义在 src/dbg/commands/cmd-general-purpose.cpp#L46-L51bool cbInstrDec(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) return false; return cmddirectexec(StringUtils::sprintf(%s--, argv[1]).c_str()); }实现非常简洁先通过IsArgumentsLessThan(argc, 2)校验参数个数——dec命令连同其目标至少要两个参数缺参直接返回 false随后将argv[1]即目标拼上后缀--构造成目标--形式的表达式字符串交给cmddirectexec执行。也就是说dec x在底层等价于提交表达式x--。第二段命令分发器 cmddirectexeccmddirectexec是 x64dbg 内部直接执行一条命令/表达式的统一入口实现在 src/dbg/command.cpp#L326-L362。它对输入先做cmdsplit分割与去空白然后尝试用cmdget按命令名查找若命中命令表则执行对应的命令回调若找不到则把整段文本交给ExpressionParser按表达式求值并将结果写入内置变量$ans。由于x--并不是注册过的命令名dec构造出的目标--会走表达式求值分支。这是dec能同时操作变量、寄存器等多种目标的原因——它复用了一整套表达式引擎而不是自己实现减法逻辑。第三段表达式引擎对--的处理ExpressionParser在词法分析阶段会把--识别为前缀或后缀自减操作符OperatorPrefixDec/OperatorSuffixDec见 src/dbg/expressionparser.cpp#L271-L283并在求值阶段按标准的 C 语义执行src/dbg/expressionparser.cpp#L778-L808case ExpressionParser::Token::Type::OperatorPrefixDec: resultv --op1v; break; case ExpressionParser::Token::Type::OperatorSuffixDec: resultv op1v--; break; ... if(!handleAssignment(op1.data.c_str(), op1v, silent, allowassign)) return false; result ExpressionParser::EvalValue(resultv);由于dec构造的是后缀形式x--其语义为先取旧值、再自减、最后回写op1v保存自减后的新值并通过handleAssignment写回目标表达式自身的求值结果resultv则是自减前的旧值。这一点对于理解下文的结果变量行为很关键。结果变量官方契约与表达式引擎的额外行为参考文档明确写道 This command does not set any result variables即dec本身不会像cmp、test等命令那样写入$_EZ_FLAG、$_BS_FLAG之类的文档化标志变量。不过从cmddirectexec的表达式分支src/dbg/command.cpp#L343-L348可以看到一个底层细节ExpressionParser parser(command); duint result; if(!parser.Calculate(result, valuesignedcalc(), true, false)) return false; varset($ans, result, true);即任何经由表达式路径求值的输入都会把结果写入$ans。因此dec x执行后$ans会携带表达式x--的求值结果——按照后缀自减语义$ans保存的是自减之前的旧值而目标x本身已被更新为减 1 后的新值。这与文档所述的命令不设置结果变量并不冲突那是命令层面的契约声明而$ans属于表达式引擎的通用行为可作为脚本中读取旧值的一种技巧取决于具体需求务必注意其后缀语义。与同族命令的对照dec / inc / add / subdec并不是孤立存在它与inc、add、sub共享同一套命令转表达式的实现模式对照阅读能快速理解整个通用运算命令族实现均位于 src/dbg/commands/cmd-general-purpose.cpp命令底层转换语义文档dec arg1arg1--目标减 1dec.mdinc arg1arg1目标加 1inc.mdsub arg1 arg2arg1-arg2目标减 arg2sub.mdadd arg1 arg2arg1arg2目标加 arg2add.mdinc的回调与dec完全对称src/dbg/commands/cmd-general-purpose.cpp#L39-L44bool cbInstrInc(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) return false; return cmddirectexec(StringUtils::sprintf(%s, argv[1]).c_str()); }区别仅在拼装的运算符是还是--。当需要步进不为 1 时则应改用add/sub并传入第二操作数dec只负责固定的减 1 场景这是它保持单参数接口的原因。实战场景脚本中的递减计数dec最常见的用途是在调试脚本中维护计数器与 var 创建变量、msg输出消息配合使用。一个可直接在 x64dbg 命令行逐条执行的最小示例var count5 dec count msg {count}执行后count由 5 变为 4消息框显示 4。若要反复递减可在循环结构中调用dec例如结合 x64dbg 的循环命令实现处理 N 个数据块之类的遍历逻辑由于dec不依赖调试会话状态这类计数脚本即使在非调试状态下也可以正常运行。再结合上文的结果变量说明若需要同时记录旧值可以在dec之后读取$ansvar count10 dec count ; count 变为 9$ans 保存旧值 10小结dec是 x64dbg 通用运算命令族中最简洁的成员之一官方参考文档仅用减少一个值一句话概括其行为但其底层实现串联了命令注册x64dbg.cpp、命令转表达式cmd-general-purpose.cpp、命令分发command.cpp与表达式自减运算expressionparser.cpp四条链路。理解这条调用链不仅能正确使用dec也能举一反三地掌握inc、add、sub等整个命令族的内部机制为编写更复杂的 x64dbg 调试脚本打下基础。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表