x64dbg SizeofType 命令详解:查询类型位宽并驱动脚本自动化
2026/9/19 23:07:19 网站建设 项目流程

x64dbg SizeofType 命令详解:查询类型位宽并驱动脚本自动化

【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg

SizeofType是 x64dbg 类型(Types)命令族中的查询类命令,用于获取当前类型数据库中任意类型(原始类型、别名、结构体、联合体、枚举、函数指针)的位宽(bit size),并将结果写入脚本变量$result,供后续脚本逻辑直接使用。本指南以 docs/commands/types/SizeofType.md 为核心,结合 types.cpp 与 cmd-types.cpp 的源码实现,说明命令的语法、结果语义、底层查找逻辑与典型应用场景。读完本文,你将能在脚本与命令行中准确获取任意自定义类型的尺寸,并理解"位宽以 bit 计"这一关键语义。

命令概览

SizeofType是类型操作命令族(见 docs/commands/types/index.rst)中的一员,与AddTypeAddStructAddUnionAddMemberAppendMemberAddFunctionAddArgAppendArgVisitTypeClearTypesRemoveTypeEnumTypesLoadTypesParseTypes同组注册,在 x64dbg.cpp 中通过dbgcmdnew("SizeofType", cbInstrSizeofType, false)挂载到命令系统。

语法

SizeofType arg1

参数

参数含义
arg1要查询的类型名称(type name),例如int32duint、自定义结构体名等

结果

命令执行成功后会将类型尺寸写入脚本变量$result,单位是bit(位),而非字节(byte)。若类型不存在或无法解析,命令会打印SizeofType failed并返回失败,$result不会被更新。

基本用法与示例

在 x64dbg 命令行或脚本中直接执行:

SizeofType int32

日志区输出:

sizeof(int32) = 32

随后在脚本中即可通过$result取用该值:

SizeofType duint // x64 构建下输出 sizeof(duint) = 64,$result 被置为 64

再结合类型定义命令使用,可对自定义结构体求尺寸。例如先用AddStruct/AddMember定义一个结构体:

AddStruct MY_STRUCT AddMember MY_STRUCT int32 field_a AddMember MY_STRUCT uint8 field_b SizeofType MY_STRUCT

由于结构体尺寸是成员尺寸的累加(见下文实现解析),$result将得到40(即32 + 8bit)。这类查询非常适合在自动化脚本中动态计算缓冲区大小、结构体长度或做内存布局校验。

源码实现深度解析

1. 命令处理函数

SizeofType的命令处理函数位于 cmd-types.cpp:

bool cbInstrSizeofType(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) return false; auto size = SizeofType(argv[1]); if(!size) { dputs(QT_TRANSLATE_NOOP("DBG", "SizeofType failed")); return false; } dprintf_untranslated("sizeof(%s) = %d\n", argv[1], size); varset("$result", size, false); return true; }

关键逻辑有三点:

  • 参数不足(少于 2 个参数,即缺类型名)直接失败;
  • 调用全局 APISizeofType,返回值为 0 视为"类型不存在/解析失败",打印SizeofType failed
  • 成功时以sizeof(<类型>) = <数值>格式输出,并通过varset("$result", size, false)写入$result脚本变量。

2. 全局 API 与线程安全

全局函数SizeofType定义于 types.cpp,它通过SHARED_ACQUIRE(LockTypeManager)以共享锁方式读取类型管理器,避免与并发的类型增删操作冲突:

int SizeofType(const std::string & type) { SHARED_ACQUIRE(LockTypeManager); return typeManager.Sizeof(type); }

该函数在 types.h 中声明,可被插件等其他模块直接调用。内部核心实现是TypeManager::Sizeof(见 types.cpp)。

3. 核心查找逻辑TypeManager::Sizeof

TypeManager::Sizeof按以下顺序解析类型并返回位宽:

类型形态返回值说明
指针类型(类型名以*结尾)primitiveSizes[Pointer] * 8返回指针本身大小,即sizeof(void*)对应的位数(x64 下为 64,x86 下为 32),与指向的目标类型无关
Typedef / 别名递归调用Sizeof(alias)别名指向的类型继续解析,直到基础类型
枚举(Enum)enum.sizeBits枚举自身的位宽
结构体 / 联合体(Struct/Union)struct.sizeBits累加(结构体)或取最大值(联合体)后的位宽
函数(Function)primitiveSizes[Pointer] * 8函数类型按函数指针大小处理
其他 / 未找到0触发命令失败分支

需要特别注意的是:所有sizeBits均以 bit 为单位存储。原始类型在初始化时即做了换算(t.sizeBits = primitiveSizes[primitive] * 8,见 types.cpp),因此SizeofType int32返回 32 而非 4。

4. 原始类型尺寸表

类型管理器的构造函数(types.cpp)注册了全部内建原始类型及其别名,这是SizeofType能够直接查询的基础:

类型别名尺寸(bit)
int8_t, int8, char, byte, bool, signed char8
uint8_t, uint8, uchar, unsigned char, ubyte8
int16_t, int16, wchar_t, char16_t, short16
uint16_t, uint16, ushort, unsigned short16
int32_t, int32, int, long32
uint32_t, uint32, unsigned int, unsigned long32
int64_t, int64, long long64
uint64_t, uint64, unsigned long long64
dsintsizeof(void*) * 8
duint, size_tsizeof(void*) * 8
float32
double, long double64
ptr, void*sizeof(void*) * 8
char*, const char*sizeof(char*) * 8
wchar_t*, const wchar_t*sizeof(wchar_t*) * 8

可见dsint/duint/size_t等与指针宽度相关的类型,其尺寸会随构建架构(x64/x86)自动变化,SizeofType因此也可以用来在脚本中探测当前调试器是 64 位还是 32 位。

5. 结构体尺寸的累积规则

SizeofType对结构体返回的位宽,来自结构体定义过程中实时维护的sizeBits字段:

  • 结构体(struct):每添加一个成员,s.sizeBits += m.sizeBits累加(types.cpp);
  • 联合体(union):取所有成员的最大值if(typeSize > s.sizeBits) s.sizeBits = typeSize;(types.cpp);
  • 数组成员typeSize = Sizeof(type) * arraySize按元素个数放大(types.cpp);
  • 位域成员:尺寸取位域声明的sizeBits(但不能超过成员类型位宽,见 types.cpp);
  • 显式偏移:当成员指定了超出当前布局的bitOffset时,会通过AppendStructPadding自动插入填充位(types.cpp),这些填充同样计入最终位宽。

因此,SizeofType反映的是类型数据库中的逻辑布局尺寸,与 C 编译器在目标架构上的实际对齐规则可能不完全一致,使用时需结合具体场景判断。

与类型命令族的协作

SizeofType的典型工作流是"先定义、再查询":

  1. 手工定义:用AddType/AddStruct/AddUnion/AddMember/AddFunction/AddArg逐个构建类型(对应文档见 AddType、AddStruct、AddMember、AddFunction 等);
  2. 批量导入:用ParseTypes解析 C 风格声明、或LoadTypes从文件/JSON 加载类型(见 ParseTypes、LoadTypes);
  3. 查询校验:用SizeofType获取位宽,配合EnumTypes(EnumTypes)枚举全部类型、VisitType/dt(VisitType)展示成员布局,形成完整的类型管理与检视闭环;
  4. 脚本消费:把$result用于条件分支、循环或内存操作,例如在脚本中先SizeofType再据此分配缓冲区或计算遍历步长。

边界情况与注意事项

  • 类型不存在时返回 0:任何有效类型的位宽至少为 8 bit,因此 0 被安全用作"未找到"的哨兵值;命令会打印SizeofType failed且不修改$result
  • 指针类型返回指针宽度:对以*结尾的类型名(如MY_STRUCT*),返回的是指针大小而非所指结构体的大小(types.cpp)。若要查询结构体本身的尺寸,请去掉末尾的*
  • 单位是 bit:所有返回值均为位宽。若脚本需要字节数,应自行除以 8。
  • 不依赖调试会话SizeofType只读取调试器内部的类型数据库,无需附加或启动被调试进程即可执行,可在任意时刻用于脚本初始化。

总结

SizeofType虽然语法简单,却是 x64dbg 类型系统中连接"类型定义"与"脚本逻辑"的关键查询入口。理解其$result返回值语义(bit 单位)、别名递归解析、指针/枚举/结构体/函数的差异化处理,以及"0 表示未找到"的失败约定,能帮助你在逆向分析与自动化脚本中更精确地利用自定义类型体系。相关实现与测试可进一步查阅 types.cpp、types.h 与 cmd-types.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),仅供参考

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

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

立即咨询