1. 程式人生 > >逆向工程權威指南學習筆記

逆向工程權威指南學習筆記

宣告:本文整理自《逆向工程權威指南(上冊)》

非常亂,不行整理了。

第三章

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