x64dbg DataFloat/DataReal4/df 命令详解:将地址标记为 Float 类型数据
【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg
导读
DataFloat(别名DataReal4、df)是 x64dbg 内置命令集(dbgcmd)中的一条“数据类型标记”命令,用于把指定内存地址处的字节标记为4 字节单精度浮点数(Float / real4),从而让反汇编视图与内存转储视图以浮点数语义呈现和解释该地址的数据。本文以官方命令文档为主线,结合 cmd-types.cpp 的命令注册与实现、encodemap.cpp 的类型编码映射以及 GUI 端 CPUDump.cpp 的显示逻辑,完整讲解参数、用法、底层原理与相关命令,帮助读者在逆向分析与恶意软件分析中高效标注与解读浮点数据。
命令总览
| 命令名 | 别名 | 功能 |
|---|---|---|
DataFloat | DataReal4、df | 将地址处的数据标记为 Float(real4,4 字节单精度浮点数) |
该命令通过 x64dbg.cpp 中的dbgcmdnew("DataFloat,DataReal4,df", cbInstrDataFloat, true)注册,注册时同时绑定了三个名称:正式名DataFloat、别名DataReal4与短命令df,因此三条命令完全等价,可任意混用。
参数说明
命令语法如下:
DataFloat [arg1] [arg2] DataReal4 [arg1] [arg2] df [arg1] [arg2]| 参数 | 含义 | 默认值 | 说明 |
|---|---|---|---|
arg1 | 要标记的内存地址 | 无(必填) | 支持表达式,如401000、rsp+8、dis.sel()等 |
[arg2] | 要标记的字节大小 | 1 | 未指定时默认只标记 1 字节 |
参数解析逻辑位于 cmd-types.cpp 的cbInstrDataGeneric:
- 通过
valfromstring(argv[1], &addr, false)将第一个参数解析为地址,因此arg1可以填写任意合法的 x64dbg 表达式(寄存器、符号、算术表达式等); - 当提供第二个参数时,通过
valfromstring(argv[2], &size, false)解析大小;若未提供,size被初始化为1; - 随后调用
EncodeMapSetType(addr, size, type, &created)将类型写入编码映射表(EncodeMap)。
结果与返回值
该命令不设置任何结果变量(如$result)。可以通过命令行的返回值判断执行是否成功:
- 成功:返回
true; - 失败:返回
false,例如参数数量不足、地址表达式解析失败或EncodeMapSetType内部出错(此时日志会输出EncodeMapSetType failed...)。
作为对比,DataFloat与同族的DataByte、DataWord、DataDword等命令共享同一套cbInstrDataGeneric实现框架(见 cmd-types.cpp),这些命令均不产生结果变量。
命令执行后的界面行为
命令成功标记后,视图会立即刷新:
- 若该地址此前没有任何编码记录(
created == true),命令内部会执行disasm dis.sel()以重算当前选中行的反汇编结果; - 若此前已有编码记录,则调用
GuiUpdateDisassemblyView()刷新反汇编视图。
(上述行为见 cmd-types.cpp。)这意味着标记完成后,用户在反汇编窗口与内存转储窗口可以立刻看到数据以浮点形式呈现,无需手动刷新。
底层原理:EncodeMap 编码映射
数据类型编码
DataFloat实际写入的编码类型是enc_real4,在 bridgemain.h 中定义并注明为//4 byte float。该类型对应的固有字节大小由 encodemap.cpp 的GetEncodeTypeSize返回4 字节:
case enc_real4: return 4;写入逻辑
EncodeMapSetType(见 encodemap.cpp)负责把类型写入按内存段组织的ENCODEMAP缓冲区:
- 对于大小大于 1 的标记,中间字节会被填为
enc_middle,起始字节写入enc_real4; - 末尾会清理残留的
enc_middle,将其恢复为enc_unknown,保证后续读取不越界; - 该映射会随数据库一起缓存保存与加载(
EncodeMapCacheSave/EncodeMapCacheLoad),因此标记信息可以持久化到数据库,重启调试会话后依然保留。
读取与显示
GUI 端在 CPUDump.cpp 中,遇到enc_real4时通过ToFloatString将地址处的 4 字节按单精度浮点数格式化,并在提示文本中标注(Real4)。同时,QZydis.cpp 将enc_real4映射为指令操作数描述"float",使得反汇编窗口中的相关操作数也会以浮点语义着色与格式化。
实战用法示例
1. 标记单个浮点数
将0x401000处的数据标记为 Float(1 字节,等效于标记起始 4 字节):
df 4010002. 标记一段浮点数组
将0x401000起始的 64 字节(16 个 float)全部标记为浮点数据:
DataFloat 401000, 40注意:x64dbg 命令参数以空格分隔,
arg2直接跟在arg1后即可。若地址中包含空格或需要表达式求值,可使用括号或直接使用表达式形式。
3. 使用表达式定位地址
结合寄存器与表达式标记栈上的浮点数据:
df rsp+8 DataReal4 dis.sel()其中dis.sel()返回反汇编窗口当前选中行的地址(见 表达式与输入 文档)。
验证与观察
- 标记完成后,切换到内存转储(Dump)视图,将显示格式切换为浮点(Float),可以看到该区域以单精度浮点数呈现;
- 在反汇编视图中,若操作数落在已标记区域,
enc_real4会驱动浮点语义的高亮与格式化(由 QZydis.cpp 的指令映射支撑); - 将鼠标悬停在转储视图对应地址上,提示框会显示类似
[地址] = 3.14159 (Real4)的内容(见 CPUDump.cpp); - 通过 EnumTypes.md 可以列出当前已加载的类型,通过 ClearTypes.md 可清除类型映射。
与相邻命令及自动分析的关系
同族命令
DataFloat属于 x64dbg 的 Data 系列数据类型标记命令,同族的还包括(全部实现在 cmd-types.cpp):
| 命令 | 编码类型 | 字节大小 |
|---|---|---|
DataByte | enc_byte | 1 |
DataWord | enc_word | 2 |
DataDword | enc_dword | 4 |
DataFword | enc_fword | 6 |
DataQword | enc_qword | 8 |
DataTbyte | enc_tbyte | 10 |
DataOword | enc_oword | 16 |
DataMmword | enc_mmword | 8 |
DataXmmword | enc_xmmword | 16 |
DataYmmword | enc_ymmword | 32 |
DataFloat | enc_real4 | 4 |
DataDouble | enc_real8 | 8 |
DataLongdouble | enc_real10 | 10 |
DataAscii/DataUnicode | enc_ascii/enc_unicode | 1 / 2 |
DataCode/DataJunk | enc_code/enc_junk | — |
(各编码的字节大小见 encodemap.cpp 的GetEncodeTypeSize。其中DataDouble对应 8 字节双精度浮点,DataLongdouble对应 10 字节扩展精度浮点,可按需选择。)
自动分析中的浮点识别
除了手动标记,x64dbg 的高级分析(advanced analysis)在扫描指令时也会自动识别浮点指令上下文,将数据区域自动归类为enc_real4或enc_dword(见 advancedanalysis.cpp)。这意味着:手动使用DataFloat标记是自动分析的补充手段——当自动分析未能识别(或用户希望强制覆盖)某块数据为浮点时,df提供了精确、可控的手动标注路径。
常见注意事项
arg2的语义是字节数:df 401000 4标记的是 4 个字节(一个完整 float);标记区间的实际生效大小会被钳制到所在内存段剩余范围内(EncodeMapSetType内部对size做了std::min(map.size - offset, size)处理);- 不产生结果变量:脚本中若依赖
$result判断结果,需要改用命令返回值(cmd系列函数或脚本的返回值检查)来判断成功与否; - 地址必须可解析:地址表达式非法会导致命令失败并返回
false,不会写入任何编码; - 持久化依赖数据库:标记信息保存在 EncodeMap 缓存中,随数据库保存/加载;若数据库被清除,标记也会一并消失。
参考与延伸
- 官方命令文档:DataFloat
- 同族文档:DataDouble、DataLongdouble、DataDword
- 类型系统文档:EnumTypes、ClearTypes、ParseTypes
- 表达式语法:Expressions
- 核心实现:cmd-types.cpp、encodemap.cpp、CPUDump.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),仅供参考