- 逆向工程
- 调试器
- 开发工具
- 应用安全
【免费下载链接】x64dbg
An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.
div是 x64dbg 调试器"通用算术"命令族中的除法命令,用于将两个值相除并把商写回第一个操作数。本文以命令参考文档 div.md 为骨架,结合命令实现源码 cmd-general-purpose.cpp 与表达式引擎 expressionparser.cpp,完整讲解div的语法、执行语义、除零边界行为与底层原理,并给出命令行、脚本及断点场景中的实战示例,帮助你在逆向分析与脚本自动化中准确使用除法运算。
命令定位:通用算术命令族中的除法
在 x64dbg 的命令体系中,div属于"通用目的(General Purpose)"命令组。该组集中了调试脚本中最常用的标量运算命令,包括inc、dec、add、sub、mul、mulhi、div、and、or、xor、neg、not、bswap、rol、ror、shl、shr、sar等,完整清单参见 general-purpose/index.rst 中的 toctree。这些命令的共同特点是:它们并非 CPU 指令的封装,而是操作 x64dbg 表达式引擎的值(value),运算对象可以是寄存器、用户变量、内存位置或任意可解析的表达式。
div在其中承担除法角色:把目标值除以源值,再把结果写回目标。它不涉及浮点,执行的是表达式引擎中的整数除法,适用于地址计算、循环计数、步长换算等典型逆向工程场景。
语法与参数
原文档 div.md 定义了如下接口:
| 项目 | 说明 |
|---|---|
| 命令名 | div |
| 描述 | Divide two values.(将两个值相除) |
arg1 | Destination. 目标,即被除数;除法结果写回此位置 |
arg2 | Source. 源,即除数 |
| 结果 | 不设置任何结果变量(This command does not set any result variables.) |
调用形式为:
div arg1, arg2参数之间以逗号分隔(x64dbg 命令解析器同样接受空格分隔,逗号是更稳妥的写法)。arg1与arg2都可以是表达式引擎支持的任何值形式,例如:
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。这与同族的add、sub、mul等二元运算命令的参数校验逻辑完全一致。
执行语义:本质是表达式赋值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 += arg2、sub翻译为arg1 -= arg2、mul翻译为arg1 *= arg2的模式一脉相承(参见 cmd-general-purpose.cpp)。cmddirectexec是 x64dbg 内部同步执行一条命令字符串的入口,声明于 command.h,实现在 command.cpp。
这一设计带来两个重要推论:
- 结果是写回的,而非返回值。
div将商直接写回arg1,因此文档明确说明"不设置任何结果变量"——与add、sub等一致,不存在类似表达式函数的返回值可供后续命令读取;若需要在计算后保留原值,请先把arg1复制到临时变量再执行div。 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不会引发未定义行为,而是以一条可感知的错误终止本次运算。
整数除法语义
op1与op2的类型是duint(x64dbg 的通用无符号整数类型,x86 下为 32 位、x64 下为 64 位),因此result = op1 / op2是无符号整数除法,结果向零截断、不产生小数。例如div eax, 3在eax = 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, arg2→arg1 += arg2,见 add.md;sub arg1, arg2→arg1 -= arg2,见 sub.md;mul arg1, arg2→arg1 *= arg2,见 mul.md;mulhi arg1, arg2→ 乘法的高位部分写回,用于 64 位乘法的高半部分,见 mulhi.md;inc arg1/dec arg1→arg1++/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.
相关推荐
SerenityOS expr 命令详解:表达式求值器的语法、运算符与源码实现
SerenityOS expr 命令详解:表达式求值器的语法、运算符与源码实现 导读 expr 是 SerenityOS 提供的一个标准命令行表达式求值工具,它
操作系统内核驱动x64dbg 的 xor 命令详解:按位异或运算、`^=` 快速赋值与表达式运算原理
x64dbg 的 xor 命令详解:按位异或运算、 ^= 快速赋值与表达式运算原理 xor 是 x64dbg 调试器“通用运算(General Purpose)
逆向工程调试器开发工具应用安全x64dbg `or` 命令完全指南:按位或运算的参数语义与表达式引擎实现解析
x64dbg or 命令完全指南:按位或运算的参数语义与表达式引擎实现解析 or 是 x64dbg 调试器在命令行、脚本与表达式上下文中执行 按位或(Binar
逆向工程调试器开发工具应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考