• 标 题:Acprotect之完美卸载XP V9.15脱壳修复 (狗尾续貂)
  • 作 者:simonzh2000
  • 时 间:2004年2月24日 08:13
  • 链 接:http://bbs.pediy.com

感谢 DFCG 和 看雪 的大侠.
我在春节前还是一个脱壳菜鸟,
连 UPX 的手动脱壳也不会.
春节的时候我看了DFCG的 13 章手动脱壳入门
11章手动脱壳提高, 总算有点进步了.

谢谢David大侠的貂:
http://bbs2.pediy.com/viewtopic.php?t=4448

// 用 OD 跟踪脱壳后OEP=432D4的程序, 执行到 443399 时出错

00443389    FF15 88874400   CALL DWORD PTR DS:[<&msvcrt.__getmainargs>]     ; MSVCRT.__getmainargs
0044338F    68 80404500     PUSH net.00454080                               ; // End Address
00443394    68 00404500     PUSH net.00454000                               ; // Start Address
00443399    E8 DC000000     CALL <JMP.&msvcrt._initterm>                    ; // 解密代码


// F7 跟进去看看, 注意 454000,454080 这两个参数
// d 454000
// 原来都是函数入口

00454000  00 00 00 00 51 41 44 00 10 11 40 00 60 11 40 00  ....QAD.@.`@.
00454010  E0 12 40 00 10 14 40 00 70 93 40 00 C0 93 40 00  ?@.@.p揁.罁@.
00454020  10 94 40 00 60 94 40 00 00 D0 40 00 30 19 41 00  擛.`擛..蠤.0A.
00454030  70 19 41 00 F0 1F 41 00 30 20 41 00 70 20 41 00  pA.?A.0 A.p A.
00454040  B0 20 41 00 F0 20 41 00 30 21 41 00 70 21 41 00  ?A.?A.0!A.p!A.
00454050  20 22 41 00 50 B8 41 00 D0 C7 41 00 F0 C7 41 00   "A.P窤.星A.鹎A.
00454060  10 C8 41 00 30 C8 41 00 50 C8 41 00 70 C8 41 00  華.0華.P華.p華.
00454070  90 C8 41 00 F0 2F 42 00 36 30 42 00 6B 72 42 00  惾A.?B.60B.krB.
00454080  00 00 00 00


//msvcrt._initterm

7800119B >  56              PUSH ESI
7800119C    8B7424 08       MOV ESI,DWORD PTR SS:[ESP+8]                    ; // 取出 454000
780011A0    EB 03           JMP SHORT MSVCRT.780011A5
780011A2    83C6 04         ADD ESI,4                                       ; // 下一个
780011A5    3B7424 0C       CMP ESI,DWORD PTR SS:[ESP+C]                    ; // >454080 吗?
780011A9    73 0A           JNB SHORT MSVCRT.780011B5                       ; // 是则结束
780011AB    8B06            MOV EAX,DWORD PTR DS:[ESI]                      ; // 取出一个函数入口
780011AD    85C0            TEST EAX,EAX
780011AF  ^ 74 F1           JE SHORT MSVCRT.780011A2
780011B1    FFD0            CALL EAX                                        ; // 执行用户的函数
780011B3  ^ EB ED           JMP SHORT MSVCRT.780011A2
780011B5    5E              POP ESI
780011B6    C3              RETN

// bp 780011B1, F9 运行
// 当 EAX = 00423036 时出错
// 从新来过
 
// bp 00423036, F9 断下,
// 接下来一大段花指令, SMC, 注意循环,
// 用户指令 F7 过, 系统函数 F8 过, 循环 F4 过

00423036    E8 05000000     CALL net.00423040
0042303B    E9 18000000     JMP net.00423058
00423040    55              PUSH EBP
00423041    8BEC            MOV EBP,ESP
00423043    51              PUSH ECX
00423044    8D45 FF         LEA EAX,DWORD PTR SS:[EBP-1]
00423047    B9 00834500     MOV ECX,net.00458300
.
.
.
.
00423A9A    E8 47F10100     CALL <JMP.&mfc42.#823_??2@YAPAXI@Z>
00423A9F    8970 04         MOV DWORD PTR DS:[EAX+4],ESI
00423AA2    8958 14         MOV DWORD PTR DS:[EAX+14],EBX
00423AA5    8947 04         MOV DWORD PTR DS:[EDI+4],EAX
00423AA8    E8 30B60800     CALL net.004AF0DD                               ; // Call 004AF0DD, F7跟进
00423AAD    8B47 04         MOV EAX,DWORD PTR DS:[EDI+4]                    ; // 返回到 00423AAD, 下面有用
.
.
.
.
004AF0DD    
.
.
004AF25E   /E9 0B000000     JMP net.004AF26E
004AF263   |79 03           JNS SHORT net.004AF268
004AF265   |66:D3EA         SHR DX,CL
004AF268   |81F5 5D54168F   XOR EBP,8F16545D
004AF26E   4B              DEC EBX
004AF26F  ^ 0F85 7FFFFFFF   JNZ net.004AF1F4                                ; // 一个望回跳的循环
004AF275    50              PUSH EAX                                        ; // F4 到这里
004AF27D    58              POP EAX                                         ; net.004AF348
004AF27E    E9 05000000     JMP net.004AF288
004AF283    4A              DEC EDX
004AF284    76 02           JBE SHORT net.004AF288
004AF286    13D7            ADC EDX,EDI
004AF288    E8 7EBE0000     CALL net.004BB10B                               ; // F8 过
004AF28D    8B4424 20       MOV EAX,DWORD PTR SS:[ESP+20]                   ; // EAX = 00423AAD, 返回地址
004AF291    33C9            XOR ECX,ECX
004AF293    8B9C8D 8D234000 MOV EBX,DWORD PTR SS:[EBP+ECX*4+40238D]         ; // 4AF38D 开始放返回地址的RVA
004AF29A    039D 55CF4000   ADD EBX,DWORD PTR SS:[EBP+40CF55]               ; // RVA + 400000
004AF2A0    3BC3            CMP EAX,EBX
004AF2A2    74 07           JE SHORT net.004AF2AB
004AF2A4    90              NOP
004AF2A5    90              NOP
004AF2A6    90              NOP
004AF2A7    90              NOP
004AF2A8    41              INC ECX                                         ; // 不匹配, 下一个
004AF2A9  ^ EB E8           JMP SHORT net.004AF293
004AF2AB    C7848D 8D234000>MOV DWORD PTR SS:[EBP+ECX*4+40238D],0           ; // 找到了, ECX=49
004AF2B6    8DB5 6D524000   LEA ESI,DWORD PTR SS:[EBP+40526D]               ; // 4B226D 放加密后的代码
004AF2BC    B8 0A000000     MOV EAX,0A                                      ; // 加密代码 10 字节一段
004AF2C1    F7E1            MUL ECX
004AF2C3    03F0            ADD ESI,EAX                                     ; // 对应该返回地址的加密代码
004AF2C5    51              PUSH ECX
004AF2C6    56              PUSH ESI              ; // ESI=4B226D+A*49=4B2547
004AF2C7    8A85 CD204000   MOV AL,BYTE PTR SS:[EBP+4020CD]
004AF2CD    0AC0            OR AL,AL
004AF2CF    75 28           JNZ SHORT net.004AF2F9
004AF2D1    90              NOP
004AF2D2    90              NOP
004AF2D3    90              NOP
004AF2D4    90              NOP
004AF2D5    8B85 55CF4000   MOV EAX,DWORD PTR SS:[EBP+40CF55]               ; // 400000
004AF2DB    8B70 3C         MOV ESI,DWORD PTR DS:[EAX+3C]                   ; // 40003C, PE头
004AF2DE    03B5 55CF4000   ADD ESI,DWORD PTR SS:[EBP+40CF55]               ; // 400100
004AF2E4    83C6 28         ADD ESI,28                                      ; // 400128, OEP
004AF2E7    AD              LODS DWORD PTR DS:[ESI]                         ; // OEP值
004AF2E8    8AD8            MOV BL,AL
004AF2EA    02DC            ADD BL,AH
004AF2EC    C1E8 10         SHR EAX,10
004AF2EF    02D8            ADD BL,AL
004AF2F1    02DC            ADD BL,AH                                       ; // OEP 四字节相加
004AF2F3    889D CD204000   MOV BYTE PTR SS:[EBP+4020CD],BL                 ; // 放到 4AF0CD
004AF2F9    8A9D CD204000   MOV BL,BYTE PTR SS:[EBP+4020CD]                 ; // 也到 BL
004AF2FF    B9 0A000000     MOV ECX,0A
004AF304    5E              POP ESI
004AF305    8BFE            MOV EDI,ESI
004AF307    AC              LODS BYTE PTR DS:[ESI]
004AF308    32C3            XOR AL,BL                                       ; // 加密代码 XOR BL
004AF30A    AA              STOS BYTE PTR ES:[EDI]                          ; // 得到明码
004AF30B  ^ E2 FA           LOOPD SHORT net.004AF307
004AF30D    83EE 0A         SUB ESI,0A
004AF310    59              POP ECX
004AF311    56              PUSH ESI
004AF312    8B7424 24       MOV ESI,DWORD PTR SS:[ESP+24]
004AF316    83EE 04         SUB ESI,4
004AF319    AD              LODS DWORD PTR DS:[ESI]                         ; // 423AA8处函数入口 4AF0DD
004AF31A    50              PUSH EAX
004AF31B    BB 6D524000     MOV EBX,net.0040526D
004AF320    81EB DD204000   SUB EBX,net.004020DD
004AF326    B8 0A000000     MOV EAX,0A
004AF32B    F7E1            MUL ECX
004AF32D    03D8            ADD EBX,EAX
004AF32F    58              POP EAX
004AF330    03C3            ADD EAX,EBX
004AF332    8946 FC         MOV DWORD PTR DS:[ESI-4],EAX                    ; // 修改423AA8 处函数入口为 4B2547
004AF335    5E              POP ESI                                         ; net.004B2547
004AF356    83EE 06         SUB ESI,6
.
.
// 调整Stack
// SMC
.
.
004AF38A    61              POPAD
004AF38B    61              POPAD
004AF38C    C3              RETN              ; // 返回到4B2547执行

// 从上面的过程可以看到, 如果OEP变了, 那么加密代码解密出来就不对