大神論壇 逆向脫殼分析基礎學習筆記四 堆疊篇
本文為本人在大神論壇逆向破解脫殼學習筆記之一,為本人對以往所學的回顧和總結,可能會有謬誤之處,歡迎大家指出。
陸續將不斷有筆記放出,希望能對想要入門的萌新有所幫助,一起進步
堆疊
堆疊是什麼?
一塊區域
用於:
臨時儲存一些資料,如果數量很少就放到暫存器中
堆疊需要具備的功能
能夠記錄存了多少資料
能夠非常快速地找到某個資料
堆疊的優點
臨時儲存大量資料,便於查詢
簡易的堆疊模型
- BASE,TOP是2個32位的通用暫存器,裡面儲存的是記憶體單元編號(記憶體地址).
- BASE裡面儲存了一個地址,記錄的起始地址.
- TOP裡面也儲存了一個地址,記錄的是結束的地址.
- 存入資料的時候,TOP的值減4(為方便演示,每次存取都是4個位元組)
- 釋放資料的時候,TOP的值加4(為方便演示,每次存取都是4個位元組)
- 如果要讀取中間的某個資料的時候可以通過TOP 或者 BASE 加上偏移的方式去讀取
- 這種記憶體的讀寫方式有個學名:堆疊
自己模擬一個堆疊
指定棧底和棧頂
Windows分配棧時 是從高地址往低地址分配
MOV EBX,0x13FFDC BASE
MOV EDX,0x13FFDC TOP
棧底和棧頂可以是兩個任意的暫存器(Windows採用的是EBP和ESP)
剛開始堆疊為空,棧頂和棧底相同
將資料寫入堆疊(入棧)
先將資料壓入後再修改棧頂
資料壓入
MOV DWORD PTR DS:[EDX-4],0xAAAAAAAA
修改棧頂
SUB EDX,4
先修改棧頂後再將資料壓入
修改棧頂
LEA EDX,DWORD PTR DS:[EDX-4] (和上面的SUB一樣)
資料壓入
MOV DOWRD PTR DS:[EDX],0xAAAAAAAA
讀取堆疊中的內容
棧頂加偏移讀取
MOV ESI,DWORD PTR DS:[EBX-8]
棧底加偏移讀取
MOV EDI,DWORD PTR DS:[EDX+4]
將資料彈出堆疊(出棧)
先取出資料再修改棧頂
取出資料
MOV EAX,DOWRD PTR DS:[EDX]
修改棧頂
ADD EDX,4
先修改棧頂再取出資料
修改棧頂
LEA EDX,DWORD PTR DS:[EDX+4]
取出資料
MOV EAX,DOWRD PTR DS:[EDX-4]
WINDOWS的堆疊的操作
上面我們自己模擬的兩個用作棧頂和棧底的暫存器在WINDOWS中分別對應ESP和EBP
並且前面我們自己模擬的入棧和出棧操作也有對應的指令:PUSH 和 POP
就是封裝了壓入資料和修改棧頂的操作
push xxx將 xxx的資料壓入堆疊
pop xxx將棧頂的資料儲存到xxx中
堆疊相關彙編指令
PUSH指令
PUSH r32
PUSH r16
PUSH m16
PUSH m32
PUSH imm8/imm16/imm32
所有的push都是將esp-4?
不是,要分情況,看壓入的資料的資料寬度
當push的是立即數將esp-4
當push r32如push eax時將esp-4
當push dword ptr ds:[12FFDA]即壓入雙字記憶體地址中的資料時將esp-4
當push word ptr ds:[12FFDA]即壓入字記憶體地址中的資料時將esp-2
當push ax,即r16 ,16位通用暫存器時,esp-2
push不允許壓入資料寬度為8的資料 如ah al 和byte ptr ds:[記憶體編號]
POP指令
POP r32
POP r16
POP m16
POP m32
PUSHAD和POPAD指令
將所有的32位通用暫存器壓入堆疊,方便後面隨意使用暫存器,用於保護現場
與POPAD對應
PUSHFD和POPFD指令
然後將32位標誌暫存器EFLAGS壓入堆疊
與POPAD對應
其它相關指令
pusha:將所有的16位通用暫存器壓入堆疊
popa:將所有的16位通用暫存器取出堆疊
pushf::將的16位標誌暫存器EFLAGS壓入堆疊
popf:將16位標誌暫存器EFLAGS取出堆疊
本系列逆向脫殼基礎學習都在下方連結中,歡迎下載並交流溝通
文由 lyl610abc 原創,歡迎分享本文,轉載請保留出處