關(guān)于逆向工程

編程語言


1、機(jī)器語言,電腦CPU可直接解讀,與運(yùn)行平臺密切相關(guān),通用性很差,早期計(jì)算機(jī)利用卡帶記錄01便是如此;

2、匯編語言,是一種用于可編程器件的低級語言。在不同的設(shè)備中,匯編語言對應(yīng)著不同的機(jī)器語言指令集, 運(yùn)行時按照設(shè)備對應(yīng)的機(jī)器碼指令進(jìn)行轉(zhuǎn)換,所以可移植性也較差;

3、高級語言。



編譯、鏈接和PE文件




C\C++語言:

編譯是指編譯器將源代碼進(jìn)行詞法和語法的分析,將高級語言指令轉(zhuǎn)換為匯編代碼。

1、預(yù)處理。正式編譯前,根據(jù)已放置在文件中的預(yù)處理指令來修改源文件的內(nèi)容,包含宏定義指令,條件編譯指令,頭文件包含指令,特殊符號替換等。

2、編譯、優(yōu)化。編譯程序通過詞法分析和語法分析,將其翻譯成等價的中間代碼表示或匯編代碼。

3、目標(biāo)代碼生成。將上面生成的匯編代碼譯成目標(biāo)機(jī)器指令的過程。目標(biāo)文件中所存放著與源程序等效的目標(biāo)的機(jī)器語言代碼。

鏈接是指將有關(guān)的目標(biāo)文件彼此相連接生成可加載、可執(zhí)行的目標(biāo)文件,其核心工作是符號表解析和重定位。鏈接按照工作模式分靜態(tài)和動態(tài)鏈接兩類。

靜態(tài)鏈接:鏈接器將函數(shù)的代碼從其所在地(目標(biāo)文件或靜態(tài)鏈接庫中)拷貝到最終的可執(zhí)行程序中,整個過程在程序生成時完成。靜態(tài)鏈接庫實(shí)際上是一個目標(biāo)文件的集合,其中的每個文件含有庫中的一個或者一組相關(guān)函數(shù)的代碼,靜態(tài)鏈接則是把相關(guān)代碼拷貝到源碼相關(guān)位置處參與程序的生成。

動態(tài)鏈接:動態(tài)鏈接庫在編譯鏈接時只提供符號表和其他少量信息用于保證所有符號引用都有定義,保證編譯順利通過。程序執(zhí)行時,動態(tài)鏈接庫的全部內(nèi)容將被映射到運(yùn)行時相應(yīng)進(jìn)程的虛地址空間,根據(jù)可執(zhí)行程序中記錄的信息找到相應(yīng)的函數(shù)地址并調(diào)用執(zhí)行


經(jīng)過編譯鏈接后,程序生成,windows程序以PE文件形式存儲。

PE文件全稱Portable Executable,意為可移植可執(zhí)行文件,常見的EXE、DLL、OCX、SYS、COM都是PE文件。 PE文件以段的形式存儲代碼和相關(guān)資源數(shù)據(jù),其中數(shù)據(jù)段和代碼段是必不可少的兩個段。

在應(yīng)用程序中最常出現(xiàn)的段有以下6種:

1、執(zhí)行代碼段,.text命名;

2、數(shù)據(jù)段,.data、.rdata 命名;

3、資源段,.rsrc命名;

4、導(dǎo)出表,.edata命名;

5、導(dǎo)入表,.idata命名;

6、調(diào)試信息段,.debug命名。

系統(tǒng)并非在硬盤上直接運(yùn)行程序,而是將其裝載進(jìn)內(nèi)存里,包括其中的代碼段、數(shù)據(jù)段等。

程序運(yùn)行時,由“裝載器”將硬盤上的數(shù)據(jù)復(fù)制到內(nèi)存,裝載器根據(jù)程序的PE頭中的各種信息,進(jìn)行堆棧的申請和代碼數(shù)據(jù)的映射裝載,在完成所有的初始化工作后,程序從入口點(diǎn)地址進(jìn)入,開始執(zhí)行代碼段的第一條指令。


逆向原理


“逆向”,顧名思義,將編譯鏈接好的程序反過來恢復(fù)成“代碼級別”。


C\C++程序在經(jīng)過編譯鏈接后,程序?yàn)闄C(jī)器碼,直接可供CPU使用,對于這類程序我們使用IDA、OD等逆向程序,只能將其恢復(fù)成匯編代碼狀態(tài),然后通過讀匯編代碼來解讀程序的運(yùn)行過程機(jī)制,當(dāng)然,一些逆向工具提供的插件可以將一些函數(shù)恢復(fù)成偽代碼級別。

至此,我們把程序恢復(fù)成了可讀代碼,依靠閱讀這些代碼來梳理程序運(yùn)行過程,這叫做“靜態(tài)調(diào)試”。

與此對應(yīng)的“動態(tài)調(diào)試”則是讓程序運(yùn)行起來,更加直觀的觀察程序的運(yùn)行過程。在動態(tài)調(diào)試中,斷點(diǎn)起著很大的作用,使程序能夠暫停下來以觀察各寄存器狀態(tài)。


常用工具


靜態(tài)分析工具

(1)IDA Pro(Interactive Disassembler Professional )

IDA Pro是總部位于比利時列日市(Liège)的Hex-Rayd公司的一款產(chǎn)品。IDA 的主要目標(biāo)之一,在于呈現(xiàn)盡可能接近源代碼的代碼,而且通過派生的變量和函數(shù)名稱來盡其所能地注釋生成的反匯編代碼,適用于三大主流操作 系統(tǒng):Microsoft Windows.Mac OS X 和 Linux。IDA Pro提供了許多強(qiáng)大功能,例如函數(shù)的交叉引用查看、函數(shù)執(zhí)行流程圖及偽代碼等,并且也有一定的動態(tài)調(diào)試功能。同時,IDA pro可以在windows、linux、ios下進(jìn)行二進(jìn)制程序的動態(tài)調(diào)試和動態(tài)附加,支持查看程序運(yùn)行內(nèi)存空間,設(shè)置內(nèi)存斷點(diǎn)和硬件斷點(diǎn)。


(2)c32asm

c32asm 是款非常好用的反匯編程序,具有反匯編模式和十六進(jìn)制編輯模式,能跟蹤exe文件的斷點(diǎn),也可直接修改軟件內(nèi)部代碼 ,提供輸入表、輸出表、參考字符、跳轉(zhuǎn)、調(diào)用、PE文件分析結(jié)果等顯示 ,提供匯編語句逐字節(jié)分析功能,有助于分析花指令等干擾代碼。


(3)Win32Dasm

Win32dasm可以將應(yīng)用程序靜態(tài)反編譯為WIN 32匯編代碼,利用Win32dasm我們可以對程序進(jìn)行靜態(tài)分析,幫助快速找到程序的破解突破口。筆者下載的 Win32Dasm還可以附加到正在運(yùn)行的進(jìn)程,對進(jìn)程進(jìn)行動態(tài)調(diào)試,但如果原程序經(jīng)過了加密變換處理或著是被EXE壓縮工具壓縮過,那么用Win32dasm對程序進(jìn)行反匯編就沒有任何意義了。


(4)VB Decompiler pro

VB Decompiler pro是一個用來反編譯VB編寫的程序的工具。VB Decompiler反編譯成功后,能夠修改VB窗體的屬性,查看函數(shù)過程等 ,VB Decompiler Pro 能反編譯Visual Basic 5.0/6.0的p-code形式的EXE, DLL 或 OCX文件。對native code形式的EXE, DLL或OCX文件,VB Decompiler Pro 也能給出反編譯線索。



動態(tài)分析工具

(1)Ollydbg

Ollydbg運(yùn)行在windows平臺上,是 Ring 3級調(diào)試器,可以對程序進(jìn)行動態(tài)調(diào)試和附加調(diào)試,支持對線程的調(diào)試同時還支持插件擴(kuò)展功能, 它會分析函數(shù)過程、循環(huán)語句、選擇語句、表[tables]、常量、代碼中的字符串、欺騙性指令、API調(diào)用、函數(shù)中參數(shù)的數(shù)目,import表等等 ;支持調(diào)試標(biāo)準(zhǔn)動態(tài)鏈接庫(Dlls),目前已知 OllyDbg 可以識別 2300 多個 C 和 Windows API 中的常用函數(shù)及其使用的參數(shù),是 Ring3級功能最強(qiáng)大的一款動態(tài)調(diào)試工具。



(2)Windbg

Windbg是Microsoft公司免費(fèi)調(diào)試器調(diào)試集合中的GUI的調(diào)試器,支持Source和Assembly兩種模式的調(diào)試。Windbg不僅可以調(diào)試應(yīng)用程序,還可以 對內(nèi)核進(jìn)行調(diào)試。結(jié)合Microsoft的Symbol Server,可以獲取系統(tǒng)符號文件,便于應(yīng)用程序和內(nèi)核的調(diào)試。Windbg支持的平臺包括X86、IA64、AMD64。Windbg 安裝空間小,具有圖形操作界面,但其最強(qiáng)大的地方是有豐富的調(diào)試指令。


輔助工具

系統(tǒng)監(jiān)視工具:

Wireshark ?(免費(fèi)軟件,網(wǎng)絡(luò)監(jiān)視和包分析類軟件)

Outpost Firewall (共享軟件,使用hook技術(shù)的Windows防火墻)

ProcExp (免費(fèi)軟件,強(qiáng)大的進(jìn)程分析軟件)

FileMon (免費(fèi)軟件,強(qiáng)大的文件讀寫監(jiān)視軟件)

RegMon (免費(fèi)軟件,強(qiáng)大的注冊表讀寫監(jiān)視軟件)

反保護(hù)工具:

LordPE (Win32 PE文件修改,轉(zhuǎn)存工具)

ImportREC (Win32 PE文件結(jié)構(gòu)修復(fù)軟件)

AIl versions ASPack unpacker (免費(fèi)軟件,ASPack壓縮殼脫殼工具)

UnPECompact(免費(fèi)軟件,PECompact壓縮殼脫殼工具)

UPX(自由軟件,UPX壓縮殼加殼和脫殼工具)

其它:

Hedit (共享軟件,16進(jìn)制編輯器)

PEiD (免費(fèi)較件,軟件信息和編寫語言分析工具)


crackme


crackme(通常簡稱CM)是用來測試程序設(shè)計(jì)人員的逆向工程技能的小程序。

KeygenMe、ReverseMe、UnpackMe,KeygenMe是要求別人做出程序?qū)?yīng)的 keygen (序號產(chǎn)生器)。

ReverseMe 要求別人把它的算法做出逆向分析。

UnpackMe 是則是要求別人把它成功脫殼 。

以上參考

一些匯編知識


CPU大體上可以分為3個部分:

1.算術(shù)邏輯部件ALU(arithmetic logic unit)用來進(jìn)行算術(shù)和邏輯運(yùn)算。這部分與我們的關(guān)系不太大,我們沒必要管它。

2.控制邏輯。同樣與我們的關(guān)系不大。

3.工作寄存器,它在計(jì)算機(jī)中起著重要的作用,每一個寄存器相當(dāng)于運(yùn)算器中的一個存儲單元,但它的存取速度遠(yuǎn)遠(yuǎn)快于存儲器。它用來存放計(jì)算過程中所需要的或所得到的各種信息,包括操作數(shù)地址、操作數(shù)及運(yùn)算的中間結(jié)果等。

我們常說的32位,就是說寄存器是32位的。

通用寄存器一共八個,分別是EAX、EBX、ECX、EDX、ESP、EBP、EDI、ESI。

其中,EAX—EDX這四個寄存器又可稱為數(shù)據(jù)寄存器,除了直接訪問外,還可分別對其高十六位和低十六位進(jìn)行訪問。它們的低十六位就是把它們前邊兒的E去掉,即EAX的低十六位就是AX。而且它們的低十六位又可以分別進(jìn)行八位訪問,也就是說,AX還可以再進(jìn)行分解,即AX還可分為AH(高八位)AL(低八位)。

EAX


這四個寄存器,主要就是用來暫時存放計(jì)算過程中所用的操作數(shù)、結(jié)果或其它信息。

ESP、EBP、EDI、ESI這四個寄存器的主要用途就是在存儲器尋址時,提供偏移地址,可以稱為指針或變址寄存器。

1. 通用寄存器:

AX (單字=16位) = AH + AL -> 其中’+’號并不代表把它們代數(shù)相加。AH和AL寄存器是相互獨(dú)立的,只不過都是AX寄存器的一部分,所以你改變AH或AL (或者都改變) ,AX寄存器也會被改變。

-> 'accumulator'(累加器): ? ? ? ? ? ? ? ? ? ? 用于進(jìn)行數(shù)學(xué)運(yùn)算

BX -> 'base'(基址寄存器): ? ? ? ? ? ? ? ? ? ? 用來連接棧(之后會說明)

CX -> 'counter'(計(jì)數(shù)器):

DX -> 'data'(數(shù)據(jù)寄存器): 大多數(shù)情況下用來存放數(shù)據(jù)

DI -> 'destination index'(目的變址寄存器): 例.? 將一個字符串拷貝到DI

SI -> 'source index'(源變址寄存器): 例.? 將一個字符串從SI拷貝

o2. 索引寄存器(指針寄存器):

BP -> 'base pointer'(基址指針寄存器): 表示棧區(qū)域的基地址

SP -> 'stack pointer'(棧指針寄存器): 表示棧區(qū)域的棧頂?shù)刂?/p>

o3. 段寄存器:

CS -> 'code segment'(代碼段寄存器): 用于存放應(yīng)用程序代碼所在段的段基址

DS -> 'data segment'(數(shù)據(jù)段寄存器): 用于存放數(shù)據(jù)段的段基址

ES -> 'extra segment'(附加段寄存器): 用于存放程序使用的附加數(shù)據(jù)段的基地址

SS -> 'stack segment'(棧段寄存器): 用于存放棧段的段基址

o4. 指令指針寄存器:

IP -> 'instruction pointer'(指令指針寄存器): 指向下一個指令

API所用的數(shù)據(jù),均是靠堆棧來傳送的,即先將要傳送的數(shù)據(jù)壓入堆棧,然后CALL至API函數(shù),API函數(shù)會在函數(shù)體內(nèi)用出棧指令將相應(yīng)的數(shù)據(jù)出棧。然后進(jìn)行操作。


參考

參考?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容