汇编与易语言
一、堆棧結(jié)構(gòu)
可以看出一個函數(shù)局部變量和實參的位置
二、易語言例子解析
帶上下文
00000000 - 60 pushad 00000001 - 8B 4D 10 mov ecx, dword [ebp+0x10] 00000004 - 8B 7D 08 mov edi, dword [ebp+0x08] 00000007 - 8B 75 0C mov esi, dword [ebp+0x0C] 0000000A - F3 A4 rep movsb 0000000C - 61 popad這里牽涉到其他寄存器,需要保存環(huán)境,默認ebp esp 自動還原
pushad是將8個32位寄存器壓入棧中,壓入的順序依次為 EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
popad 相反
帶局部變量
置入代碼 ({ 139, 69, 8, 139, 0, 137, 69, 252 }) ' mov eax , dword ptr [ebp+08h] //第一個參數(shù)地址賦值給eax ' mov eax , dword ptr [eax] //把上步驟參數(shù)的地址的值取出來 ' mov dword ptr [ebp-04h] , eax //再把值傳給臨時變量ret這里沒看到小數(shù)的轉(zhuǎn)換,只是取值而已, 說明類型無關(guān)
無局部變量
末尾的返回值無效的,只是為了保證編輯器語法通過,可以任意值
這里沒有后面的倆個ret
三、易語言進階例子
數(shù)據(jù)8字節(jié)的(長整數(shù),雙精度浮點數(shù))
置入代碼 ({ 139, 69, 8, 255, 48, 143, 69, 248, 255, 112, 4, 143, 69, 252 }) ' mov eax , dword ptr [ebp+08h] ’第一個參數(shù)翻入eax ' push dword ptr [eax] 把參數(shù)所指的值并入棧 4個字節(jié) 低位 ' pop dword ptr [ebp-08h] 把參數(shù)的值賦值給第二個局部變量 ' push dword ptr [eax+04h] 4個字節(jié) 高位 ' pop dword ptr [ebp-04h] 高位對應(yīng)局部變量高位末尾多倆個ret指令,無用,但看著別扭
低地址存低位,高地址存高位,棧是往低地址擴展的
從匯編看這個函數(shù)stdcall調(diào)用方式
四、c/c++例子
__cdecall:參數(shù)右到左入棧,調(diào)用方維持堆棧平衡(默認)
__stdcall:參數(shù)右到左入棧,被調(diào)用方堆棧平衡
SS:stack segment register 棧段暫存器
SP:stack pointer 棧指針
在VS編輯器中中堆棧會自動幫你配平衡,只需要關(guān)鍵匯編代碼,比如下例子
eax保存函數(shù)返回值,edx保存高位
無局部變量
int add(int a, int b) {_asm{mov eax, dword ptr[ebp + 08h] //第一個參數(shù)add eax, dword ptr[ebp + 0Ch] //第二個參數(shù),堆棧的地址高到低,先入棧}//return (a + b);//K&R推薦return都打括號 }標(biāo)準(zhǔn)調(diào)用方式
int __stdcall add(int a, int b) {_asm{mov eax, dword ptr[ebp + 08h]add eax, dword ptr[ebp + 0ch]}//return (a + b);//K&R推薦return都打括號 }RETN 8看到?jīng)],被調(diào)用方維持堆棧平衡,2個參數(shù)8個字節(jié)
c調(diào)用方式
int add(int a, int b) {//int c = 10;_asm{mov dword ptr[ebp - 04h], 10mov eax, dword ptr[ebp + 08h]add eax, dword ptr[ebp + 0ch]add eax, dword ptr[ebp -04h]}//return (a + b + c);//K&R推薦return都打括號 }數(shù)據(jù)8字節(jié)的(長整數(shù),雙精度浮點數(shù))
long long add(long long a, long long b) {return (a + b);//K&R推薦return都打括號 }long long 是8個字節(jié),低位低位相加,高位高位相加
增加一個臨時變量
五、相關(guān)指令
leave 指令
等價于
mov esp, ebppop ebpcall 指令
1、段內(nèi)轉(zhuǎn)移的CALL指令等價于:push eipjmp 目的位置 2、段間轉(zhuǎn)移的CALL指令等價于:push CSpush eipjmp 目的位置RETN/RETF 指令
RETN指令用于從段內(nèi)CALL;
RETF指令用于從段間CALL。
倆種格式:
RETN/RETF
RETN/RETF 操作數(shù)
六、總結(jié)
1、匯編指令結(jié)合od ,分析了易語言中的置入代碼.
2、VS編輯器內(nèi)聯(lián)匯編分析c/c++代碼, 快捷鍵alt +8 查看反匯編窗口.
3、坑就是VS編譯要禁止優(yōu)化, od出現(xiàn)大量db時, 刪除分析即可
終于完結(jié)了, 通過實踐果然對匯編與內(nèi)存的印象更加深刻~
七、相關(guān)文檔
通用32位CPU 常用寄存器及其作用
總結(jié)
- 上一篇: 突然发现浏览器广告拦截插件原理
- 下一篇: 三级联动下拉列表的开发过程与范例