1. 程式人生 > >windows程式逆向筆記(一)

windows程式逆向筆記(一)

1.吾愛破解
l 按鈕-程式執行的日誌、外掛載入的資訊檢視
e 按鈕-模組資訊,程式載入的所有模組、庫 都可以看到路徑等 雙擊就可以看到基地址
m 按鈕-記憶體資訊 對於 e按鈕中 的各個模組的基地址等
t 按鈕-執行緒資訊
w 按鈕-視窗資訊
h 按鈕- 一些控制代碼的資訊
c 按鈕-反彙編視窗 或者雙擊 從暫存器的 EIP shift+加號回到之前的位置
p 按鈕-記錄修改資訊 可以在這做還原 恢復
k 按鈕-呼叫堆疊
b 按鈕-斷點
ALT+F9 反回用戶領空
F12 OD暫停

vc6編譯特點: (rdata 只讀資料段)
入口點程式碼是固定的程式碼,入口呼叫的API也是相同的,其中有的push地址不同程式可能不同,區段有四個 也是固定的.text .rdata .data .rsrc
一般呼叫的api:[<&MSVCRT.__set__app_type>][<&MSVCRT.__p__fmode>][<&MSVCRT.__p__commode>]等

vs編譯特點:
入口點固定,一般第一個是call,第二個是jmp
區段:.text .rdata .data .rsrc .reloc(重定位)
易語言:
易語言獨立編譯是呼叫的vc編譯,因為和vc相同(獨立編譯在Exeinfo PE 裡 易語言會被識別成vc(因為是用微軟的聯結器))
區分vc6:找個call呼叫,點進去,看看是不是載入了一些易語言核心庫(jmp dword ptr ds:[0x48DC6C] jmp dword ptr ds:[0x48DC70] jmp dword ptr ds:[0x48DC74] jmp dword ptr ds:[0x48DC64]等)
非獨立編譯:入口壓棧之後,會載入執行庫
例如:ascii “GetNewSock”,0 ascii “error”,0 等 也可以在 e按鈕裡檢視載入庫資訊 fnr 和fne 都是易語言支援庫檔案
看不到程式碼,用ctrl+a 或者用資料分析 就可以看到上面這些ascii “xx” 等
Delphi編譯特點:
區段: CODE DATA BSS .idata .tls .rdata .reloc .rsrc
.net
有時候開啟就執行 外掛-ILLY-RUN/stop ILLY 可以讓.net可以中斷
在 e按鈕裡 看模組資訊,會載入一堆 .net庫
VB和QT (VB語言的編碼用的unicode)
和.net一樣,在模組里加載的庫來分辨

加殼:
UPX一般把區段壓縮成三個區段,殼的區段是任意命名的
Themida 或WinLicense (一個是授權,一個是非授權,一個殼)殼 一般第一個區段是 空的,然後是 .rsrc 和 .idata 然後還有兩個任意命名的區段
VMP殼 看區段,會把加密殼的段放在.data 和 .reloc .rsrc中間,額外新增三個區段,一般是 .XXX0,.XXX,.XXX1 這樣來命名
shielden殼 分析程式碼 會顯示 是 se加殼的
ns(北斗)殼 開始兩個壓棧 ( 可能 區段資訊: 按順序 X0 X1 X2 )

脫殼 一般殼的程式碼比較短,殼程式碼結束的地方就是OEP
1.找OEP (在Import REConstructor中 OEP=找到的地址-基地址 RAV)
2.Dump映象檔案
3.修復IAT
4.修復重定位表,修復資源,修復VMOPE等

FSG脫殼: RVA 怎麼找:  在ope裡進call 函式,然後檢視記憶體     RVA=找到的起始地址 - 基地址    大小 是在call記憶體裡 最後一個減去RVA的地址
		在Import REC裡,點顯示無效的 ,有許多FFFFF的 刪除指標

	有時候xp上可以開啟,windows7等無法開啟,可能是ISA資源沒有修復,也可能是因為ASLR (用CFF explorer開啟程式,然後Nt Headers,然後File Header,然後點右下角,把 Relocation info stripped from file的勾選上(不勾選是支援))
   OD載入每次入口不一樣:我們可以把重定位勾上(關閉),就可以修復

簡單排查崩潰問題
	在od開啟,在strongod中,把 忽略所有異常 去掉,然後 options中,在Exceptions中 把異常型別的鉤全部去掉,然後點執行,崩潰了,看堆疊視窗,然後右鍵跟隨到修復的地方,
	在崩潰的地方下個斷點,然後執行會發現 有地址指向空的地方,把地址複製下來,到有殼時候的這個地址去檢視內容。(一般就是因為其起始位置和大小寫錯了)

修改:①retn,在函式開始的地方直接反匯 ②用nop填充

windows常用函式:
1.MessageBoxA/W
訊息框

2.ShellExecuteA/W
3.WinExec
4.CreateProcessA/W
彈網頁常用三個函式

5.CreateThread

6.RegCreateKeyExA/W
7.RegOpenKeyExA/W
8.RegDeleteKeyExA/W
登錄檔

explorer.exe http://www.52pojie.cn/thread-384195-1-1.html

CreateWindowExA/w     建立視窗
DialogBoxParamA/W

資源修改
1.利用資源編輯器修改版權
Restorator
ResEdit
ResHacker

2.利用API定位修改版權的地方
SetDlgItemTextW/A (DialogBox控制元件設定文字)

3.利用十六進位制編輯器修改
C32Asm
Winhex


課外:給Exe程式新增彈窗
1.新增MessageBoxA的匯入表並獲取VA
MessageBoxA
MessageBoxA  ord:0 rva: 001AA187 VA:005AA187

2.新增一個新的區段,並植入彙編程式碼(彈窗並跳回原來的EP)
push Style(0)
push Title
push Text
push hOwner(0)
call dword ptr ds:[0x5AA187]

3.修改EP到新的起始位置並儲存

很多老殼的出口點是 401000

大小比較自校驗:
	有的軟體脫殼後無法執行,可以檢視是否進行了大小比較,從而判斷是否進行了大小自校驗

小知識:
一般關鍵跳的上面1-3個call 是關鍵call
je是根據上面的比較結果來選擇跳不跳 test al,al 是比較上面call 的返回值 這種情況 call 就是影響跳不跳的關鍵(可以進入call函式內部,修改暫存器的值 使之可以跳轉或不跳轉)

除了通過字串,還可以根據API來尋找,有時候call在裡面,要跳出去當前call,回到上一層或者再上幾層call ,然後檢視上面比較 來修改

ini檔案斷點使用函式:GetPrivateProfileStringA
Alt+F9 反回程序領空     (系統領空是無法修改的!!!!! )(大地址是系統領空 小地址是程式領空)

查詢不到字串,也找不到函式時,可以 右鍵→檢視→user32 進入user32模組,然後 右鍵→查詢->二進位制字串 ,然後輸入十六進位制字串(萬能斷點特徵碼) :F3 A5 8B C8 83 E1 03 F3 A4 E8 
	然後下完斷點,輸入註冊碼以後,回到程式領空,然後繼續向下執行 多看堆疊  (萬能斷點在xp下比較好用)
對於vb程式來說,修改返回值,messagebox等都沒有用,在斷點裡有vb用的 rtcMsgbox 是vb裡的 訊息類彈窗

提示註冊的資訊庫,就叫做 NAG  舉例:(執行程式,出彈窗,然後返回OD,F12暫停,然後檢視呼叫堆疊(K按鈕),然後選擇系統領空的
	user32.messageboxExA,右鍵,選擇 顯示呼叫,然後加斷點,過載程式,然後執行,尋找關鍵條,注意尋找段首和斷尾(一般retn為斷尾)!!!!!!)
jnz  根據標誌位跳轉,zf=0則實現跳轉,zf=1 則不跳轉,一般根據返回值 或檢視上面是否有比較等可以修改標誌暫存器的值

BC++ 的程式脫殼後打不開,可能不是自校驗,需要手動查詢 ITA的地址
	手動查詢方法:到達OEP後,離OEP很近有一個call,我們選中後回車,跟蹤call的裡面尋找 IAT,然後向上翻動,到 段首 的位置,然後選中段首那一行,右鍵,
		資料視窗中跟隨->記憶體地址,然後在下面的資料視窗右鍵,(有可能是 Hex/ascii),然後右鍵, 長型 -> 地址 (更改回地址樣式),然後再ImPrc裡,輸入OEP,
		然後在RVA裡輸入 計算後的地址(資料視窗中的地址-基地址),然後在大小裡輸入1000(這個數比較隨意,只要大過這個段就行),然後點 獲取輸入表,
		然後點 顯示無效函式,然後在無效函式那裡 右鍵,刪除指標,然後轉存即可

使用Dark:假設註冊頁面三個按鈕,把程式載入DD,然後點 過程,找到三個按鈕的視窗,(可以先先右鍵,檢視附件資料看一下資訊,)然後雙擊,根據段首的地址,
		在OD裡載入程式,然後查詢該地址,下斷點然後 執行程式,在註冊碼那裡的按鈕斷掉,其他的斷點關掉。  然後按照對比,找到註冊碼就可以了。

程式破解也可以使用單步法,有時候某個call裡跳出(註冊型別)的視窗,而上面有跳轉可以跳過這個call ,一般就修改這個跳轉跳過這個call就可以了
F12 暫停法尋找註冊碼:載入od,執行程式,彈出註冊失敗等提示框後,反匯OD,F12,然後 執行到使用者程式碼,關閉掉提示框,然後程式會返回到程式領空,
	然後向上尋找關鍵跳 (一般關鍵跳上面就是關鍵call) ,一般需要修改標誌位的話,需要進入關鍵call 裡,在關鍵call裡單步執行,如果遇到假碼了,
	F8別太快,慢慢來,裡面可以找到註冊碼

製作記憶體補丁:先載入程式,找到關鍵跳,然後開啟註冊編寫器,然後 選擇 製作記憶體補丁, 選擇程式,輸入標題,然後點 新增資料: 
		修改地址(關鍵跳地址)   修改範圍(可以不用寫)  修改長度 (關鍵跳地址後面的一列,每2個數字算一個長度,假設 0F8489040000 這是6個長度)
		原始指令(修改長度的那一個數據,地址後面的一列)  修改指令(NOP 是 90,根據在OD中NOP填充多少行 就填寫多少個 90)
		然後點選生成就行了。 然後執行破解補丁就可以
針對易語言的push窗體法(網路驗證):程式載入od, 到地址 401000處,然後 右鍵->查詢->二進位制字串->然後輸入FF 25(找窗體事件。找按鈕事件是FF 55),確定
		到易語言體這裡(上面有個 push 0x520...) ,然後點選右鍵->查詢->命令 ,輸入命令 :push 10001,點查詢,然後下面有個 push 0x520.....複製下來,
		然後把剛開始 通過FF 25那裡的查詢的push 覆蓋掉(繞過掉開始主介面的視窗),然後點彙編,然後複製到可執行檔案 。這樣來回的重複,就可以了
退出暗裝的解決辦法:(這裡以一個開啟自動退出的暗裝為例)載入od,先執行,發現自動退出,重新載入,在外掛->常用斷點設定->常用斷點,勾選上
		ExitProcess(程式退出)斷點,確定。然後執行程式,在斷點處,右下角堆疊視窗中,(在API下面)有個 返回到 (程式名)  來自(程式名),在這一行,右鍵,
		反彙編視窗跟隨,然後上面有個call(就是退出函式的call)。然後上面有個跳轉,修改跳轉,可以跳過這個call,然後複製到可執行程式即可
網路驗證的本地突破:先把程式在dark裡開啟,過程,尋找那個按鈕,有時候點一個按鈕,彈出的介面才有那個按鈕,那要先找外層的按鈕。找到地址後,去od裡
		然後一直F8,然後F8不動了以後(可能是連線伺服器或者彈錯等),可以NOP嘗試一下 ,然後繼續向下找到關鍵條(一個錯誤提示後面一般有個跳轉),一般
		也跳向了失敗,也NOP掉, 然後執行檢視是否成功
		
VB的通用技巧:載入od,右鍵->執行指令碼->開啟,然後選擇指令碼檔案 (需要指令碼支援,比如 vb按鈕事件.txt|.osc|.osc.txt)。之後會自動下斷,然後執行,如果是
		重啟驗證,可以執行一下,在斷點下面,往下翻頁檢視找到 xx xx,0xFFFF(%85的VB程式用這個數值,和四個F作比較,影響下面的關鍵跳),在這裡下斷點,然後把其他
		的斷點刪除,然後這就是關鍵比較,看看可以修改下面的關鍵跳,有多個地方顯示註冊點時,可以複製這條比較命令,然後 右鍵->查詢->所有命令,然後在
		查詢到的命令,右鍵,在每個命令上設定斷點,然後進行相應修改。
所有模組間的呼叫(VB執行之後自動退出):載入od,發現執行之後自動退出,右鍵->查詢->所有模組間的呼叫,找到vb的退出函式 X__vbaEnd,全部下斷,然後F9執行
		程式,然後查詢關鍵跳 (可以跳過call退出函式的地方)進行修改,有的地方沒有跳過函式,就可以不用理他。  假如有關機指令等,可以搜尋字串,找到這
		個字串,然後段首下斷,找到寫入那句話,資料視窗中跟隨,然後資料視窗中選中,空格鍵,然後 勾選上 保持大小,把指令用0填充,然後確定,然後儲存就行了。

脫殼八法:
esp定律: 基本上第一個命令 是 pushad 就可以用esp定律 同時也可以看 右邊暫存器視窗,只有esp是紅色的,就可以使用esp定律
在esp 暫存器上點 右鍵 然後 資料視窗跟隨,然後選擇資料(只要是從esp跟隨過去的,資料選多少都行),選中後點右鍵,然後
選擇 斷點->硬體訪問->然後隨便選一個 ,然後執行到斷點處,然後單步執行,一般碰到 跳轉 大跳轉 跳過來 或者 retn
程式碼變成看不懂(也可能不變) 一般就到oep了
單步跟蹤: 開始,先F8,然後看哪個call跑飛了,就F7進入這個call,繼續F8,然後按照上面的迴圈,如果有往上跳轉的,直接在下面按
F4(執行到所選,前提是跳轉實現再這麼做),一直F8,看到 popad ,一般就快到OEP附近了
兩次斷點:先設定od,在選項,除錯設定,異常,把所有的都打上勾(全部忽略),確定。 然後 Alt+m 鍵,先在 第一個段(與程式名相同的段).rsrc那下F2斷點,
然後按 shift+F9 ,然後在Alt+M,在 401000處下斷,然後 shift +F9,然後按照單步跟蹤法脫殼。
最後一次異常法:載入od,選項->除錯設定->把所有的打上勾的全部取消(不勾選),然後 shift +F9,再一次 shift +F9 (看看 按幾次程式能正常啟動,假如
第二次啟動,那麼異常就只有一次),然後重新載入程式,按異常的次數按shift +F9,然後在右下角堆疊視窗,有一個SE(SE處理程式/SExx控制代碼等),在
上面 右鍵->反彙編視窗跟隨(或者根據中間的地址去查詢),然後F2斷點,然後shift +F9,然後執行到斷點處,然後取消斷點,然後按照單步跟蹤法,脫殼
SFX :載入od,選項->除錯設定->異常,把所有的都打上勾(全部忽略),然後選擇 SFX, 選擇 位元組方式跟蹤真正入口處(單選的最後一個),然後重新載入,然後等待
它自動獲取真正的入口
模擬跟蹤法: 載入od後,可以檢視記憶體,找到 SFX的地址(第一列),然後輸入命令 (tc eip < SFX的地址)然後斷下來就是 OEP(按e檢視基址)一般不直接使用,而是:
先使用兩次斷點法,(第二次斷點不一定是401000,根據基址來尋找,一般是 基地址+ 1000)到接近oep的位置,然後在使用模擬跟蹤法。
出口標誌: 載入od,假如有 pushad,可以右鍵,查詢命令 ,輸入相應的命 popad,取消 整個塊 選項,然後查詢,然後再popad處F4,然後F8,然後檢視是
否到達oep,如果跑飛了,就繼續向下尋找 popad,重複查詢,一直到F4可以斷下來,然後單步向下找到OEP即可
一步OPE: 載入od,直接執行程式,然後看右下角堆疊,先拉到最後,然後往上拉,找到 程式名.地址 那裡,(如果(堆疊視窗)沒有向上的括號)然後反彙編視窗跟隨
(第二列地址跟隨也可),然後反彙編視窗跟隨(第二列地址跟隨也可),刪除分析,然後再看右下角堆疊,有向上的括號,找到 段首,找到
返回到 程式名.地址 ,然後 在反彙編視窗跟隨地址,然後在 向上翻,查詢他的oep(一般是段首),然後
右鍵,資料視窗中跟隨,然後再下面的資料視窗中 右鍵,斷點,硬體執行斷點,然後重新載入,直接執行到斷點,然後脫殼
如果OEP找對,又無法執行,就用loadpe ,先修正映象,然後 完全脫殼。然後再用Import rec修復即可