AlphaRom是日本游戲常用的保護方式,它的新版本比以前加強了不少。最近脫一個galgame的殼,略有心得,記錄如下:
首先是反調試強度增加,在xp中用普通ollydbg也無法運行,可能是StrongOD和HideOD沒調對選項吧。還好用nooby的ollydbg能正常運行。
其次是IAT加密,它把一大部分API的代碼復制進自己分配的內存中去,并加上大量垃圾指令。如果事先在API的任何位置下了int 3斷點的話,復制過程中就直接出錯導致程序跳出。而如果在API下硬件斷點,則經常無法斷在需要的地方,因為程序本體執(zhí)行API大部分都是去殼復制完的代碼里執(zhí)行。
以下是脫殼過程:
1. 運行AlphaRom激活工具alsignup_act_100723_110729.exe并運行游戲, 這樣游戲就被激活,可以正常運行了。
2. PEID顯示連接器版本6.0,所以找GetVersion,把它的最后一個指令retn改成EB FE。然后運行一陣暫?匆谎,如果停在這個指令上就手動讓函數返回。繼續(xù)運行直到某次停在另外一個地址的EB FE上,這就是被殼復制過去的GetVersion,返回后上面的push ebp就是OEP了。
3. 找到OEP后以后只要在OEP上下硬件斷點就可以停在OEP了。停在OEP上后可以dump,只需要頭兩個section就夠了,后面5個都是殼的section。
4. 在dump下來的文件中搜索call [address]和jmp [address],也就是FF15和FF25開頭的call和jmp,address限制在程序本體范圍內。這可以寫幾句C完成。
5. 整理上面搜到的address,就是iat的thunks的地址。在importrec里手動填寫iat的起始地址和大小,Get Imports后Save tree保存為iat.txt。注意這里如果叫importrec自動搜索iat的話搜不全。
6. 發(fā)現有一小部分iat是正確API地址,其他大多都是殼分配的地址,還有幾個地址本身處于殼區(qū)段。
7. 首先解決在殼分配的地址里復制的API。先嘗試hook GetVersion,讓它用E9跳到一個空白處再跳回來。重新運行程序,驚喜地發(fā)現GetVersion對應的iat地址上直接變成了舊版AlphaRom里的jmp GetVersion。得出結論:API開頭若是E9大跳,殼就不會復制代碼了。通過對GetVersion開頭下內存訪問斷點分析,找到了四個相關的跳轉位置,寫一個ODBGScript,負責在這四個跳轉處改變eip,也就是讓殼以為所有API的開頭都是E9大跳轉。不能直接在代碼上patch,否則會出錯跳出。完事后復制代碼部分的iat就全得到了。ODBGScript如下:
lc
dbh
mov OEP, 43ab20
mov CHECK_1, 9692db
mov JUMP_1, 9695cd
mov CHECK_2, 965781
mov JUMP_2, 965868
mov CHECK_3, 967828
mov JUMP_3, 968443
mov CHECK_4, 968524
mov JUMP_4, 968540
bphws OEP, "x"
loop:
bphws CHECK_1, "x"
run
cmp eip, CHECK_1
jne end
mov eip, JUMP_1
bphwc CHECK_1
bphws CHECK_2, "x"
run
cmp eip, CHECK_2
jne end
mov eip, JUMP_2
bphwc CHECK_2
bphws CHECK_3, "x"
run
cmp eip, CHECK_3
jne end
mov eip, JUMP_3
bphwc CHECK_3
bphws CHECK_4, "x"
run
cmp eip, CHECK_4
jne end
mov eip, JUMP_4
bphwc CHECK_4
jmp loop
end:
cmp eip, OEP
jne final
log "Finished"
final:
8. 注意,此時得到的API中有ntdll里的,要把這些換成對應的kernel32里的API。在dump下來的文件中,iat的thunks的地址后面一點就有全部的API名字與dll名字,把API名字整理出來,找出現在iat.txt中不存在的,然后就可以輕易找出ntdll函數與kernel32函數的對應。這種對應比如像ntdll.RtlFreeHeap其實是kernel32.HeapFree。
9. 然后還剩5個殼區(qū)段中的iat,這些都是復制的API。這個并沒有被前面的腳本簡化,應該是殼在不同的地方進行的復制。通過與剩下的名字對比,并查看調用它們的地方,很容易根據參數個數和種類猜出來。
10. 最后用importrec來Load tree,加載修改過的iat.txt,Fix dump,脫殼就完成了。