自校檢是許多軟件的保護手段之一,對軟件加個簡單的殼再增加自校檢在一定程序上可以抵擋住一大部分新手,不過,對許多人來說,這個保護已經很弱了。。下面講幾種常見的解決自校檢方法,寫的粗略,希望大家補充。
1、通用對比法。就是將已經觸發自校檢的程序與原來正常的程序進行關鍵跳轉對比,這種方法比較通用,大部分的自校檢可以通過此方法解決(如果軟件有防多開窗口的限制,需
要先解決這個問題。)附件中的sample1.EXE是一個加了ASPACK的自校檢程序,修改任何代碼或大小等都會觸發校檢提示軟件被修改。dumped.EXE是脫殼后的文件,由于觸發校檢運行后出現“文件被非法修改”的提示,現在我們來解決脫殼后文件的自校檢問題。打開脫殼后的程序dumped.EXE,下斷BP?CreateFileA,F9兩次后出現出錯提示。CTRL+F2重新載入dumped.EXE,下斷BP?reateFileA,F9一次。這時另開一個OD打開原來的程序sample1.EXE,用腳本到達OEP,命令中也下斷BP?CreateFileA,F9一次,這時兩個OD停在同一個地方,然后在兩個OD中逐步單步跟蹤,碰到JE、JNE、JBE...之類的關鍵跳轉要對比一下兩者的區別。
7C801A24?>??8BFF????????????MOV?EDI,EDI??????????????????????????????;?BP?CreateFileA斷在這里,ALT+F9返回
7C801A26????55??????????????PUSH?EBP
=================
0040111C??|.??3BF4??????????CMP?ESI,ESP??????????????????????????????;??都停在這里,逐步F8,進行關鍵跳轉的對比
0040111E??|.??E8?0D030000???CALL?crcdumpe.00401430
00401123??|.??8985?E0FEFFFF?MOV?DWORD?PTR?SS:[EBP-120],EAX
00401129??|.??83BD?E0FEFFFF>CMP?DWORD?PTR?SS:[EBP-120],-1
00401130??|.??75?07?????????JNZ?SHORT?crcdumpe.00401139
逐步F8,跟到下面的代碼時,發現兩個跳轉不一樣:
0040120C???/75?07???????????JNZ?SHORT?crc.00401215???????????????????;?原版這個地方信息窗口提示:跳轉沒有實現
0040120E???|B8?01000000?????MOV?EAX,1
00401213???|EB?02???????????JMP?SHORT?crc.00401217
00401215???\33C0????????????XOR?EAX,EAX
=======================
0040120C??|.?/75?07?????????JNZ?SHORT?crcdumpe.00401215??????????????;??脫殼版這個地方信息窗口提示:跳轉已經實現,NOP掉
0040120E??|.?|B8?01000000???MOV?EAX,1
00401213??|.?|EB?02?????????JMP?SHORT?crcdumpe.00401217
00401215??|>?\33C0??????????XOR?EAX,EAX
這時將脫殼版0040120C處代碼NOP掉后另存為dumpedFIX.EXE。試著運行一下,如果正常完事,還不行的話繼續跟蹤下去。該例只改這一處。
2、跟蹤退出函數。附件中sample2也是個自校檢程序,修改任何一處軟件會自動退出。我們試著用UltraEdit將sample2.EXE的最后一個字節改為01后另存為sample2-change.EXE,這時運行sample2-change就會自動退出,我們就是要從退出函數入手。軟件退出一般都是調用ExitProcess、PostQuitMessage之類的,我們用OD載入sample2-change.EXE,從輸入表中我們可以看出軟件是調用ExitProcess退出的。于是在OD中下斷BP?ExitProcess,F9運行,斷下后看堆棧信息:
0012FEB8???004015B5??/CALL?到?ExitProcess?來自?sample2-.004015AF?????//從這里我們可以看出ExitProcess的調用地方是在004015AF
0012FEBC???00000000??\ExitCode?=?0
0012FEC0???20DFA6E6
在OD中CTRL+G,輸入004015AF:
004015AF??|.??FF15?AC514200?CALL?DWORD?PTR?DS:[<&KERNEL32.ExitProces>;?\就在這里,向上找這個子CALL的首部
004015B5??|>??8BE5??????????MOV?ESP,EBP
004015B7??|.??5D????????????POP?EBP
004015B8??\.??C3????????????RETN
=======================================
004014E0??/$??55????????????PUSH?EBP?????????????????????????????????;??找到這里,注意信息欄的內容
004014E1??|.??8BEC??????????MOV?EBP,ESP
004014E3??|.??51????????????PUSH?ECX
004014E4??|.??833D?F8354200>CMP?DWORD?PTR?DS:[4235F8],1
004014EB??|.??75?11?????????JNZ?SHORT?sample2-.004014FE
信息欄的內容:
Local?Calls?from?0040146B,?0040148B,?004014A9,?004014C9
也就是說有四個地方調用ExitProcess退出,因為程序的退出按鈕和關閉的叉號也是調用ExitProcess函數的,一般都會在前面幾個,我們在內容上右擊,“前往CALL來自0040146B”
0040146B??|.??E8?70000000???CALL?sample2-.004014E0???????????????????;?\到這里,同樣查找首部
00401470??|.??83C4?0C???????ADD?ESP,0C
00401473??|.??5D????????????POP?EBP
00401474??\.??C3????????????RETN
============
00401460??/$??55????????????PUSH?EBP?????????????????????????????????;??在這里,信息欄提示:Local?Calls?from?00401072,?<ModuleEntryPoint>+11A
00401461??|.??8BEC??????????MOV?EBP,ESP
00401463??|.??6A?00?????????PUSH?0???????????????????????????????????;?/Arg3?=?00000000
00401465??|.??6A?00?????????PUSH?0???????????????????????????????????;?|Arg2?=?00000000
在Local?Calls?from?00401072上右擊,前往CALL來自00401072:
00401048??|.??E8?BDFFFFFF???CALL?sample2-.0040100A
0040104D??|.??85C0??????????TEST?EAX,EAX
0040104F??|.??74?1F?????????JE?SHORT?sample2-.00401070???????????????;??是從這里跳過去的,NOP掉
00401051??|.??8BF4??????????MOV?ESI,ESP
00401053??|.??6A?30?????????PUSH?30??????????????????????????????????;?/Style?=?MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401055??|.??68?28004200???PUSH?sample2-.00420028???????????????????;?|Title?=?"提示"
0040105A??|.??68?1C004200???PUSH?sample2-.0042001C???????????????????;?|Text?=?"正常運行!"
0040105F??|.??6A?00?????????PUSH?0???????????????????????????????????;?|hOwner?=?NULL
00401061??|.??FF15?B4524200?CALL?DWORD?PTR?DS:[<&USER32.MessageBoxA>>;?\MessageBoxA
00401067??|.??3BF4??????????CMP?ESI,ESP
00401069??|.??E8?82050000???CALL?sample2-.004015F0
0040106E??|.??EB?07?????????JMP?SHORT?sample2-.00401077
00401070??|>??6A?00?????????PUSH?0
00401072??|.??E8?E9030000???CALL?sample2-.00401460???????????????????;??就是這里了,最終會調用ExitProcess,向上看是從哪里跳過來
00401077??|>??33C0??????????XOR?EAX,EAX
可以看出,00401072處的CALL最終呼叫ExitProcess退出,所以只要使0040104F處的跳轉失效即可,將0040104F的跳轉NOP掉后保存,測試運行正常。
三、利用第三方軟件輔助查找關鍵的地方。很多軟件利用CRC或者MD5實現磁盤文件校驗或者內存映像校驗等,對此類軟件我們可以利用算法識別工具找到密碼學算法和核心,然后層層向上,找到最初的調用地方更改其流程方向。還是附件中的sample1.EXE,脫殼的文件為dumped.EXE,我們來解決這個軟件的自校檢。先用PEID的插件kanal分析dumped.EXE所采的密碼學算法,如圖,
可以看出,軟件采用了CRC算法,算法特征碼出現在0040131C,就從這里入手,OD載入dumped.EXE,CTRL+G搜索0040131C:
0040131C??|???2083?B8ED898D?AND?BYTE?PTR?DS:[EBX+8D89EDB8],AL????????;??找到的地方在這里,上拉找到這個CALL的首部
00401322??|???FC????????????CLD
00401323??|???FB????????????STI
00401324??|???FFFF???????????????????????????????????????????????????;??未知命令
00401326??|.??EB?0E?????????||JMP?SHORT?crcdumpe.00401336
00401328??|>??8B95?FCFBFFFF?||MOV?EDX,DWORD?PTR?SS:[EBP-404]
0040132E??|.??D1EA??????????||SHR?EDX,1
00401330??|.??8995?FCFBFFFF?||MOV?DWORD?PTR?SS:[EBP-404],EDX
00401336??|>^?EB?B5?????????|\JMP?SHORT?crcdumpe.004012ED
00401338??|>??8B85?F8FBFFFF?|MOV?EAX,DWORD?PTR?SS:[EBP-408]
0040133E??|.??8B8D?FCFBFFFF?|MOV?ECX,DWORD?PTR?SS:[EBP-404]
00401344??|.??898C85?00FCFF>|MOV?DWORD?PTR?SS:[EBP+EAX*4-400],ECX
0040134B??|.^?E9?6AFFFFFF???\JMP?crcdumpe.004012BA
============================
00401290??/>?\55????????????PUSH?EBP?????????????????????????????????;??到這里,看OD的提示欄:Jump?from?00401005,從00401005跳轉來的
00401291??|.??8BEC??????????MOV?EBP,ESP
00401293??|.??81EC?50040000?SUB?ESP,450
00401299??|.??53????????????PUSH?EBX
0040129A??|.??56????????????PUSH?ESI
在Jump?from?00401005上右擊,“前往JMP?來自00401005”
00401005???$?/E9?86020000???JMP?crcdumpe.00401290????????????????????;??到這里,看信息欄內容:Local?Call?from?00401201,00401201處的CALL調用這里
0040100A???$?|E9?B1000000???JMP?crcdumpe.004010C0
在Local?Call?from?00401201上右擊,“前往CALL?來自00401201”
00401201??|.??E8?FFFDFFFF???CALL?crcdumpe.00401005???????????????????;??到這里,再向上找到這個CALL的頂部
00401206??|.??83C4?08???????ADD?ESP,8
==================
004010C0??/>?\55????????????PUSH?EBP?????????????????????????????????;??到這里,看任務欄信息:Jump?from?0040100A
004010C1??|.??8BEC??????????MOV?EBP,ESP
004010C3??|.??81EC?64010000?SUB?ESP,164
在Jump?from?0040100A上右擊,“前往JMP?來自0040100A”
0040100A???$?/E9?B1000000???JMP?crcdumpe.004010C0????????????????????;??到這里,繼續根據任務欄信息向上找:Local?Call?from?00401048
0040100F???$?|E9?1C000000???JMP?crcdumpe.00401030
在Local?Call?from?00401048上右擊,“前往CALL?來自00401048”
00401048??|.??E8?BDFFFFFF???CALL?crcdumpe.0040100A???????????????????;??就是這里了,計算CRC并進行對比的CALL
0040104D??|.??85C0??????????TEST?EAX,EAX
0040104F??|.??74?1F?????????JE?SHORT?crcdumpe.00401070???????????????;??這里就是關鍵跳轉了,NOP掉
00401051??|.??8BF4??????????MOV?ESI,ESP
00401053??|.??6A?30?????????PUSH?30??????????????????????????????????;?/Style?=?MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401055??|.??68?40004200???PUSH?crcdumpe.00420040???????????????????;?|Title?=?"提示"
0040105A??|.??68?34004200???PUSH?crcdumpe.00420034???????????????????;?|Text?=?"正常運行!"
0040105F??|.??6A?00?????????PUSH?0???????????????????????????????????;?|hOwner?=?NULL
00401061??|.??FF15?B4524200?CALL?DWORD?PTR?DS:[<&user32.MessageBoxA>>;?\MessageBoxA
更改0040104F處的跳轉后保存為dumpedFIX,運行正常。
四、對付校檢自身大小的軟件的一般方法。也有許多軟件,利用CHECKSUM、FILELEN等在代碼中對本身的大小做了標記,如果發現大小變了就自動退出。附件中的FILELEN就是這樣的,FILELEN-UNPACK.EXE是脫殼后的軟件,由于脫殼后軟件大小發生了變化,所以FILELEN-UNPACK運行后就自動退出。對付這種校檢,我們有個簡單的方法,就是將脫殼后的軟件中檢測自身大小的部分改為脫殼后文件的大小。我們看一下FILELEN的大小為:10752字節轉16進制為2A00,再看看脫殼后的文件FILELEN-UNPACK.EXE的大小30208字節,即7600,關鍵是如何找到對自身大小進行對比的語句,我們知道一般的形式都是CMP?EAX,2A00,但是到底是哪個寄存器呢?EAX,EBX、ECX....,寄存器種類比較多,我們不可能每個去找,這時W32Dasm派上用場。用W32Dasm載入FILELEN-UNPACK,我們只要搜索00002A00即可,前面的部分不管它,找到在這里:
:00401B8F?81FE002A0000????????????cmp?esi,?00002A00
右擊-“HEX”,更改代碼002A00為脫殼后的大小007600即可,再搜索,發現該例只有一個對比的地方,保存后運行正常。
對于VB檢測自身大小的軟件我們還可以跟蹤FileLen函數,因為VB一般都用FileLen檢測自身的大小,用OD載入FILELEN-UNPACK.EXE,下斷BP?rtcFileLen,F9后斷下,ALT+F9返回:
00401B5E???.??8BF0??????????MOV?ESI,EAX??????????????????????????????;??這里EAX的值就是FILELEN取得的自身的大小,EAX=00007600
00401B60???.??8D55?D4???????LEA?EDX,DWORD?PTR?SS:[EBP-2C]
00401B63???.??8D45?D8???????LEA?EAX,DWORD?PTR?SS:[EBP-28]
00401B66???.??52????????????PUSH?EDX
00401B67???.??8D4D?E0???????LEA?ECX,DWORD?PTR?SS:[EBP-20]
00401B6A???.??50????????????PUSH?EAX
00401B6B???.??8D55?DC???????LEA?EDX,DWORD?PTR?SS:[EBP-24]
00401B6E???.??51????????????PUSH?ECX
00401B6F???.??8D45?E4???????LEA?EAX,DWORD?PTR?SS:[EBP-1C]
00401B72???.??52????????????PUSH?EDX
00401B73???.??50????????????PUSH?EAX
00401B74???.??6A?05?????????PUSH?5
00401B76???.??FF15?70104000?CALL?DWORD?PTR?DS:[<&msvbvm60.__vbaFreeS>;??msvbvm60.__vbaFreeStrList
00401B7C???.??8D4D?CC???????LEA?ECX,DWORD?PTR?SS:[EBP-34]
00401B7F???.??8D55?D0???????LEA?EDX,DWORD?PTR?SS:[EBP-30]
00401B82???.??51????????????PUSH?ECX
00401B83???.??52????????????PUSH?EDX
00401B84???.??6A?02?????????PUSH?2
00401B86???.??FF15?14104000?CALL?DWORD?PTR?DS:[<&msvbvm60.__vbaFreeO>;??msvbvm60.__vbaFreeObjList
00401B8C???.??83C4?24???????ADD?ESP,24
00401B8F???.??81FE?002A0000?CMP?ESI,2A00?????????????????????????????;??這里就是利用FILELEN取得的大小與原來做的標記對比,可以改這里的2A00為7600或者更改下面的跳轉
00401B95???.??75?6E?????????JNZ?SHORT?FILELEN-.00401C05
00401B97???.??B9?04000280???MOV?ECX,80020004
好像常見的自校檢就這些,我不知道還有沒有其它的,如果有希望大家能夠補充完善。
附件:http://bbs.pediy.com/attachment.php?attachmentid=2017&d=1151747683