You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM64 Windows下RtlLookupFunctionEntry函数大小计算过度问题咨询

ARM64 Windows下RtlLookupFunctionEntry获取函数大小异常的原因

关键差异:ARM64与x64的RUNTIME_FUNCTION语义不同

你遇到的问题核心是对ARM64 Windows unwind表的误解:

  • x64平台的PRUNTIME_FUNCTION中,FunctionLength直接对应单个函数的字节长度;
  • 但ARM64的IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY里的FunctionLength字段,代表的是unwind区域(Unwind Region)的长度,而非单个函数的长度。这个区域可包含多个逻辑独立的函数,共享同一条unwind信息。

ntdll.dll中函数的特殊表现

以你测试的NtClose为例,它实际只有8字节指令(svc 0x0F + ret),但这类系统调用存根在ntdll中是连续批量排列的,共用同一个unwind条目。RtlLookupFunctionEntry返回的FunctionLength对应的是整个连续区块的长度,因此数值会远大于单个函数的实际大小——这是ARM64 Windows标准模块的常规打包方式,属于设计特性而非bug。

自建项目结果不稳定的原因

你的项目重建后结果时好时坏,源于编译器的优化策略:

  • 当编译器将多个短函数合并到同一个unwind区域时,返回的FunctionLength会覆盖整个区块,导致大小超量;
  • 当函数被单独分配unwind信息时,FunctionLength会匹配单个函数的实际长度。

正确获取函数边界的方法

既然ARM64的unwind表字段无法直接提供单个函数大小,可采用以下替代方案:

  1. 导出表差值法:对于导出函数,获取当前函数在导出表中的下一个函数地址,两者的差值即为当前函数的近似长度(适用于ntdll这类标准模块);
  2. 符号表查询:使用dbghelp库的SymInitialize和SymGetSymFromAddr64接口,从符号表中获取准确的函数长度;
  3. 编译期标记:针对自建项目,可手动添加函数起始/结束标记(如定义空函数作为结束锚点),或启用编译器特定选项生成函数边界信息。

你的测试代码中,直接用FunctionLength *4计算大小的逻辑,在ARM64下仅当函数独占一个unwind区域时才有效,无法通用。

内容的提问来源于stack exchange,提问作者user30408201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:19:57