常見函式呼叫約定(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
0040113 C 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)
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 [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 # 沒做棧平衡
C++ 函式呼叫約定
thiscall用於C++中類成員函式(方法)的呼叫
thiscall 函式呼叫約定
暫時不懂C++,等學了C++類了再更新
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,#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
相關推薦
常見函式呼叫約定(x86、x64、arm、arm64)
我學習逆向,整理的一些常見的函式呼叫約定反彙編筆記。由於我是新手,肯定有一些疏漏不完善的,我遇到了會實時更新的。 X86 函式呼叫約定 X86 有三種常用呼叫約定,cdecl(C規範)/stdcall(WinAPI預設)/fastcall
2018/10/03-函式呼叫約定、cdecl、stdcall、fastcall- 《惡意程式碼分析實戰》
cdecl是最常用的約定之一,引數是從右到左按序被壓入棧,當函式完成時由呼叫者清理棧,並且將返回值儲存在EAX中。 stdcall約定是被呼叫函式負責清理棧,其他和cdecl非常類似。 fastcall呼叫約定跨編譯器時變化最多,但是它總體上在所有情況下的工作方式都是相似的。在fastcall
cdecl、stdcall、fastcall、thiscall函式呼叫約定區別 (轉)
在C語言中,假設我們有這樣的一個函式: int function(int a,int b) 呼叫時只要用result = function(1,2)這樣的方式就可以使用這個函式。但是,當高階語言被編譯成計算機可以識別的機器碼時,有一個問題就凸現出來:在CPU中,計算機沒有辦法知道一個函式呼叫需要
cdecl、stdcall、fastcall函式呼叫約定區別
論函式呼叫約定 在C語言中,假設我們有這樣的一個函式: int function(int a,int b) 呼叫時只要用result = function(1,2)這樣的方式就可以使用這個函式。但是,當高階語言被編譯成計算機可以識別的機器碼時,有一個問題就凸現出來:在CPU中
push、pop及函式呼叫約定
push: 把一個32位的運算元壓入堆疊中。這個操作導致esp被減4。esp被形象地稱為棧頂。我們認為頂部是地址小的區域,那麼,壓入堆疊中資料越多,這個堆疊也就越堆越高,esp也就越來越小。在32位平臺,esp每次減少4位元組。 pop: 相反,esp被加4,一個數據
x64函式呼叫約定——MSVC & GCC
傳參 MSVC 前4個引數使用rcx、rdx、r8、r9,剩下的引數用棧 GCC 前6個引數使用rdi、rsi、rdx、rcx、r8、r9,剩下的引數用棧。注意rdx、rcx的順序和MSVC上不一樣 caller saved registers 這類暫存器可由子函式自由使用,
x86 常見呼叫約定(cdecl,fastcall,stdcall) & x86和ARM呼叫約定的棧幀分析 & ARM ATPCS(ARM-THUMB procedure call standard)
#PS:要轉載請註明出處,本人版權所有 #PS:這個只是 《 我自己 》理解,如果和你的 #原則相沖突,請諒解,勿噴 由於某些工作的需要,我需要掌握X86以及ARM的一些呼叫規則,讓自己可以大致看懂ASM程式碼。於是,我總結了一下我需要的東西
Windows x64彙編函式呼叫約定
最近在寫一些字串函式的優化,用到x64彙編,我也是第一次接觸,故跟大家分享一下。 x86:又名 x32 ,表示 Intel x86 架構,即 Intel 的32位 80386 彙編指令集。 x64:表示 AMD64 和 Intel 的 EM64T ,而不包括 IA6
從彙編角度檢視C語言函式呼叫約定【非常有用】
轉自:https://blog.csdn.net/Holmofy/article/details/76094986 為了防止出現不必要的程式碼影響組合語言的檢視,所以程式中不使用任何庫函式,以保持彙編程式碼的簡潔。 這裡所使用的彙編是VC的MASM。 預設函式呼叫方式_
【軟體開發底層知識修煉】二十五 ABI之函式呼叫約定二之函式返回值為結構體時的約定
上一篇文章學習了幾種函式呼叫約定的區別,點選連結檢視上一篇文章:【軟體開發底層知識修煉】二十四 ABI之函式呼叫約定 本篇文章繼續學習函式呼叫約定中,關於函式返回值的問題。當函式返回值為結構體時,函式返回值是如何來傳給呼叫者的。
【軟體開發底層知識修煉】二十四 ABI之函式呼叫約定
上一篇文章學習了Linux環境下的函式棧幀的形成與摧毀。點選連結檢視相關文章:軟體開發底層知識修煉】二十三 ABI-應用程式二進位制介面三之深入理解函式棧幀的形成與摧毀 本篇文章繼續學習ABI介面相關的內容。函式呼叫約定
名字修飾約定和函式呼叫約定
所謂名字修飾約定,就是指變數名、函式名等經過編譯後重新輸出名稱的規則。 比如原始碼中函式名稱為int Func(int a,int b),經過編譯後名稱可能為[email protected]@[email protected]、[email
函式呼叫約定與函式名稱修飾規則(一)
作者:星軌(oRbIt) E_Mail:[email protected] 轉載請註明原作者,否則請勿轉載 使用C/C++語言開發軟體的程式設計師經常碰到這樣的問題:有時候是程式編譯沒有問題,但是連結的時候總是報告函式不存在(經典的L
函式呼叫約定及函式名修飾規則
函式呼叫約定:是指當一個函式被呼叫時,函式的引數會被傳遞給被呼叫的函式和返回值會被返回給呼叫函式。函式的呼叫約定就是描述引數是怎麼傳遞和由誰平衡堆疊的,當然還有返回值。 幾種型別:__stdcall,__cdecl,__fastcall,__thiscall,__n
論函式呼叫約定
在C語言中,假設我們有這樣的一個函式: int function(int a,int b) 呼叫時只要用result = function(1,2)這樣的方式就可以使用這個函式。但是,當高階語言被編譯成計算機可以識別的機器碼時,有一個問題就凸現出來:在CPU中,計算機沒有辦法
ARM函式呼叫約定
1、函式呼叫約定主要涉及引數如何傳遞、返回值如何傳遞、返回地址如何儲存以及不要破壞呼叫函式的上下文。那麼在ARM中,這些約定規則是什麼樣呢? 2、測試程式如下: static int fun_a(uint32_t a, uint32_t b, uint32_t c) {
Iperf使用教程、移植到ARM、移植時遇到的問題解決。
iperf是一個基於Client/Server的網路效能測試工具,可以測試TCP、UDP和SCTP頻寬質量,能夠提供網路吞吐率資訊,以及震動、丟包率,最大段和最大傳輸單元大小等統計資訊,幫助我們測試網路效能,定位網路瓶頸。其中抖動和丟包率適應於UDP測試,二頻寬測試適應於TC
x86、arm、mips架構函式呼叫例項分析
原文網址:http://nieyong.github.com/wiki_cpu/ 在看過了上面的幾節之後,在潛意識中你想記住的東西肯定很多了。這個時候,你需要靜下心來休息一下在沉澱一下。 "Now is a good point to take a break to l
檢查.net dll構建的目標平臺是any cpu、x86、x64
example out exe 使用 mic ons tar ima target 有時候,需要檢查構建的dll是否針對正確的平臺 可以使用CorFlags.exe(它是.NET Framework SDK的一部分)從dll中查找此信息。運行CorFlags.exe將產生以
python函式呼叫順序、高階函式、巢狀函式、閉包詳解
一:函式呼叫順序:其他高階語言類似,Python 不允許在函式未宣告之前,對其進行引用或者呼叫錯誤示範: def foo(): print 'in the foo' bar() foo() 報錯: in the foo Traceback (most re