哇嗚,我寫了一半了。接下來也繼續加油吧 \OwO/
在 Dx03 “hello world” 篇中,有嘗試利用修改檔案將顯示的字串改成其他的字串過 ( Patch
)。但是當這個程式有經過壓縮器保護後,我們難以找到原本存放原本字串的位置 ( 通常是 .rdata
區塊 ) 來進行更改。所以想對已經被加殼的程式進行 patch
時,就需要等壓縮器的 EP
跑完後進入 OEP
時,插隊放入可以修改資料的代碼,這樣才能進行修改,俗稱 “code cave
”。
原本解壓縮是像這樣 :
EP
開始執行OEP
執行原程式插入 code cave
後 :
EP
開始執行CodeCave
( 透過修改 jmp
)CodeCave
跳回 OEP
既然要做一個內嵌代碼補丁,就得來一個最好有加殼的破解對象。
看看今天要破解的項目吧 : unpackme by ap0x
由於原本的程式在書中與官網的連結掛了,所以我在這邊放上備份的檔案。
https://github.com/Dinlon5566/IT_Reverse_Engineering/tree/main/Dx15
首先利用 x32dbg
來分析這個程式在 EP
後會做甚麼 :
哇 ! 慘了,這個不像之前那個 UPX
可以直接找 popad
來查詢 OEP
( 因為連 pushad
都沒有 )。不過沒有關係,他 call
了 4010E9
的位置,執行進去看看 :
看來它把 4010F5
這個位置移到 EAX
後 call
了 40109B
,一樣進去
看起來這邊有比較多東西可以分析,逐行分析看看
40109B : 把 EAX
推到 stack
保存起來,直到 4010BB
取出
40109C : 把剛剛丟進 EAX
的值傳到 EBX
40109E : 計數器設置 154
,與 4010AD
一起判斷是在設定一個範圍
4010A3 : 對 EBX
的直指向位置的一個 byte
進行與 44
的 XOR
運算
4010A9 : EBX ++
4010AA : 檢查 ECX
是不是 0
4010AD : 透過 FLAG
確認上行的結果,非 0
就回到 4010A3
根據 40109C
與 40109E
可以判定解碼的範圍 : 40109B +153
( 第一次也要 -1 ) = 401249
故第一個加密區塊範圍在 4010F5 ~ 401248
? 之後的加密區塊部分有些大同小異,差不多的就不再一行一行解釋 ( 懶 )。
當解密結束後,call
到 4010BD
。此時 EAX = 004010F5
。
看到了是跟上面很像的加密動作,起始點是 401007
,範圍在 7F
, XOR
值是 7
。
計算出第二個解密區塊是 401007 ~ 401085
。
緊接著又繼續下個解密,起始點是 EAX = 004010F5
( 上面都沒動到 ),範圍是 154
,值是11
。
計算出第三個解密區塊是 4010F5 ~ 401248
。
恩...這範圍似乎有點相似……這不就是剛剛解密的第一個區塊範圍 ! 原來是二次解密呢 !
回到 RET
,下一個指令是 call 401039
。這個調用位置是剛剛解密過的第二個區塊。
首先可以看到 又將 EAX
給到 EBX
,ECX
設定成 154
。
但多了把 EDX
歸零的動作,之後將 EBX
指向位置的資料加上去。大概就是把 4010F5 ~ 401248
的資料全加起來,之後與 401062
行的 31EB8DB0
這個值來比對 ( overflow
計算上忽略 ) ,要是不一樣就發出錯誤信息,稱之為 Check sum
。
在 0040105D
時 call
了一個 40108A
,看看吧
又是解密區塊,這時候 EAX
是 40124A
,他想直接做到 ESI = 00401280
。XOR
值是 17
。
結束後就跳回401062
。
下一行就是比對 check sum
,透過 JE
來分出是否有竄改的結局;要是正常就跳到 401083
,否則就彈出視窗,解鎖 Bad End 。
繼續看上圖,正常路線該是 jmp 40121E
,繼續下去。
看起來這邊就是主程式了,有種柳暗花明的感覺呢。
既然 40121E
就是 OEP
了,那就要特別關注帶我們跳到 OEP
的 401083
。
今天就到這邊吧,明天來把 Cave code 打上去 !