常见函数调用约定(x86、x64、arm、arm64)
2018-02-08 22:52
363 查看
我学习逆向,整理的一些常见的函数调用约定反汇编笔记。由于我是新手,肯定有一些疏漏不完善的,我遇到了会实时更新的。
参数1~参数4 分别保存到 R0~R3 寄存器中 ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 R0 中。
ARM64
参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 X0 中。
X86 函数调用约定
X86 有三种常用调用约定,cdecl(C规范)/stdcall(WinAPI默认)/fastcall 函数调用约定。cdecl 函数调用约定
参数从右往左一次入栈,调用者实现栈平衡,返回值存放在 EAX 中。20: int cdecl_sum = cdecl_add(1, 2, 3, 4, 5, 6, 7); 00401138 push 7 0040113A push 6 0040113C push 5 0040113E push 4 00401140 push 3 00401142 push 2 00401144 push 1 00401146 call @ILT+5(_cdecl_add) (0040100a) 0040114B add esp,1Ch # 栈平衡 0040114E mov dword ptr [ebp-4],eax # 返回值 3: int __cdecl cdecl_add(int a, int b, int c, int d, int e, int f, int g) 4: { 00401030 push ebp 00401031 mov ebp,esp 00401033 sub esp,44h 00401036 push ebx 00401037 push esi 00401038 push edi 00401039 lea edi,[ebp-44h] 0040103C mov ecx,11h 00401041 mov eax,0CCCCCCCCh 00401046 rep stos dword ptr [edi] 5: int sum = a+b+c+d+e+f+g; 00401048 mov eax,dword ptr [ebp+8] 0040104B add eax,dword ptr [ebp+0Ch] 0040104E add eax,dword ptr [ebp+10h] 00401051 add eax,dword ptr [ebp+14h] 00401054 add eax,dword ptr [ebp+18h] 00401057 add eax,dword ptr [ebp+1Ch] 0040105A add eax,dword ptr [ebp+20h] 0040105D mov dword ptr [ebp-4],eax 6: return sum; 00401060 mov eax,dword ptr [ebp-4] # 存放返回值 7: } 00401063 pop edi 00401064 pop esi 00401065 pop ebx 00401066 mov esp,ebp 00401068 pop ebp 00401069 ret
stdcall 函数调用约定
参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 EAX 中。21: int stdcall_sum = stdcall_add(1, 2, 3, 4, 5, 6, 7); 00401151 push 7 00401153 push 6 00401155 push 5 00401157 push 4 00401159 push 3 0040115B push 2 0040115D push 1 0040115F call @ILT+15(_stdcall_add@28) (00401014) 00401164 mov dword ptr [ebp-8],eax # 返回值 9: int __stdcall stdcall_add(int a, int b, int c, int d, int e, int f, int g) 10: { 00401080 push ebp 00401081 mov ebp,esp 00401083 sub esp,44h 00401086 push ebx 00401087 push esi 00401088 push edi 00401089 lea edi,[ebp-44h] 0040108C mov ecx,11h 00401091 mov eax,0CCCCCCCCh 00401096 rep stos dword ptr [edi] 11: int sum = a+b+c+d+e+f+g; 00401098 mov eax,dword ptr [ebp+8] 0040109B add eax,dword ptr [ebp+0Ch] 0040109E add eax,dword ptr [ebp+10h] 004010A1 add eax,dword ptr [ebp+14h] 004010A4 add eax,dword ptr [ebp+18h] 004010A7 add eax,dword ptr [ebp+1Ch] 004010AA add eax,dword ptr [ebp+20h] 004010AD mov dword ptr [ebp-4],eax 12: return sum; 0 11626 04010B0 mov eax,dword ptr [ebp-4] # 存放返回值 13: } 004010B3 pop edi 004010B4 pop esi 004010B5 pop ebx 004010B6 mov esp,ebp 004010B8 pop ebp 004010B9 ret 1Ch # 栈平衡(等价于先 add esp, 1Ch 再 ret)
fastcall 函数调用约定
参数1、参数2分别保存在 ECX、EDX ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 EAX 中。25: int fastcall_sum = fastcall_add(1, 2, 3, 4, 5, 6, 7); 00401167 push 7 00401169 push 6 0040116B push 5 0040116D push 4 0040116F push 3 00401171 mov edx,2 00401176 mov ecx,1 0040117B call @ILT+0(@fastcall_add@28) (00401005) 00401180 mov dword ptr [ebp-0Ch],eax # 返回值 15: int __fastcall fastcall_add(int a, int b, int c, int d, int e, int f, int g) 16: { 004010D0 push ebp 004010D1 mov ebp,esp 004010D3 sub esp,4Ch 004010D6 push ebx 004010D7 push esi 004010D8 push edi 004010D9 push ecx 004010DA lea edi,[ebp-4Ch] 004010DD mov ecx,13h 004010E2 mov eax,0CCCCCCCCh 004010E7 rep stos dword ptr [edi] 004010E9 pop ecx 004010EA mov dword ptr [ebp-8],edx 004010ED mov dword ptr [ebp-4],ecx 17: int sum = a+b+c+d+e+f+g; 004010F0 mov eax,dword ptr [ebp-4] 004010F3 add eax,dword ptr [ebp-8] 004010F6 add eax,dword ptr [ebp+8] 004010F9 add eax,dword ptr [ebp+0Ch] 004010FC add eax,dword ptr [ebp+10h] 004010FF add eax,dword ptr [ebp+14h] 00401102 add eax,dword ptr [ebp+18h] 00401105 mov dword ptr [ebp-0Ch],eax 18: return sum; 00401108 mov eax,dword ptr [ebp-0Ch] # 存放返回值 19: } 0040110B pop edi 0040110C pop esi 0040110D pop ebx 0040110E mov esp,ebp 00401110 pop ebp 00401111 ret 14h # 栈平衡(等价于先 add esp, 14h 再 ret)
X64 函数调用约定
X64只有一种 fastcall 函数调用约定fastcall 函数调用约定
参数1、参数2、参数3、参数4分别保存在 RCX、RDX、R8D、R9D ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 RAX 中。# 该代码是 msvc 2017 x64 生成的汇编代码 int fastcall_sum = fastcall_add(1, 2, 3, 4, 5, 6, 7); 00007FF6577A366E mov dword ptr [rsp+30h],7 00007FF6577A3676 mov dword ptr [rsp+28h],6 00007FF6577A367E mov dword ptr [rsp+20h],5 00007FF6577A3686 mov r9d,4 00007FF6577A368C mov r8d,3 00007FF6577A3692 mov edx,2 00007FF6577A3697 mov ecx,1 00007FF6577A369C call fastcall_add (07FF6577A11C2h) 00007FF6577A36A1 mov dword ptr [fastcall_sum],eax # 返回值 int __fastcall fastcall_add(int a, int b, int c, int d, int e, int f, int g) { 00007FF6D22D1790 mov dword ptr [rsp+20h],r9d 00007FF6D22D1795 mov dword ptr [rsp+18h],r8d 00007FF6D22D179A mov dword ptr [rsp+10h],edx 00007FF6D22D179E mov dword ptr [rsp+8],ecx 00007FF6D22D17A2 push rbp 00007FF6D22D17A3 push rdi 00007FF6D22D17A4 sub rsp,0E8h 00007FF6D22D17AB mov rbp,rsp 00007FF6D22D17AE mov rdi,rsp 00007FF6D22D17B1 mov ecx,3Ah 00007FF6D22D17B6 mov eax,0CCCCCCCCh 00007FF6D22D17BB rep stos dword ptr [rdi] 00007FF6D22D17BD mov ecx,dword ptr [rsp+108h] int sum = a + b + c + d + e + f + g; 00007FF6D22D17C4 mov eax,dword ptr 00007FF6D22D17CA mov ecx,dword ptr [a] 00007FF6D22D17D0 add ecx,eax 00007FF6D22D17D2 mov eax,ecx 00007FF6D22D17D4 add eax,dword ptr [c] 00007FF6D22D17DA add eax,dword ptr [d] 00007FF6D22D17E0 add eax,dword ptr [e] 00007FF6D22D17E6 add eax,dword ptr [f] 00007FF6D22D17EC add eax,dword ptr [g] 00007FF6D22D17F2 mov dword ptr [sum],eax return sum; 00007FF6D22D17F5 mov eax,dword ptr [sum] # 存放返回值 } 00007FF6D22D17F8 lea rsp,[rbp+0E8h] 00007FF6D22D17FF pop rdi 00007FF6D22D1800 pop rbp 00007FF6D22D1801 ret # 没做栈平衡
C++ 函数调用约定
thiscall用于C++中类成员函数(方法)的调用thiscall 函数调用约定
暂时不懂C++,等学了C++类了再更新ARM/ARM64 函数调用约定
ARM和ARM64使用的是ATPCS(ARM-Thumb Procedure Call Standard/ARM-Thumb过程调用标准)的函数调用约定。ATPCS 函数调用约定
[b]ARM参数1~参数4 分别保存到 R0~R3 寄存器中 ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 R0 中。
; 该代码是 arm-linux-androideabi-gcc + IDA PRO 生成的反汇编代码 .text:00008438 MOV R3, #5 .text:0000843C STR R3, [SP,#0x1C+e] ; e .text:00008440 MOV R3, #6 .text:00008444 STR R3, [SP,#0x1C+f] ; f .text:00008448 MOV R3, #7 .text:0000844C STR R3, [SP,#0x1C+g] ; g .text:00008450 MOV R0, #1 ; a .text:00008454 MOV R1, #2 ; b .text:00008458 MOV R2, #3 ; c .text:0000845C MOV R3, #4 ; d .text:00008460 BL add .text:00008464 STR R0, [R11,#sum] .text:000083C4 EXPORT add .text:000083C4 STR R11, [SP,#-4+var_s0]! .text:000083C8 ADD R11, SP, #0 .text:000083CC SUB SP, SP, #0x1C .text:000083D0 STR R0, [R11,#a] .text:000083D4 STR R1, [R11,#b] .text:000083D8 STR R2, [R11,#c] .text:000083DC STR R3, [R11,#d] .text:000083E0 LDR R2, [R11,#a] .text:000083E4 LDR R3, [R11,#b] .text:000083E8 ADD R2, R2, R3 .text:000083EC LDR R3, [R11,#c] .text:000083F0 ADD R2, R2, R3 .text:000083F4 LDR R3, [R11,#d] .text:000083F8 ADD R2, R2, R3 .text:000083FC LDR R3, [R11,#e] .text:00008400 ADD R2, R2, R3 .text:00008404 LDR R3, [R11,#f] .text:00008408 ADD R2, R2, R3 .text:0000840C LDR R3, [R11,#g] .text:00008410 ADD R3, R2, R3 .text:00008414 STR R3, [R11,#sum] .text:00008418 LDR R3, [R11,#sum] .text:0000841C MOV R0, R3 ; R0返回值 .text:00008420 SUB SP, R11, #0 .text:00008424 LDR R11, [SP+var_s0],#4 .text:00008428 BX LR
ARM64
参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左一次入栈,被调用者实现栈平衡,返回值存放在 X0 中。
; 该代码是 aarch64-linux-android-gcc + IDA PRO 生成的反汇编代码 .text:0000000000400684 MOV W0, #9 .text:0000000000400688 STR W0, [SP,#0x40+i] ; i .text:000000000040068C MOV W0, #10 .text:0000000000400690 STR W0, [SP,#0x40+j] ; j .text:0000000000400694 MOV W0, #11 .text:0000000000400698 STR W0, [SP,#0x40+k] ; k .text:000000000040069C MOV W0, #12 .text:00000000004006A0 STR W0, [SP,#0x40+l] ; l .text:00000000004006A4 MOV W0, #1 ; a .text:00000000004006A8 MOV W1, #2 ; b .text:00000000004006AC MOV W2, #3 ; c .text:00000000004006B0 MOV W3, #4 ; d .text:00000000004006B4 MOV W4, #5 ; e .text:00000000004006B8 MOV W5, #6 ; f .text:00000000004006BC MOV W6, #7 ; g .text:00000000004006C0 MOV W7, #8 ; h .text:00000000004006C4 BL add .text:00000000004006C8 STR W0, [X29,#0x20+sum] .text:00000000004005E8 EXPORT add .text:00000000004005E8 .text:00000000004005E8 SUB SP, SP, #0x30 .text:00000000004005EC STR W0, [SP,#0x30+a] .text:00000000004005F0 STR W1, [SP,#0x30+b] .text:00000000004005F4 STR W2, [SP,#0x30+c] .text:00000000004005F8 STR W3, [SP,#0x30+d] .text:00000000004005FC STR W4, [SP,#0x30+e] .text:0000000000400600 STR W5, [SP,#0x30+f] .text:0000000000400604 STR W6, [SP,#0x30+g] .text:0000000000400608 STR W7, [SP,#0x30+h] .text:000000000040060C LDR W1, [SP,#0x30+a] .text:0000000000400610 LDR W0, [SP,#0x30+b] .text:0000000000400614 ADD W1, W1, W0 .text:0000000000400618 LDR W0, [SP,#0x30+c] .text:000000000040061C ADD W1, W1, W0 .text:0000000000400620 LDR W0, [SP,#0x30+d] .text:0000000000400624 ADD W1, W1, W0 .text:0000000000400628 LDR W0, [SP,#0x30+e] .text:000000000040062C ADD W1, W1, W0 .text:0000000000400630 LDR W0, [SP,#0x30+f] .text:0000000000400634 ADD W1, W1, W0 .text:0000000000400638 LDR W0, [SP,#0x30+g] .text:000000000040063C ADD W1, W1, W0 .text:0000000000400640 LDR W0, [SP,#0x30+h] .text:0000000000400644 ADD W1, W1, W0 .text:0000000000400648 LDR W0, [SP,#0x30+i] .text:000000000040064C ADD W1, W1, W0 .text:0000000000400650 LDR W0, [SP,#0x30+j] .text:0000000000400654 ADD W1, W1, W0 .text:0000000000400658 LDR W0, [SP,#0x30+k] .text:000000000040065C ADD W1, W1, W0 .text:0000000000400660 LDR W0, [SP,#0x30+l] .text:0000000000400664 ADD W0, W1, W0 .text:0000000000400668 STR W0, [SP,#0x30+sum] .text:000000000040066C LDR W0, [SP,#0x30+sum] ;X0 返回值 .text:0000000000400670 ADD SP, SP, #0x30 .text:0000000000400674 RET
相关文章推荐
- IOS生成同时支持armv7,armv7s,i386,x86_64,arm64的静态库.a文件
- Android 关于arm64-v8a、armeabi-v7a、armeabi、x86、x86_64下的so文件兼容问题
- X86、X64和X86_64区别
- x86,amd64,x86-64,x64区别
- x86,I386,i686, x86_64, x64,amd64、Windows Linux AIX下查看CPU位数和操作系统位数、rpm包名
- ZBar 支持i386 armv6 armv7 armv7s x86_64 arm64
- Xcode8.3静态库libmp3lame.a无法真机运行!lame静态库libmp3lame.a 编译,支持arm64 armv7s x86_64 i386 armv7
- 我的Android进阶之旅------>Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题
- Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容。请查看计算机的系统信息,了解是否需要 x86 (32 位)或 x64 (64 位)
- EasyPlayer支持x86和arm64 ABI
- x86,amd64,x86-64,x64区别
- 114. Architectures与指令集架构armv6,armv7,armv7s,arm64,i386,x86_64
- >Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题
- Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容。请查看计算机的系统信息,了解是否需要 x86 (32 位)或 x64 (64 位)
- $NDK_ROOT/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/arm-linux-androideabi/bin/nm
- X86和X86_64和X64有什么区别?
- 【转】iOS lame编译 arm64 armv7s armv7 x86_64 i386指令集
- 几个概念:x86-64 x64以及IA-32 IA-64
- EM64T AMD64(x86-64/x64) i386
- armv7 armv7s arm64 i386 x86_64