研究aspr殼的pre-dip

看雪資料發表於2015-11-15

一年多前,在漢化新世紀論壇看到Volx關於Aspr殼的pre-dip跟蹤和處理的帖子,獲益非淺。
漢化新世紀論壇多次被黑,資料也丟失了,實在可惜。
在這裡只是把幾個帖子內容重複敘述。
何謂pre-dip?我只能說一個大概,就是在程式程式碼解壓後達到OEP之前殼在程式放入殼的地址指標,達到程式後返回殼執行相應的功能。
pre-dip按照分佈的位置可分為四個部分,第一個部分有6個Call EAX和一個Call EBX(也有Call [xxxxxx]的形式。
位置在第21個異常(準確位置以堆疊窗出現硬碟指紋為準)
硬碟指紋在我的機子上看到是這樣"mIjMiACQQJ8=",每部機子的程式碼都不一樣,但位元組長度一樣,以“=”結尾。
到達異常後在下方設斷點,按Shift+F9跳出異常後按F8單步往下走就能看到如下的結構,每個Aspr殼都有這樣的結構,除了記憶體地址不同其它的結構都是一樣的。

011BAA53   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAA58   8B40 0C          MOV EAX,DWORD PTR DS:[EAX+C]
011BAA5B   FFD0             CALL EAX                      <<==pre-dip1
011BAA5D   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAA62   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
011BAA65   85C0             TEST EAX,EAX
011BAA67   74 29            JE SHORT 011BAA92
011BAA69   8B15 1CC71B01    MOV EDX,DWORD PTR DS:[11BC71C]
011BAA6F   E8 C8FCFFFF      CALL 011BA73C
011BAA74   68 90551B01      PUSH 11B5590
011BAA79   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAA7E   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
011BAA81   FFD0             CALL EAX                     <<==pre-dip2
011BAA83   68 90551B01      PUSH 11B5590                  
011BAA88   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAA8D   8B40 2C          MOV EAX,DWORD PTR DS:[EAX+2C]
011BAA90   FFD0             CALL EAX                      <<==pre-dip3
011BAA92   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAA97   8378 28 00       CMP DWORD PTR DS:[EAX+28],0
011BAA9B   74 0F            JE SHORT 011BAAAC
011BAA9D   68 60561B01      PUSH 11B5660
011BAAA2   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAAA7   8B40 28          MOV EAX,DWORD PTR DS:[EAX+28]
011BAAAA   FFD0             CALL EAX                      <<==pre-dip4
011BAAAC   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAAB1   8378 2C 00       CMP DWORD PTR DS:[EAX+2C],0
011BAAB5   74 0F            JE SHORT 011BAAC6
011BAAB7   68 30561B01      PUSH 11B5630
011BAABC   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAAC1   8B40 2C          MOV EAX,DWORD PTR DS:[EAX+2C]
011BAAC4   FFD0             CALL EAX                     <<==pre-dip5
011BAAC6   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAACB   8378 30 00       CMP DWORD PTR DS:[EAX+30],0
011BAACF   74 0F            JE SHORT 011BAAE0
011BAAD1   68 FC551B01      PUSH 11B55FC
011BAAD6   A1 1CC71B01      MOV EAX,DWORD PTR DS:[11BC71C]
011BAADB   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
011BAADE   FFD0             CALL EAX                     <<==pre-dip6
011BAAE0   8B15 C4C51B01    MOV EDX,DWORD PTR DS:[11BC5C4]
................
011BAB43   8B15 1CC71B01    MOV EDX,DWORD PTR DS:[11BC71C]
011BAB49   E8 EEFBFFFF      CALL 011BA73C
011BAB4E   8B1D 1CC71B01    MOV EBX,DWORD PTR DS:[11BC71C]
011BAB54   8B1B             MOV EBX,DWORD PTR DS:[EBX]
011BAB56   FFD3             CALL EBX                     <<==pre-dip7
011BAB58   8D55 C8          LEA EDX,DWORD PTR SS:[EBP-38]
011BAB5B   E8 20C0FEFF      CALL 011A6B80
011BAB60   8B55 C8          MOV EDX,DWORD PTR SS:[EBP-38]
011BAB63   A1 FCC51B01      MOV EAX,DWORD PTR DS:[11BC5FC]
011BAB68   E8 738AFEFF      CALL 011A35E0
011BAB6D   EB 0A            JMP SHORT 011BAB79

跟進Call EAX 後是位置在程式領空,能看到類似的結構
004FE148   55               PUSH EBP
004FE149   8BEC             MOV EBP,ESP
004FE14B   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
004FE14E   A3 D4085200      MOV DWORD PTR DS:[5208D4],EAX <<=看EAX的值指向殼地址。
004FE153   5D               POP EBP
004FE154   C2 0400          RETN 4

EAX的值就是殼的地址指標,越過OEP後會返回到殼地址執行相應的功能。

第一部分有7個pre-dip,有相應的7種功能。
pre-dip1(以在殼的位置排序)
硬碟指紋,越過OEP後會返回到殼檢測是否有硬碟指紋,脫殼後沒有這個地址,會造成異常。
有部分程式以硬碟指紋來計算註冊碼。
應對:在程式領空找一個空地,最好是塊的最後,填入硬碟指紋,然後把這個地址放入相應的位置。
假設硬碟指紋放在521FF0處,那麼5208D4填入F01F5200(注意高低位的順序)。
pre-dip2
指向殼的一個RET(C3),如果單獨使用是簡單檢測殼是否存在。
應對:在程式領空找一個RET讓指標指向此處。
pre-dip3
同pre-dip2
pre-dip4
校驗註冊碼,與硬碟指紋計算後生成一個密匙,在部分殼裡,會解壓N段程式碼起到防止脫殼的功能。
應對:越過OEP後對此地址設斷點監視執行時是否解壓程式碼,如果解壓程式碼等程式碼解壓完後,dump下這段程式碼,修補dump.exe相應的位置,並把指標指向程式的一個RET.如果沒有解壓程式碼,把指標指向當時的EIP例如上例在5208D4處填入4EE14F00.
pre-dip5
已經註冊的程式在執行重要功能時返回殼解密N段關鍵程式碼,這是Aspr強悍之處,使用此功能如果沒有key很難破解,曾經在001論壇看到zombieys放過一個例子,Awmaw1.55;Awmaw1.6;Awmaw1.81其中Awmaw1.81在不用key的情況下根據Awmaw1.55;Awmaw1.6還原Awmaw1.81的解密程式碼。
應對:越過OEP後對此地址設斷監視,等N段程式碼解密完成後dump下這段程式碼修補dump.exe相應的程式碼,並把相應的指標指向程式的RET,但要注意堆疊值,如果有變必須做相應的調整。
pre-dip6
和pre-dip5是成對出現,功能是對解密程式碼重新加密。
應對:解密後的程式碼一般會出現pre-dip6的指標,跟蹤加密完成後的堆疊值,然後做相應的處理,CALL RET
或nop掉或調整堆疊指標。如果有pre-dip5;pre-dip6就不必理會pre-dip2;pre-dip3因為地址是相同的。
pre-dip7
這個比較特別,起破壞作用,執行後修復難度加大,具體例子可參考jingulong在001論壇的《Afslock1.60a脫殼》的帖子。

第22個異常中斷後是註冊名的pre-dip
第23個異常後兩個pre-dip第一個是時間計數,第二個是使用次數計數。
第24個異常有兩個pre-dip這是生死轉折,試用時間和使用次數已過會跳到第一個pre-dip,用工具脫殼往往也會
跳到第一個pre-dip。
另外還有一處隱藏的pre-dip(aspr強悍之處),例如水晶按鈕在第22異常後如果是註冊版會引發新的異常中斷後有一排功能相同的pre-dip,像這種情況除非是能算出key了。

由於水平有限很難表達清楚,不足之處望各位指正。
再次感謝VolX的精彩帖子。

相關文章