x64dbg DataTbyte 命令详解:将内存标记为 Tbyte(10 字节)数据类型

x64dbg DataTbyte 命令详解:将内存标记为 Tbyte(10 字节)数据类型 x64dbg DataTbyte 命令详解将内存标记为 Tbyte10 字节数据类型【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg导读DataTbyte是 x64dbg 内置的数据库/类型标记命令之一用于将指定地址处的内存标记为Tbyte10 字节即 x87 扩展精度浮点数数据类型从而让反汇编视图与数据视图以 10 字节为粒度正确解读该区域。本文以官方命令文档 DataTbyte.md 为骨架结合 x64dbg 命令注册、类型映射EncodeMap与 GUI 刷新等底层源码完整讲解其语法、参数、实现原理、适用场景与边界注意事项帮助逆向工程师在分析 x87 FPU 浮点数据或手工标注自定义数据结构时准确使用该命令。命令概览它做了什么DataTbyte属于 x64dbg 的「Types数据类型」命令族其作用一句话概括为Mark data at address as Tbyte. —— 将指定地址处的数据标记为 Tbyte。TbyteTemporary real / 扩展精度实数是 x87 FPU 中long double类型的底层表示固定占用10 个字节。在 x64dbg 的枚举定义中这一点有明确注释见 bridgemain.henc_tbyte, //10 bytes命令注册位于 x64dbg.cppdbgcmdnew(DataTbyte, cbInstrDataTbyte, true); //mark as Tbyte第三个参数true表示该命令为调试器内部命令debug-only即它主要面向调试会话中的内存标注场景。该命令与DataByte、DataWord、DataDword、DataFword、DataQword、DataOword、DataMmword、DataXmmword、DataYmmword、DataFloat、DataDouble、DataLongdouble等命令共同构成完整的数据类型标记体系文档索引见 docs/commands/types/index.rst。语法与参数详解官方文档给出的语法如下参数含义是否必填arg1要标记的地址必填[arg2]标记的大小以字节为单位未指定时默认为 1可选arg1目标地址arg1是希望标记的内存起始地址。与 x64dbg 其他命令一致该地址支持使用valfromstring解析的各类表达式——既可以是直接的十六进制地址如401000也可以是寄存器、符号名、表达式函数或模块内偏移如dis.sel()、cip等。底层对地址的解析由cbInstrDataGeneric中的valfromstring(argv[1], addr, false)完成见 cmd-types.cpp解析失败时命令直接返回失败不会产生任何标记副作用。arg2标记大小字节arg2指定要标记的连续字节数默认值为 1。这是一个需要特别留意的地方虽然 Tbyte 类型本身的语义宽度是 10 字节但命令默认只标记 1 字节若希望完整标记一个 10 字节的扩展精度浮点数需要显式传入大小例如DataTbyte 401000, 10。具体来说不传arg2时cbInstrDataGeneric内部将size初始化为1传入arg2时同样经过valfromstring解析为数值解析失败则命令失败。结果变量文档明确指出This command does not set any result variables. —— 本命令不设置任何结果变量。因此DataTbyte执行后不会向$result等脚本变量写入任何值它是一次纯副作用操作主要用于交互式命令行、脚本中的类型标注流程脚本可通过其他查询命令如EnumTypes、VisitType后续验证标注结果。实战示例以下示例均在 x64dbg 命令行或脚本中执行1. 将当前选中地址标记为 1 字节 Tbyte使用默认大小DataTbyte dis.sel()2. 将0x401000处 10 个字节标记为 Tbyte完整覆盖一个扩展精度浮点数DataTbyte 401000, 103. 在脚本中结合寄存器动态标注例如分析 x87 FPU 栈顶数据所在地址DataTbyte st0, 10命令执行成功后反汇编视图与数据视图会立即以 Tbyte 语义刷新显示若该区域此前未被标注created true调试器会执行disasm dis.sel()重新反汇编当前选中行否则调用GuiUpdateDisassemblyView()刷新视图详见下文实现原理。已标注的区域会被记录进 x64dbg 的数据库database随会话保存与恢复这也是DataTbyte与纯临时标记如高亮的本质区别。底层实现原理从命令到类型映射1. 命令分发DataTbyte的命令处理函数是cbInstrDataTbyte其实现极为精简见 cmd-types.cppbool cbInstrDataTbyte(int argc, char* argv[]) { return cbInstrDataGeneric(enc_tbyte, argc, argv); }它将 Tbyte 对应的编码类型枚举enc_tbyte委托给通用的cbInstrDataGeneric处理。2. 通用标记流程cbInstrDataGeneric核心逻辑位于 cmd-types.cpp完整流程如下static bool cbInstrDataGeneric(ENCODETYPE type, int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) return false; duint addr; if(!valfromstring(argv[1], addr, false)) return false; duint size 1; if(argc 3) if(!valfromstring(argv[2], size, false)) return false; bool created; if(!EncodeMapSetType(addr, size, type, created)) { dputs(QT_TRANSLATE_NOOP(DBG, EncodeMapSetType failed...)); return false; } if(created) DbgCmdExec(disasm dis.sel()); else GuiUpdateDisassemblyView(); return true; }关键步骤参数数量校验IsArgumentsLessThan(argc, 2)保证至少提供地址参数否则返回false地址解析valfromstring将表达式转为duint默认大小size初始化为1仅当存在第三个参数时才覆盖写类型映射调用EncodeMapSetType(addr, size, type, created)失败时向控制台输出EncodeMapSetType failed...并返回false视图刷新created为真表示首次为该区域创建映射此时执行disasm dis.sel()重新反汇编否则仅刷新反汇编视图。3. 类型映射写入EncodeMapSetType真正落地标记的是 encodemap.cpp 中的EncodeMapSetType。它对整段区域先做边界裁剪size std::min(map.size - offset, size)随后根据类型的宽度datasize分两条路径写入单字节类型datasize 1且非代码类型直接用memset将整段填为同一类型多字节类型先用enc_middle填充整段表示中间字节/未定类型再按datasize步进在每段的起始字节写入类型标记。Tbyte 属于后者GetEncodeTypeSize(enc_tbyte)返回10见 encodemap.cpp因此当执行DataTbyte 401000, 10时系统在起始地址写入enc_tbyte其余 9 字节标记为enc_middle共同构成一个 10 字节的数据单元。这解释了为什么若只标记 1 字节默认值该区域将无法被识别为完整的数据单元视图会以 10 字节步进解读并产生不完整的显示。4. 读取与 GUI 显示标记完成后反汇编与数据视图通过EncodeMapGetTypeencodemap.cpp按地址查询类型GUI 侧在 CPUDisassembly.cpp 的类型表中将enc_tbyte映射为 tbyte 标签StringUtil.cpp 与 EncodeMap.h 负责其字符串表示与颜色主题渲染QZydis.cpp 则在数据指令映射表中登记{tbyte, tbyte, tbyte}供反汇编显示。典型应用场景x87 FPU 数据分析DataTbyte最常见的实战场景是x87 FPUfld/fstp等指令操作的扩展精度浮点数据标注。值得注意的是x64dbg 的自动分析器在识别 x87 浮点常量时也会主动推断enc_tbyte见 advancedanalysis.cpptype isfloat ? enc_real10 : enc_tbyte;说明 Tbyte 与 x87 浮点数据在语义上高度绑定。当你在 x87 代码路径中遇到类似以下指令时fld tbyte ptr [eax8] fstp tbyte ptr [ebp-0x10]tbyte ptr即指向一个 10 字节的扩展精度浮点数。此时使用DataTbyte手动标注源地址可以让反汇编与数据窗口以正确的 10 字节边界显示该浮点值避免被误判为整数数组或混入相邻数据DataTbyte eax8, 10此外当自动分析未覆盖的自定义数据结构包含 10 字节扩展浮点字段时DataTbyte也能作为手工标注手段补充数据库信息且该标注随数据库持久化保存。注意事项与边界默认大小陷阱arg2默认为 1 字节而不是 Tbyte 的语义宽度 10 字节。想要完整标注一个扩展精度浮点数务必显式传入, 10或更大的连续区域大小。不设置结果变量DataTbyte无$result输出脚本中如需确认执行成败应结合DataTbyte返回值命令执行成功返回真或后续类型查询命令。与DataLongdouble的区别DataLongdouble将区域标记为 10 字节长双精度浮点enc_real10而DataTbyte标记为通用的 10 字节 Tbyteenc_tbyte。二者字节宽度相同但语义标注不同GUI 显示的数值解读方式也有差异。从 advancedanalysis.cpp 可见自动分析在区分“是否为浮点”时会在enc_real10与enc_tbyte之间二选一逆向时请按实际数据语义选择。仅标记起始点命令从arg1起始连续标记arg2个字节跨页/跨模块区域请确保地址与大小在可写映射范围内否则EncodeMapSetType会因无法创建映射而失败并在控制台报错。持久化类型标记写入 EncodeMap 并随数据库.dd32/.dd64数据库文件保存下次打开会话时自动恢复。总结DataTbyte虽是一个参数极简的命令但其背后串联了 x64dbg 的完整类型标注链路命令行解析valfromstring→ 类型映射写入EncodeMapSetTypeencodemap.cpp→ 视图刷新disasm dis.sel()/GuiUpdateDisassemblyView。掌握它的核心是理解两点地址参数支持任意表达式、大小参数默认为 1 字节而 Tbyte 语义宽度为 10 字节。在分析 x87 浮点代码或手工标注 10 字节数据单元时一条DataTbyte addr, 10即可让调试视图以正确边界呈现数据显著提升逆向分析效率。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考