常见函数调用约定(x86、x64、arm、arm64)

常见函数调用约定(x86、x64、arm、arm64)_第1张图片

我学习逆向,整理的一些常见的函数调用约定反汇编笔记。由于我是新手,肯定有一些疏漏不完善的,我遇到了会实时更新的。

更新时间:2018年2月18日

常见函数调用约定(x86、x64、arm、arm64)

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;

004010B0  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)

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 [b]

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                                  # 没做栈平衡

X64

参数1、参数2、参数3分别保存在RDX、R8D、R9D中,this指针存放RCX中,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 RAX 中。

# 该代码是 msvc 2017 x64 生成的汇编代码

  int sum = calc.thiscall_add(1, 2, 3, 4, 5, 6, 7);

00007FF602E6190F  mov        dword ptr [rsp+38h],7

00007FF602E61917  mov        dword ptr [rsp+30h],6

00007FF602E6191F  mov        dword ptr [rsp+28h],5

00007FF602E61927  mov        dword ptr [rsp+20h],4

00007FF602E6192F  mov        r9d,3

00007FF602E61935  mov        r8d,2

00007FF602E6193B  mov        edx,1

00007FF602E61940  lea        rcx,[calc]              # this指针

00007FF602E61944  call        Calc::thiscall_add (07FF602E610A0h)

00007FF602E61949  mov        dword ptr [sum],eax    # 返回值

int Calc::thiscall_add(int a, int b, int c, int d, int e, int f, int g)

{

00007FF602E61770  mov        dword ptr [rsp+20h],r9d

00007FF602E61775  mov        dword ptr [rsp+18h],r8d

00007FF602E6177A  mov        dword ptr [rsp+10h],edx

00007FF602E6177E  mov        qword ptr [rsp+8],rcx

00007FF602E61783  push        rbp

00007FF602E61784  push        rdi

00007FF602E61785  sub        rsp,0E8h

00007FF602E6178C  mov        rbp,rsp

00007FF602E6178F  mov        rdi,rsp

00007FF602E61792  mov        ecx,3Ah

00007FF602E61797  mov        eax,0CCCCCCCCh

00007FF602E6179C  rep stos    dword ptr [rdi]

00007FF602E6179E  mov        rcx,qword ptr [rsp+108h]

  int sum = a + b + c + d + e + f + g;

00007FF602E617A6  mov        eax,dword ptr [b]

00007FF602E617AC  mov        ecx,dword ptr [a]

00007FF602E617B2  add        ecx,eax

00007FF602E617B4  mov        eax,ecx

00007FF602E617B6  add        eax,dword ptr [c]

00007FF602E617BC  add        eax,dword ptr [d]

00007FF602E617C2  add        eax,dword ptr [e]

00007FF602E617C8  add        eax,dword ptr [f]

00007FF602E617CE  add        eax,dword ptr [g]

00007FF602E617D4  mov        dword ptr [sum],eax

  return sum;

00007FF602E617D7  mov        eax,dword ptr [sum]  # 存放返回值

}

00007FF602E617DA  lea        rsp,[rbp+0E8h]

00007FF602E617E1  pop        rdi

00007FF602E617E2  pop        rbp

00007FF602E617E3  ret                                # 没做栈平衡

ARM/ARM64 函数调用约定

ARM和ARM64使用的是ATPCS(ARM-Thumb Procedure Call Standard/ARM-Thumb过程调用标准)的函数调用约定。

ATPCS 函数调用约定

ARM

参数1~参数4 分别保存到 R0~R3 寄存器中 ,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 R0 中。

; 该代码是 arm-linux-androideabi-gcc + IDA PRO 生成的反汇编代码

.text:00008438                MOV            R3, #5

.text:0000843C                STR            R3, [SP]

.text:00008440                MOV            R3, #6

.text:00008444                STR            R3, [SP,#4]

.text:00008448                MOV            R3, #7

.text:0000844C                STR            R3, [SP,#8]

.text:00008450                MOV            R3, #8

.text:00008454                STR            R3, [SP,#12]

.text:00008458                MOV            R3, #9

.text:0000845C                STR            R3, [SP,#16]

.text:00008460                MOV            R3, #10

.text:00008464                STR            R3, [SP,#20]

.text:00008468                MOV            R0, #1

.text:0000846C                MOV            R1, #2

.text:00008470                MOV            R2, #3

.text:00008474                MOV            R3, #4

.text:00008478                BL              add

.text:0000847C                STR            R0, [R11,#-8]

.text:000083C4                EXPORT add

.text:000083C4

.text:000083C4                STR            R11, [SP,#-4]!

.text:000083C8                ADD            R11, SP, #0

.text:000083CC                SUB            SP, SP, #0x1C

.text:000083D0                STR            R0, [R11,#-16]

.text:000083D4                STR            R1, [R11,#-20]

.text:000083D8                STR            R2, [R11,#-24]

.text:000083DC                STR            R3, [R11,#-28]

.text:000083E0                LDR            R2, [R11,#-16]

.text:000083E4                LDR            R3, [R11,#-20]

.text:000083E8                ADD            R2, R2, R3

.text:000083EC                LDR            R3, [R11,#-24]

.text:000083F0                ADD            R2, R2, R3

.text:000083F4                LDR            R3, [R11,#-28]

.text:000083F8                ADD            R2, R2, R3

.text:000083FC                LDR            R3, [R11,#4]

.text:00008400                ADD            R2, R2, R3

.text:00008404                LDR            R3, [R11,#8]

.text:00008408                ADD            R2, R2, R3

.text:0000840C                LDR            R3, [R11,#12]

.text:00008410                ADD            R3, R2, R3

.text:00008414                STR            R3, [R11,#-8]

.text:00008418                LDR            R3, [R11,#-8]

.text:0000841C                MOV            R0, R3

.text:00008420                SUB            SP, R11, #0

.text:00008424                LDR            R11, [SP],#4

.text:00008428                BX              LR

ARM64

参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 X0 中。

; 该代码是 aarch64-linux-android-gcc + IDA PRO 生成的反汇编代码

.text:000000000040065C                MOV            W0, #9

.text:0000000000400660                STR            W0, [SP]

.text:0000000000400664                MOV            W0, #10

.text:0000000000400668                STR            W0, [SP,#8]

.text:000000000040066C                MOV            W0, #1

.text:0000000000400670                MOV            W1, #2

.text:0000000000400674                MOV            W2, #3

.text:0000000000400678                MOV            W3, #4

.text:000000000040067C                MOV            W4, #5

.text:0000000000400680                MOV            W5, #6

.text:0000000000400684                MOV            W6, #7

.text:0000000000400688                MOV            W7, #8

.text:000000000040068C                BL              add

.text:0000000000400690                STR            W0, [X29,#28]

.text:00000000004005E8                EXPORT add

.text:00000000004005E8

.text:00000000004005E8                SUB            SP, SP, #0x30

.text:00000000004005EC                STR            W0, [SP,#28]

.text:00000000004005F0                STR            W1, [SP,#24]

.text:00000000004005F4                STR            W2, [SP,#20]

.text:00000000004005F8                STR            W3, [SP,#16]

.text:00000000004005FC                STR            W4, [SP,#12]

.text:0000000000400600                STR            W5, [SP,#8]

.text:0000000000400604                STR            W6, [SP,#4]

.text:0000000000400608                STR            W7, [SP]

.text:000000000040060C                LDR            W1, [SP,#28]

.text:0000000000400610                LDR            W0, [SP,#24]

.text:0000000000400614                ADD            W1, W1, W0

.text:0000000000400618                LDR            W0, [SP,#20]

.text:000000000040061C                ADD            W1, W1, W0

.text:0000000000400620                LDR            W0, [SP,#16]

.text:0000000000400624                ADD            W1, W1, W0

.text:0000000000400628                LDR            W0, [SP,#12]

.text:000000000040062C                ADD            W1, W1, W0

.text:0000000000400630                LDR            W0, [SP,#8]

.text:0000000000400634                ADD            W1, W1, W0

.text:0000000000400638                LDR            W0, [SP,#4]

.text:000000000040063C                ADD            W0, W1, W0

.text:0000000000400640                STR            W0, [SP,#44]

.text:0000000000400644                LDR            W0, [SP,#44]

.text:0000000000400648                ADD            SP, SP, #0x30

.text:000000000040064C                RET

本文由看雪论坛 有影  原创 转载请注明来自看雪社区

你可能感兴趣的:(常见函数调用约定(x86、x64、arm、arm64))