IDA Pro函数标签页“Arguments”字段含义及实例解析
关于IDA Pro函数标签页"Arguments"字段的疑问
我希望通过IDA Pro函数标签页中的"Arguments"值高效定位特定函数,但以下几段IDA反编译得到的代码实例中,所有函数的"Arguments"值均为00000010:
__int64 __fastcall sub_49FB60(__int64 a1) { sub_484690(a1 + 208, 0LL); sub_484690(a1 + 112, 0LL); return sub_484690(a1 + 16, 0LL); }
_QWORD *__fastcall sub_4A0050(_QWORD *a1, __int64 a2) { sub_4A3CB0(a1); *a1 = off_979AD8; a1[13] = a2; return a1; }
__int64 __fastcall sub_4D3D20(__int64 a1, __int64 a2, unsigned __int8 a3) { __int64 v5; // rcx *(_QWORD *)a1 = a2; v5 = *(_QWORD *)(*(int *)(*(_QWORD *)a2 + 4LL) + a2 + 72); if ( v5 ) (*(void (__fastcall **)(__int64))(*(_QWORD *)v5 + 8LL))(v5); *(_BYTE *)(a1 + 8) = sub_4D3BC0(*(_QWORD *)a1, a3); return a1; }
我原本以为该字段代表参数大小总和,但计算结果不匹配,请问"Arguments"字段实际代表什么?另外,以下代码实例的"Arguments"值又代表什么?
__int64 __fastcall sub_52AFD0(unsigned int **a1, unsigned int a2, __int64 a3) { unsigned int v3; unsigned int v4; unsigned int v6; unsigned __int64 i; v6 =-1; for ( i = a2 / 8ui64; i; --i) { v3 = **a1 ^ v6; ++*a1; v4 = **a1; v6 = *(_DWORD *)(a3 + 4i64 * (v4 >> 24)); } return v6; }
解答
一、"Arguments"字段的真实定义
这个字段指的是函数栈帧中,专门用于存放传递给该函数的参数的内存区域总大小(包含内存对齐要求),其计算逻辑完全绑定当前程序的调用约定:
- x86-64微软__fastcall调用约定:前4个整数/指针参数通过
RCX/RDX/R8/R9传递,浮点参数通过XMM0-XMM3传递。此时"Arguments"仅统计栈上传递的参数大小,再加上调用约定强制要求的影子空间(shadow space)(用于被调用者临时保存寄存器参数的预留栈空间)。 - 32位__fastcall调用约定:前2个参数通过
ECX/EDX传递,剩余参数通过栈传递,此时"Arguments"仅统计栈上参数的总大小(含对齐)。 - stdcall/cdecl调用约定:所有参数均通过栈传递,此时"Arguments"就是所有参数的总大小(含对齐);两者区别仅在于stdcall由被调用者清理栈空间,cdecl由调用者清理。
二、为什么你的计算与实际值不匹配?
你之前误以为这个字段是所有参数的总字节数,但实际存在两个关键差异:
- 通过寄存器传递的参数,其大小不会被计入"Arguments"字段(仅统计栈上传递的参数部分);
- 调用约定要求的影子空间、内存对齐规则,会额外占用栈空间,这部分会被算进该字段。
针对你给出的前三个函数,它们的"Arguments"均为0x10(16字节)的原因:
sub_49FB60:仅1个参数通过寄存器传递,栈上无参数,但调用约定要求预留16字节的影子空间,因此该字段值为0x10;sub_4A0050:2个参数均通过寄存器传递,总大小刚好16字节,与影子空间大小匹配,因此该字段值为0x10;sub_4D3D20:前2个参数通过寄存器传递,第3个参数虽为1字节,但调用约定的影子空间固定为16字节,因此该字段依然显示0x10。
三、最后一个函数sub_52AFD0的"Arguments"值含义
这个函数有3个参数:unsigned int **a1(8字节)、unsigned int a2(4字节)、__int64 a3(8字节):
- 如果程序采用x86-64微软__fastcall约定,这3个参数都会通过寄存器传递(
RCX/RDX/R8),栈上无参数,此时"Arguments"值依然是调用约定要求的影子空间大小(大概率为0x10,取决于程序具体设置); - 如果程序采用栈传参数的调用约定(比如cdecl),所有参数均通过栈传递,总大小为8+4+8=20字节,按8字节对齐后为24字节(0x18),此时"Arguments"值就是0x18。
内容的提问来源于stack exchange,提问作者jeong
相关产品推荐
相关产品推荐

