老王舊殼之INT3異常、過期限制和資料附加脫殼分析

看雪資料發表於2004-11-17

     日期:2004年11月17日   破解人:csjwaman[DFCG]
―――――――――――――――――――――――――――――――――――――――――――
 
 
【軟體名稱】:EncryptPE1.0 V1.2003.5.18加殼的某程式
【軟體限制】:INT3異常、過期限制、資料附加
【脫殼宣告】:感謝fly、loveboom等高手的幫助!
【作業系統】:WIN2K
【脫殼工具】:OD等

【原文連結】:http://bbs.pediy.com/showthread.php?s=&threadid=7101

―――――――――――――――――――――――――――――――――――――――――――
 
【脫殼過程】:
 
  殼中加了INT3異常,還有過期限制,還有資料附加。
對INT3異常只要象脫EncryptPE V1.2003.5.1 Preview一樣把INT3異常NOP掉就行了。過期限制用bp GetLocalTime下斷。下面是脫殼和修復過程:


一、脫殼

用OD載入,隱藏OD,忽略所有異常,同時新增忽略0EEDFADF和C0000008異常。載入後停在:


0044D000 >  60              PUSHAD=====>停在這兒。
0044D001    9C              PUSHFD
0044D002    64:FF35 0000000>PUSH DWORD PTR FS:[0]
0044D009    E8 79010000     CALL 2.0044D187
0044D00E    0000            ADD BYTE PTR DS:[EAX],AL
0044D010    0000            ADD BYTE PTR DS:[EAX],AL
0044D012    0000            ADD BYTE PTR DS:[EAX],AL
0044D014    0000            ADD BYTE PTR DS:[EAX],AL


F9執行異常在:

77F813A2    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
77F813A5    FF75 08         PUSH DWORD PTR SS:[EBP+8]
77F813A8    E8 ECEC0000     CALL ntdll.77F90099
77F813AD    5D              POP EBP
77F813AE    C2 1800         RETN 18
77F813B1 >  CC              INT3======>NOP掉!
77F813B2    C3              RETN=======>停在此處。
77F813B3    33C9            XOR ECX,ECX
77F813B5    E9 A5BE0000     JMP ntdll.77F8D25F
77F813BA >  55              PUSH EBP
77F813BB    8BEC            MOV EBP,ESP
77F813BD    56              PUSH ESI
77F813BE    8B75 08         MOV ESI,DWORD PTR SS:[EBP+8]
77F813C1    8A06            MOV AL,BYTE PTR DS:[ESI]
77F813C3    3C 02           CMP AL,2

下斷bp GetLocalTime後SHIFT+F9執行程式,斷在:


77E649B6 >  55              PUSH EBP=====>斷在此處。取消斷點。看看堆疊區資料。
77E649B7    8BEC            MOV EBP,ESP
77E649B9    83EC 18         SUB ESP,18
77E649BC    56              PUSH ESI
77E649BD    A1 1800FE7F     MOV EAX,DWORD PTR DS:[7FFE0018]
77E649C2    8B0D 1400FE7F   MOV ECX,DWORD PTR DS:[7FFE0014]
77E649C8    3B05 1C00FE7F   CMP EAX,DWORD PTR DS:[7FFE001C]
77E649CE  ^ 75 ED           JNZ SHORT kernel32.77E649BD
77E649D0    8B15 2400FE7F   MOV EDX,DWORD PTR DS:[7FFE0024]
77E649D6    8B35 2000FE7F   MOV ESI,DWORD PTR DS:[7FFE0020]
77E649DC    3B15 2800FE7F   CMP EDX,DWORD PTR DS:[7FFE0028]
77E649E2  ^ 75 EC           JNZ SHORT kernel32.77E649D0
77E649E4    2BCE            SUB ECX,ESI
77E649E6    1BC2            SBB EAX,EDX
77E649E8    894D F8         MOV DWORD PTR SS:[EBP-8],ECX


堆疊區資料:

0123FBD8   7112A429  /CALL 到 GetLocalTime 來自 V1200351.7112A424
0123FBDC   0123FBE8  \pLocaltime = 0123FBE8
0123FBE0   71128B70  ASCII "%d"

到7112A429處:

7112A424    E8 8BC8FFFF     CALL V1200351.71126CB4    ; JMP to kernel32.GetLocalTime
7112A429    66:8B4C24 0E    MOV CX,WORD PTR SS:[ESP+E]=====>下斷後F9執行到此。然後取消斷點。
7112A42E    66:8B5424 0A    MOV DX,WORD PTR SS:[ESP+A]
7112A433    66:8B4424 08    MOV AX,WORD PTR SS:[ESP+8]
7112A438    E8 1BFEFFFF     CALL V1200351.7112A258
7112A43D    DD5C24 18       FSTP QWORD PTR SS:[ESP+18]
7112A441    9B              WAIT
7112A442    66:8B4424 16    MOV AX,WORD PTR SS:[ESP+16]
7112A447    50              PUSH EAX
7112A448    66:8B4C24 18    MOV CX,WORD PTR SS:[ESP+18]
7112A44D    66:8B5424 16    MOV DX,WORD PTR SS:[ESP+16]
7112A452    66:8B4424 14    MOV AX,WORD PTR SS:[ESP+14]
7112A457    E8 5CFCFFFF     CALL V1200351.7112A0B8
7112A45C    DC4424 18       FADD QWORD PTR SS:[ESP+18]
7112A460    DD1C24          FSTP QWORD PTR SS:[ESP]
7112A463    9B              WAIT
7112A464    DD0424          FLD QWORD PTR SS:[ESP]
7112A467    83C4 20         ADD ESP,20
7112A46A    C3              RETN=======>返回。

返回到:


711A0EF0    83C4 F8         ADD ESP,-8====>返回到這裡。
711A0EF3    DD1C24          FSTP QWORD PTR SS:[ESP]
711A0EF6    9B              WAIT
711A0EF7    8D95 90FDFFFF   LEA EDX,DWORD PTR SS:[EBP-270]
711A0EFD    B8 741B1A71     MOV EAX,V1200351.711A1B74     ; ASCII "yyyymmdd"
711A0F02    E8 3DA1F8FF     CALL V1200351.7112B044
711A0F07    8B95 90FDFFFF   MOV EDX,DWORD PTR SS:[EBP-270]
711A0F0D    58              POP EAX
711A0F0E    E8 3D3BF8FF     CALL V1200351.71124A50=====>日期比較CALL。
711A0F13    73 0D           JNB SHORT V1200351.711A0F22=====>必須跳。修改C標誌位為0。
711A0F15    8D45 E0         LEA EAX,DWORD PTR SS:[EBP-20]
711A0F18    BA 881B1A71     MOV EDX,V1200351.711A1B88
711A0F1D    E8 CA37F8FF     CALL V1200351.711246EC
711A0F22    B2 01           MOV DL,1
711A0F24    A1 D0961371     MOV EAX,DWORD PTR DS:[711396D0]
711A0F29    E8 9628F8FF     CALL V1200351.711237C4
711A0F2E    8945 D8         MOV DWORD PTR SS:[EBP-28],EAX
711A0F31    837D E8 00      CMP DWORD PTR SS:[EBP-18],0
711A0F35    0F85 32010000   JNZ V1200351.711A106D========>不能跳,修改Z標誌位為1。
711A0F3B    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
711A0F3E    8078 34 00      CMP BYTE PTR DS:[EAX+34],0
711A0F42    0F85 18010000   JNZ V1200351.711A1060
711A0F48    8D8D 88FDFFFF   LEA ECX,DWORD PTR SS:[EBP-278]
711A0F4E    BA 08000000     MOV EDX,8
711A0F53    B8 01000000     MOV EAX,1
711A0F58    E8 177CF8FF     CALL V1200351.71128B74


至此,日期限制已取消。直接F9執行,等出現註冊框後在記憶體映象401000段下記憶體訪問斷點,然後點註冊框中的“確定”。程式斷在:

00408AF7    55              PUSH EBP=====>這就是入口。現在可以DUMP了。
00408AF8    8BEC            MOV EBP,ESP
00408AFA    6A FF           PUSH -1
00408AFC    68 20434100     PUSH 2.00414320
00408B01    68 F0C34000     PUSH 2.0040C3F0
00408B06    64:A1 00000000  MOV EAX,DWORD PTR FS:[0]
00408B0C    50              PUSH EAX
00408B0D    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00408B14    83EC 58         SUB ESP,58
00408B17    53              PUSH EBX
00408B18    56              PUSH ESI
00408B19    57              PUSH EDI
00408B1A    8965 E8         MOV DWORD PTR SS:[EBP-18],ESP
00408B1D    FF15 F0414100   CALL NEAR DWORD PTR DS:[4141F0]          ; kernel32.GetVersion
00408B23    33D2            XOR EDX,EDX
00408B25    8AD4            MOV DL,AH
00408B27    8915 7C934100   MOV DWORD PTR DS:[41937C],EDX
00408B2D    8BC8            MOV ECX,EAX


DUMP後刪除第二區段,然後用ImportREC直接修復IAT,重建PE後脫殼完成。

二、修復

執行脫殼後的程式提示某處不能訪問等等。估計有自校驗,用OD載入,下斷bp GetFileSize,執行後程式斷在:

77E66B4E >  55              PUSH EBP=====>斷在這裡,看看堆疊區資料。
77E66B4F    8BEC            MOV EBP,ESP
77E66B51    51              PUSH ECX
77E66B52    51              PUSH ECX
77E66B53    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
77E66B56    50              PUSH EAX
77E66B57    FF75 08         PUSH DWORD PTR SS:[EBP+8]
77E66B5A    E8 B7FFFFFF     CALL KERNEL32.GetFileSizeEx
77E66B5F    85C0            TEST EAX,EAX
77E66B61    0F84 1F6E0200   JE KERNEL32.77E8D986
77E66B67    8B45 0C         MOV EAX,DWORD PTR SS:[EBP+C]
77E66B6A    85C0            TEST EAX,EAX
77E66B6C    0F85 612D0000   JNZ KERNEL32.77E698D3
77E66B72    837D F8 FF      CMP DWORD PTR SS:[EBP-8],-1
77E66B76    0F84 FE6D0200   JE KERNEL32.77E8D97A
77E66B7C    8B45 F8         MOV EAX,DWORD PTR SS:[EBP-8]
77E66B7F    C9              LEAVE
77E66B80    C2 0800         RETN 8

堆疊區資料:

0012FEFC   0040189A  /CALL 到 GetFileSize 來自 dumped_.00401894
0012FF00   00000058  |hFile = 00000058 (window)
0012FF04   00000000  \pFileSizeHigh = NULL

到40189A處看看:

00401894    FF15 2C414100   CALL NEAR DWORD PTR DS:[<&kernel32.GetFi>; KERNEL32.GetFileSize
0040189A    56              PUSH ESI=====>來到這裡。這時EAX=1A0F6F,其實就是檔案長度。
0040189B    8BD8            MOV EBX,EAX
0040189D    E8 6A030000     CALL dumped_.00401C0C
004018A2    8BE8            MOV EBP,EAX=====>經過上面的CALL後EAX=EOFBA。
004018A4    59              POP ECX
004018A5    3BEB            CMP EBP,EBX=====>以上兩個值比較。
004018A7    75 05           JNZ SHORT dumped_.004018AE====>不等則跳,跳則出錯。原程式跳,脫殼後程式也跳。
004018A9    6A 0D           PUSH 0D
004018AB    5B              POP EBX
004018AC    EB 71           JMP SHORT dumped_.0040191F
004018AE    57              PUSH EDI
004018AF    55              PUSH EBP
004018B0    56              PUSH ESI
004018B1    E8 3E010000     CALL dumped_.004019F4
004018B6    6A 04           PUSH 4
004018B8    68 10914100     PUSH dumped_.00419110
004018BD    56              PUSH ESI
004018BE    E8 46010000     CALL dumped_.00401A09
004018C3    A1 10914100     MOV EAX,DWORD PTR DS:[419110]
004018C8    83C4 18         ADD ESP,18
004018CB    3BC7            CMP EAX,EDI
004018CD   /74 09           JE SHORT dumped_.004018D8====>跳!
004018CF   |50              PUSH EAX
004018D0   |E8 965E0000     CALL dumped_.0040776B
004018D5   |59              POP ECX
004018D6   |8BF8            MOV EDI,EAX
004018D8   \FF35 10914100   PUSH DWORD PTR DS:[419110]
004018DE    57              PUSH EDI
004018DF    56              PUSH ESI
004018E0    E8 24010000     CALL dumped_.00401A09
004018E5    FF35 10914100   PUSH DWORD PTR DS:[419110]
004018EB    57              PUSH EDI
004018EC    E8 E3030000     CALL dumped_.00401CD4
004018F1    FF35 10914100   PUSH DWORD PTR DS:[419110]
004018F7    57              PUSH EDI
004018F8    E8 0F040000     CALL dumped_.00401D0C
004018FD    8BD8            MOV EBX,EAX
004018FF    83C4 1C         ADD ESP,1C
00401902    85DB            TEST EBX,EBX
00401904    75 0E           JNZ SHORT dumped_.00401914
00401906    A1 10914100     MOV EAX,DWORD PTR DS:[419110]
0040190B    8D4428 04       LEA EAX,DWORD PTR DS:[EAX+EBP+4]
0040190F    A3 14914100     MOV DWORD PTR DS:[419114],EAX
00401914    85FF            TEST EDI,EDI
00401916    74 07           JE SHORT dumped_.0040191F
00401918    57              PUSH EDI
00401919    E8 FF5E0000     CALL dumped_.0040781D
0040191E    59              POP ECX
0040191F    56              PUSH ESI
00401920    E8 28010000     CALL dumped_.00401A4D
00401925    59              POP ECX
00401926    5D              POP EBP
00401927    5F              POP EDI
00401928    8BC3            MOV EAX,EBX
0040192A    5E              POP ESI
0040192B    5B              POP EBX
0040192C    C3              RETN



那麼004018A7處到底該不該跳?跟蹤原程式後發現也是不跳的。原程式經過0040189D處的CALL後EAX=95000。那95000又是什麼呢?經過跟蹤原程式發現,原來95000是檔案偏移地址,那裡有資料“000011BA”。看看原來95000處的資料:

Offset     0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00095000   BA 11 00 00 DC ED BD A9  B2 46 A9 79 48 86 9F 50   ?..茼僵FyHP
00095010   84 60 19 91 58 D9 31 A8  13 F3 B5 A2 C4 C3 D4 E5   `.X??蟮⒛迷?

00095020   CB 9D FF DC FE EF 8F 5B  4B 44 03 32 17 04 C7 83   滎[KD.2..
00095030   03 82 62 48 28 A8 C8 13  55 A4 E3 92 B7 65 A6 22   .bH(ㄈ.Uゃe?
00095040   A2 82 F3 44 03 32 17 A3  A4 DA EC EE ED EF 1E 9E   D.2.¥陟銬??

00095050   6A B4 43 DB DA 83 13 8A  8B 22 25 54 A5 95 F2 03   jC圳?"%T?
00095060   33 28 48 08 68 C4 16 C3  B6 C3 17 A4 C5 F4 72 32   3(H.h?枚?づr2
00095070   C6 92 C2 25 33 82 C6 34  24 64 23 D3 F6 43 17 83   ?34$d#遇C.
........


再看看脫殼後檔案的偏移EOFBA處:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

000E0FB0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000E0FC0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000E0FD0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000E0FE0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000E0FF0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000E1000   00 00 00 00 00 00 00 00  00 00 00 00 A0 10 0E 00   ............?..
000E1010   00 40 01 00 00 00 00 00  00 00 00 00 00 00 00 00   .@..............
000E1020   E0 10 0E 00 10 40 01 00  00 00 00 00 00 00 00 00   ?...@..........
000E1030   00 00 00 00 04 11 0E 00  18 40 01 00 00 00 00 00   .........@......
000E1040   00 00 00 00 00 00 00 00  5A 12 0E 00 6C 40 01 00   ........Z...l@..
000E1050   00 00 00 00 00 00 00 00  00 00 00 00 58 19 0E 00   ............X...
000E1060   04 42 01 00 00 00 00 00  00 00 00 00 00 00 00 00   .B..............
000E1070   84 19 0E 00 14 42 01 00  00 00 00 00 00 00 00 00   ?...B..........
000E1080   00 00 00 00 D8 19 0E 00  28 42 01 00 00 00 00 00   ....?..(B......
000E1090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

根本沒有這些資料。再搜尋“000011BA”,也搜尋不到,看來這些資料在脫殼時丟失了。現在得想加法補回去。

從原程式檔案的偏移95000處到檔案末尾複製後貼上到脫殼後的檔案末尾。我這裡的起始地址是50D50。執行後程式還是提示原來的錯誤。什麼原因?原來程式還是從偏移EOFBA處查詢“000011BA”,當然找不到。好,現在得讓程式從50D50處查詢。我是直接修改:

0040189D    E8 6A030000     CALL dumped_.00401C0C====>這個CALL是返回查詢地址的,我直接改為MOV EAX,50D50 位元組剛好。
004018A2    8BE8            MOV EBP,EAX

儲存程式,執行OK。

相關文章