手工修復引入表是破解加殼軟件最難的一道工序,一向是頂尖高手的專利,令我等菜鳥往往望而卻步,而不敢奢望越雷池半步!那么有沒有簡單一些的方法呢?通過本人的實踐,終于找到了這條捷徑。我的做法可以分為以下幾步:
1、確定程序的OEP,并脫殼。 2、使未脫殼程序處于正常運行態,使用ImportREC或LordPE檢查是否所有的API都可識別,并記錄下不可識別API的列表及其函數入口地址。 3、重新啟動未脫殼程序,并使之中斷在OEP,用前面記錄到的資料在所有不可識別API的入口設執行斷點,盡可能嘗試軟件所有的功能,通過跟蹤查清每一個不可識別API的名稱及實際入口地址,并加以記錄。 4、再次啟動未脫殼程序,并使之中斷在OEP,用上一步確定的實際API的入口地址逐一替換相應的未識別API入口地址,然后使程序處于正常運行態,使用ImportREC或LordPE進行檢查,這時所有的API就都能識別了。API識別完成后,對已脫殼的程序進行FixDump,整個修復過程就完成了。
下面讓我們一起來親手搞定目前比較兇悍的加殼保護軟件之一--SVKP1.32(當前版本,看雪工具有介紹)。
使用工具:(1)、SoftICE 2.6 根據http://www.chat001.com/forum/crackforum/251195.html自行制作的修改版 (2)、ImportREC 1.6 (http://www.pediy.com/tools/PE_tools/Rebuilder/Import REC/ucfir16f.zip) (3)、LordPE DLX(http://www.pediy.com/tools/PE_tools/Lordpe/LPE-DLX.ZIP) (4)、UltraEdit 10.10a(http://www.ttdown.com/SoftDown.asp?ID=6718)
目標程序: SVK Protect 1.32 (http://www.anticracking.szm.sk/svkp_setup.exe)
安裝目標程序,裝載SoftICE。
1、下斷點“bpint 1”,然后啟動SVKP.EXE,程序中斷于 001B:07BABC57 CD01 INT 01 下命令“bd 0”關閉斷點,并使用命令“r eip 07BAEE11”修改指令指針,以便躲過SEH陷阱,再下命令“g 07D31FA5”,使程序中斷于07D31FA5處(當然,你也可以使用命令“g 00401000”使程序直接停在OEP處),使用F8鍵單步跟蹤,要不了幾步就可以到達程序的OEP:00401000 處了。記錄下此值,并記錄下從OEP開始的幾行指令及相應十六進制編碼,下匯編命令“a eip”修改入口指令為“JMP EIP”然后用命令“x”使程序退出SoftICE并在OEP處進入死循環。
2、下面需要從內存中Dump出程序。啟動LordPE,用鼠標指針點選SVKP.EXE進程,點鼠標右鍵,在彈出的菜單中點選“Correct Image Size”項前先修正映像尺寸。然后在相同的菜單中點選“Dump Full”以Dump出脫過殼的程序,命名為“SVKP_Dump.exe”。然后還在相同菜單下點選“Burn Process”殺死在內存之中處于死循環狀態的程序。此后用LordPE的PE Editor功能調入脫過殼的SVKP_Dump.exe,修改其OEP的RVA為00001000,保存退出。
3、下面需要復原SVKP_Dump.exe在OEP處的指令。使用UltraEdit載入SVKP_Dump.exe,使用十六進制碼搜索功能搜索以下字節串
eb fe f3 4b 00
找到后修改為:
68 1d f3 4b 00
改好后存盤退出。至此,脫殼程序SVKP_Dump.exe修改完畢,剩下的工作就是修復引入表IAT了。
4、啟動ImpotREC,在進程列表中選取SVKP.EXE,修改相應OEP的RVA為00001000,點擊“IAT Auto Search”按鈕,再點擊“Get Impots”按鈕,逐一檢查API的識別情況。最后發現,有5個API程序無法識別,對應的入口分別是:
(1) 07D37656
(2) 07D49E52
(3) 07D49E82
(4) 07D333DD
(5) 07D32070
5、重新啟動加殼程序,使之停在OEP處,下斷點:
(1)、“bpx 07D37656”
(2)、“bpx 07D49E52”
(3)、“bpx 07D49E82”
(4)、“bpx 07D333DD”
(5)、“bpx 07D32070”
然后讓程序繼續執行,分別從斷點處開始跟蹤,看看程序調用的究竟是哪個API,然后再返回到調用處看看:
(1) 00401005 CALL [004C521C] -- 07D37656 <-- SVKP API
(2) 00402F04 CALL [004C51A8] -- 07D49E52 <-- KERNEL32!CopyFileA
(2) 0040300B CALL [004C51A8] -- 07D49E52 <-- KERNEL32!CopyFileA
(3) 00402F58 CALL [004C51B0] -- 07D49E82 <-- KERNEL32!CreateFileMappingA
(3) 00403694 CALL [004C51B0] -- 07D49E82 <-- KERNEL32!CreateFileMappingA
(4) 00401086 CALL [004C51F8] -- 07D333DD <-- KERNEL32!GetModuleHandleA
(5) 004011A8 CALL [004C5200] -- 07D32070 <-- KERNEL32!ExitProcess
現在情況就比較清楚了,第一個API是用于為傳入的地址裝載固定的文本內容,只在程序開始時調用,不是很重要,我們為它指定一個調用形式相當的API--KERNEL32!GetVersionExA作為替代,其它的API已經清楚了。
6、再次啟動加殼程序,使之停在OEP處,用識別出來的API入口地址替換原來無法識別的API入口地址。在本人的系統下,這些識別出來的API的對應地址分別是:
(1)、KERNEL32!GetVersionExA -- 77E6A9C3
(2)、KERNEL32!CopyFileA -- 77E7DA46
(3)、KERNEL32!CreateFileMappingA -- 77E68492
(4)、KERNEL32!GetModuleHandleA -- 77E66C42
(5)、KERNEL32!ExitProcess -- 77E78F94
需要做的工作就是把這些新的入口地址填到相應的內存單元,就像這樣:
序號 內存地址 修改前 修改后
===============================================
(1)、[004C521C] 07D37656 77E6A9C3
(2)、[004C51A8] 07D49E52 77E7DA46
(3)、[004C51B0] 07D49E82 77E68492
(4)、[004C51F8] 07D333DD 77E66C42
(5)、[004C5200] 07D32070 77E78F94
===============================================
為此,分別下命令:
(1)、 “e 004C521C C3 A9 E6 77”
(2)、 “e 004C51A8 46 DA E7 77”
(3)、 “e 004C51B0 92 84 E6 77”
(4)、 “e 004C51F8 42 6C E6 77”
(5)、 “e 004C5200 94 8F E7 77”
以完成此項修改。
完成此項工作后,下命令“r eip 0040102E”,把EIP從00401000更改為0040102E,讓程序繼續執行。按照前面的第4項操作,你會發現,所有的API都可以正常識別出來了。這時,用鼠標點選“Fix Dump”按鈕,在彈出的文件選擇窗中,用Browse功能選取前面已經脫過殼的SVKP_Dump.EXE,點確定就Ok了。
7、由于KERNEL32!GetVersionExA是代用的,所以還需要考慮修改后給程序流向帶來的影響。
001B:00401000 681DF34B00 PUSH 004BF31D
001B:00401005 FF151C524C00 CALL [004C521C]
001B:0040100B 85C0 TEST EAX,EAX
001B:0040100D 751F JNZ 0040102E
我們看到,修改前:
001B:00401005 FF151C524C00 CALL [004C521C]
總是返回EAX=1,而修改后又總是返回EAX=0,這就改變了程序的實際流向,必須補救,措施就是把
001B:0040100D 751F JNZ 0040102E
修改為
001B:0040100D EB1F JMP 0040102E
Ok,你都照做了嗎?大功告成!試著啟動一下程序看看,是不是很酷?
|