WOW64环境下NtQueryObject返回错误缓冲区大小的原因问询
问题根因
该16字节越界写入是WOW64兼容层处理ObjectTypesInformation(枚举值3)查询时的固有逻辑bug,缺陷位于用户态wow64.dll中,与Windows内核本身的实现无关。
核心偏差点
WOW64层处理该查询的两个执行路径采用了不同的长度计算口径:
- 第一次探测缓冲区长度的调用(传入
NULL对象句柄、缓冲区长度为sizeof(ULONG))走纯长度计算路径:逐一枚举全局对象类型,按32位OBJECT_TYPE_INFORMATION结构体大小、类型名字符串长度、条目对齐规则累加得到总长度,也就是你观测到的8280。这个计算逻辑没有预留列表末尾终止标记的空间。 - 第二次实际填充数据的调用(传入分配好的缓冲区、长度为8280)走64位到32位结构体转换路径:内核先返回原生64位格式的对象类型列表,WOW64层负责将其转换为32位结构体写入用户缓冲区。填充完所有67个对象类型条目后,代码沿用了64位原生逻辑的写入习惯:先在列表末尾写入8字节的NULL指针作为列表终止标记,再将写入位置对齐到8字节边界,额外消耗8字节,合计在分配的缓冲区边界外多写入16字节,最终返回的
Size2即为8296。
补充说明
- 原生x64环境下不存在32/64位结构体转换流程,内核的长度计算和数据填充逻辑完全一致,因此不会出现长度偏差。
- 你之前通过
TypeName.Length + sizeof(WCHAR) == TypeName.MaximumLength规则排除的是Windows 8版本内核层ObQueryTypeInfo的字符串填充溢出bug,本次问题完全出在用户态WOW64层,和内核的字符串填充逻辑无关,因此校验结果全部正常。 - 该bug存在于Windows 10 19044之前的WOW64实现中,后续微软通过修正第一次长度探测的计算逻辑、提前预留末尾16字节空间修复了该问题,你测试的10.0.19043版本未包含该修复。
内容的提问来源于stack exchange,提问作者0xC0000022L
相关产品推荐
相关产品推荐

