x64dbg div 命令详解:除法运算的语法、表达式赋值语义与源码实现
2026/9/19 22:10:09 网站建设 项目流程
  • 逆向工程
  • 调试器
  • 开发工具
  • 应用安全

【免费下载链接】x64dbg

An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.

项目地址:https://gitcode.com/gh_mirrors/x6/x64dbg
点击查看免费下载

div是 x64dbg 调试器"通用算术"命令族中的除法命令,用于将两个值相除并把商写回第一个操作数。本文以命令参考文档 div.md 为骨架,结合命令实现源码 cmd-general-purpose.cpp 与表达式引擎 expressionparser.cpp,完整讲解div的语法、执行语义、除零边界行为与底层原理,并给出命令行、脚本及断点场景中的实战示例,帮助你在逆向分析与脚本自动化中准确使用除法运算。

命令定位:通用算术命令族中的除法

在 x64dbg 的命令体系中,div属于"通用目的(General Purpose)"命令组。该组集中了调试脚本中最常用的标量运算命令,包括incdecaddsubmulmulhidivandorxornegnotbswaprolrorshlshrsar等,完整清单参见 general-purpose/index.rst 中的 toctree。这些命令的共同特点是:它们并非 CPU 指令的封装,而是操作 x64dbg 表达式引擎的值(value),运算对象可以是寄存器、用户变量、内存位置或任意可解析的表达式。

div在其中承担除法角色:把目标值除以源值,再把结果写回目标。它不涉及浮点,执行的是表达式引擎中的整数除法,适用于地址计算、循环计数、步长换算等典型逆向工程场景。

语法与参数

原文档 div.md 定义了如下接口:

项目说明
命令名div
描述Divide two values.(将两个值相除)
arg1Destination. 目标,即被除数;除法结果写回此位置
arg2Source. 源,即除数
结果不设置任何结果变量(This command does not set any result variables.)

调用形式为:

div arg1, arg2

参数之间以逗号分隔(x64dbg 命令解析器同样接受空格分隔,逗号是更稳妥的写法)。arg1arg2都可以是表达式引擎支持的任何值形式,例如:

div eax, 4 ; eax = eax / 4,将寄存器值除以 4 div count, 0x10 ; 用户变量 count = count / 16 div dword:[00401000], 2 ; 内存位置的值除以 2 后写回该内存

从源码看,cbInstrDiv首先通过IsArgumentsLessThan(argc, 3)校验参数数量——命令名之外必须提供两个参数,不足则直接返回失败并输出错误提示,参见 cmd-general-purpose.cpp。这与同族的addsubmul等二元运算命令的参数校验逻辑完全一致。

执行语义:本质是表达式赋值arg1 /= arg2

理解div的关键在于:它不是一个独立的运算单元,而是被翻译成一个复合赋值表达式再交给表达式引擎执行。在 cbInstrDiv 的实现中:

bool cbInstrDiv(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 3)) return false; return cmddirectexec(StringUtils::sprintf("%s/=%s", argv[1], argv[2]).c_str()); }

div arg1, arg2等价于执行表达式arg1 /= arg2,这与add翻译为arg1 += arg2sub翻译为arg1 -= arg2mul翻译为arg1 *= arg2的模式一脉相承(参见 cmd-general-purpose.cpp)。cmddirectexec是 x64dbg 内部同步执行一条命令字符串的入口,声明于 command.h,实现在 command.cpp。

这一设计带来两个重要推论:

  1. 结果是写回的,而非返回值div将商直接写回arg1,因此文档明确说明"不设置任何结果变量"——与addsub等一致,不存在类似表达式函数的返回值可供后续命令读取;若需要在计算后保留原值,请先把arg1复制到临时变量再执行div
  2. arg1必须是可写的目标。它可以是寄存器、用户变量、内存位置等支持赋值的表达式;如果传入的是一个立即数常量,表达式引擎会将其判定为非法目标而报错。

底层实现:从命令注册到表达式求值

命令注册

div在调试器启动时注册到命令分发表,注册点位于 x64dbg.cpp:

dbgcmdnew("div", cbInstrDiv, false);

函数原型声明在 cmd-general-purpose.h。注册后,无论在命令行输入框、脚本文件还是断点命令文本中书写div,都会进入cbInstrDiv这一统一入口。

表达式求值中的除法

翻译出的arg1 /= arg2会进入表达式解析器。x64dbg 的表达式引擎(ExpressionParser)使用调度场算法(Shunting-yard)将中缀表达式转为逆波兰式,词法分析阶段识别/=复合赋值运算符,参见 expressionparser.cpp。在最终求值阶段,除法运算符OperatorDiv的处理如下,参见 expressionparser.cpp:

case ExpressionParser::Token::Type::OperatorDiv: if(op2 == 0) return false; result = op1 / op2; break;

可以看到,除法在求值前显式检查除数是否为 0,一旦op2 == 0就返回 false,整个表达式求值失败。这保证了div不会引发未定义行为,而是以一条可感知的错误终止本次运算。

整数除法语义

op1op2的类型是duint(x64dbg 的通用无符号整数类型,x86 下为 32 位、x64 下为 64 位),因此result = op1 / op2无符号整数除法,结果向零截断、不产生小数。例如div eax, 3eax = 10时结果为 3,而不是 3.33。若需要保留余数,可搭配表达式取模运算符%(同为OperatorMod,同样带除零检查,见 expressionparser.cpp)组合使用。

除零等边界情况

综合源码可以确认div的以下边界行为:

  • 除数为 0:表达式求值阶段返回 false,命令执行失败。这是 expressionparser.cpp 中if(op2 == 0) return false;的直接结果。
  • 参数不足IsArgumentsLessThan(argc, 3)拦截,命令失败并提示错误。
  • 目标不可写:若arg1是常量或无法解析的值,表达式引擎拒绝赋值,命令失败。
  • 整数溢出:无符号除法本身不会溢出;但若在写回arg1时目标宽度小于商的有效位(例如把 64 位结果写回 32 位寄存器),会按目标宽度截断,这与表达式引擎的常规赋值行为一致。

实战用法:命令行、脚本与断点

命令行直接计算

在 x64dbg 的命令行输入框(或通过脚本的cmd调用)直接输入:

div myvar, 8

执行后myvar的值变为原来的 1/8。可用于地址对齐、数组下标换算等即时计算。

脚本中的除法

在 x64dbg 脚本中,div常与其他算术命令组合完成复杂计算。脚本引擎执行命令字符串时同样走cmddirectexec通道(参见 simplescript.cpp),因此脚本中可直接书写:

var base var size mov base, 0x400000 mov size, 0x100 div size, 4 ; size = 0x40 add base, size ; base = 0x400040

结合变量系统(参见 variables/index.rst 与 Variables.md),可以先把被除数备份到临时变量,避免div覆盖原值后无法继续使用。

断点命令中的除法

x64dbg 的断点可以挂接命令文本,断点命中时通过cmddirectexec同步执行(参见 debugger.cpp)。因此可以把div写进断点命令,实现"命中时自动做除法并把结果存入变量"的自动化观察逻辑,例如在条件断点或日志断点前先执行div counter, 2更新计数。需要说明的是:条件断点的判定表达式本身使用表达式引擎求值,直接写(a / b) > 3即可,不必借助div命令;div的典型用途是在命令序列中完成有副作用的写回计算。

与同族算术命令的关系

div属于 x64dbg"通用算术"命令族,理解它的最佳参照是相邻命令:

  • add arg1, arg2arg1 += arg2,见 add.md;
  • sub arg1, arg2arg1 -= arg2,见 sub.md;
  • mul arg1, arg2arg1 *= arg2,见 mul.md;
  • mulhi arg1, arg2→ 乘法的高位部分写回,用于 64 位乘法的高半部分,见 mulhi.md;
  • inc arg1/dec arg1arg1++/arg1--,见 inc.md 与 dec.md。

它们在 cmd-general-purpose.cpp 中以同一套"翻译成复合赋值表达式 →cmddirectexec"的模式实现,参数校验、写回语义与错误处理完全一致。掌握div,就等于掌握了这一族命令的通用使用范式。

小结

div是 x64dbg 中语义简洁但用途广泛的除法命令:div arg1, arg2等价于表达式arg1 /= arg2,执行无符号整数除法并把商写回arg1,不设置任何结果变量。其底层由 cmd-general-purpose.cpp 的cbInstrDiv完成"命令 → 复合赋值表达式"的翻译,再由 expressionparser.cpp 完成带除零保护的求值。在命令行、脚本和断点命令中均可直接使用;计算前备份原值、警惕除零与目标不可写,是写出健壮自动化脚本的关键。

  • 逆向工程
  • 调试器
  • 开发工具
  • 应用安全

【免费下载链接】x64dbg

An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.

项目地址:https://gitcode.com/gh_mirrors/x6/x64dbg
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询