逆向工程權威指南學習筆記
宣告:本文整理自《逆向工程權威指南(上冊)》
非常亂,不行整理了。
第三章
RET 將控制權交給呼叫程式(將控制權交給作業系統)
編譯器在字串常量的尾部添加了00H,原因是為這個字串常量新增結束標誌(即數值為0的單個位元組)
push offset $SG3803
通過push,把字串指標推送入棧。
call _printf
printf函式結束之後,程式的控制流返回到main函式,字串地址仍然在棧中,需要調整棧指標(ESP暫存器的值)來釋放這個指標。
add esp,4;等價於POP 暫存器
把esp暫存器的值加4來釋放這個指標。加4的原因是x86記憶體地址使用32位(即4位元組),在x64的平臺上,就得加8。
IntelC++編譯器使用POPECX而不是add來釋放資料棧,是因為POP ECX對應的Opcode比add esp的opcode要短。
main函式的最後一項任務是讓eax的值為0
AND ESP,0FFFFFFF0H
令ESP的值向16位元組邊界對齊(成為16的整數倍)。主流的編譯規則規定“程式訪問的地址必須向16位元組對齊(被16整除)”
SUB ESP,10h
在棧中分配0x10bytes,即16位元組。
LEAVE指令,等效於“MOVESP,EBP”和“POPEBP”兩條指令。此指令調整了資料棧指標ESP,並將EBP的數值恢復到呼叫這個函式之前的初始狀態。程式段在開始部分就對EBP進行了操作,所以函式要在退出之前恢復這些暫存器的值。
x86-64硬體平臺上,暫存器和指標都是64位的,儲存在R-字頭的暫存器裡。編譯器會優先使用暫存器傳遞部分引數,再利用記憶體傳遞其餘的引數。windows64的程式還會使用RCX、RDX、R8、R9這四個暫存器來存放函式函式引數。
ARM模式
STMFD SP!,{R4,LR}
把R4暫存器和LR暫存器的數值放到資料棧中,此指令首先將SP遞減,在棧中分配一個新的空間以便儲存R4和LR的值。STMFD可以用來在指定的記憶體空間儲存多個暫存器的值。
ADR R0,ahelloworld
先對PC進行取值操作,將字串的偏移量與PC值相加,將結果儲存到R0之中
push ebp;在棧裡儲存EBP暫存器的內容
BL _2printf
BL實施的操作是1.將下一條指令的地址寫入LR暫存器2.將printf函式的地址寫入PC暫存器,引導系統執行該函式。
CISC(複雜指令集)和RISC(精簡指令集)在工作模式上的區別,就是如果擁有複雜指令集,作業系統可以利用棧儲存返回地址。
Mov R0,#0
將R0暫存器清0
LDMFD SP!,R4,PC
把棧裡儲存的PC的值和R4暫存器的值恢復回來。
mov ebp,esp;將ESP的值複製到EBP暫存器
sub esp,x;修改棧的高度,以便為函式的區域性變數申請儲存空間。
在函式執行期間,EBP是函式訪問區域性變數和函式引數的基準值。
mov esp,ebp
pop ebp
RET 0
釋放棧中申請的記憶體,還原EBP暫存器的值,將程式碼控制權還原給呼叫者函式
第5章 棧
ARM的棧分為遞增棧和遞減棧。遞減棧的首地址是棧的最高地址,棧向低地址增長,棧指標的值隨棧的增長而減少。遞增棧則相反。
棧的用途:
1.儲存函式結束時的返回地址。
call指令結束後返回地址將被儲存在棧裡;在call所呼叫的函式結束之後,程式將執行無條件跳轉指令,跳轉到這個返回地址。
2.引數傳遞
cdecl,通過棧指標獲取其所需要的引數。
3.儲存區域性變數
向棧底調整棧指標,函式可在資料棧裡分配出一片可用於儲存區域性變數的記憶體空間。
4.alloca函式
alloca函式直接使用棧來分配記憶體,這是他與malloc的區別。程式不需要特地使用free()來釋放由alloca函式申請的記憶體。
ESP-0xC |
第2個區域性變數,在IDA中為var_8 |
ESP-8 |
第1個區域性變數,在IDA中為var_4 |
ESP-4 |
儲存的EBP值 |
ESP |
返回地址 |
ESP+4 |
arg1,在IDA中記為arg_0 |
ESP+8 |
arg2,在IDA中記為arg_4 |
ESP+0xc |
arg3,在IDA中記為arg_8 |