【目 标】: 应作者要求,这里不贴上软件名
【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任 务】:分析外壳
【操作平台】:Windows 2003 server
【作 者】: LOVEBOOM[DFCG][FCG][US]
【相关链接】: ......
【简要说明】: 脱ACPROTECT的壳并不多,以前最多只是大概的脱一下,对壳有流程并没有多少认识,前几天帮朋友了一下这个软件,也许
是我水平太菜了,也许是脱这个东西脱的比较少,在脱这个软件花了我很多时间,搞的过程中还很容易出小问题。还有一个原因是脱了一下新
版的ASPR 2.X stolen code让我看到头疼,虽然坚持了,但现在还有一小部分没有解决:-(。没办法两个都壳都是难搞的,本着看aspr的东西稍
微多了点,因此牺牲了睡觉时间,帮自己补了下课。壳的思路比较新,边执行边解壳,解压一段执行后又还原回去,代码替换,EMBEDD protect
等等。这么有吸引力,当然不要错过了。因为我对RSA无KEY怎么突破之类的没有一点了解,再者也没有见过软件用RSA lock code.,所以这次没
有分析KEY相关的东西。我这次和以前的文章有点不同,这次为了更细的分析出壳的各模块功能,把相关的模块放在独立的地方,也不像以前那
样,插来插去的。不是很方便自己查看。也很久没有细细的去品尝壳了。也是该“享受”一下。
【详细过程】:
写在前面的,你只是想知道怎么脱壳的话,那么这你可跳过这一章节,这一章节是分析壳的每个部分,是比较漫长的。如果你完全分析好了,
后面脱就简单了。
由于是一步一步的走,所以不用什么特别的设置了。唯一一点就是要很磨得下去。打开OD,忽略全部异常。准备眼睛再度近视几度。
泡上一杯水,然后开始这次的旅程:
为了防止壳的检测,这次我没有去除花指令直接动态跟踪分析了下。
0057C000 > 60 PUSHAD ; EP
0057C001 E8 01000000 CALL 0057C007 ; 程序一开始就反复解壳代码
0057C006 - 72 83 JB SHORT 0057BF8B
0057C008 04 24 ADD AL,24
0057C00A 06 PUSH ES
0057C00B C3 RETN
0057C00C 85C3 TEST EBX,EAX
0057C00E 76 01 JBE SHORT 0057C011
0057C010 4B DEC EBX
0057C011 87D8 XCHG EAX,EBX
0057C013 E8 01000000 CALL 0057C019
0057C018 - 76 83 JBE SHORT 0057BF9D
......
0057C204 64:FF30 PUSH DWORD PTR FS:[EAX]
0057C207 64:8920 MOV DWORD PTR FS:[EAX],ESP
0057C20A CC INT3
0057C20B 90 NOP
0057C20C F8 CLC
0057C20D 90 NOP
0057C20E FC CLD
......
0057C29F 64:8F05 0000000>POP DWORD PTR FS:[0] ; 直接F2,然后执行到这里,
0057C2A6 83C4 04 ADD ESP,4
0057C2A9 7C 03 JL SHORT 0057C2AE ; 这里是开始还原的地址
0057C2AB 7D 01 JGE SHORT 0057C2AE
......
0057C436 4A DEC EDX
0057C437 ^ 0F85 7FFFFFFF JNZ 0057C3BC ; 没有解压完则跳回继续解压
0057C43D EB 01 JMP SHORT 0057C440
壳一开始就通过几个异常来循环解压出壳的代码。解压的方法很简单的:
MOV EBX,DWORD PTR DS:[EAX]
XOR EBX,EDI
ROR EBX,1F
ADD EAX,4
XOR EBX,DWORD PTR DS:[EAX]
ADD EAX,-4
MOV DWORD PTR DS:[EAX],EBX
XOR EDI,45BA1300
继续:
......
0057C7F8 64:8F05 0000000>POP DWORD PTR FS:[0] ; 0012FFE0
0057C7FF 83C4 04 ADD ESP,4
0057C802 E9 BB4A0100 JMP 005912C2 ; 全部解压完了跳去执行壳的代码
......
005912C2 E8 39AEFFFF CALL <sub_GetEBP > ; jmp到这里
005912C7 E8 00000000 CALL 005912CC
005912CC 5B POP EBX
005912CD 2B9D 0E204000 SUB EBX,DWORD PTR SS:[EBP+40200E] ; 计算IMAGEBASE
005912D3 81EB CC520100 SUB EBX,152CC
005912D9 899D 46F84000 MOV DWORD PTR SS:[EBP+40F846],EBX ; 计算出的IMAGEBASE保存到 [EBP+40F846]=[0058A846]=400000
005912DF 899D 7BFD4000 MOV DWORD PTR SS:[EBP+40FD7B],EBX ; 计算出的IMAGEBASE保存到 [EBP+40FD7B]=[0058AD7B]==400000
005912E5 E8 C6FDFFFF CALL <sub_GetEP_CRYPT_KEY>
005912EA E8 11AEFFFF CALL <sub_GetEBP >
005912EF E8 DAA5FFFF CALL <Get_RND_VALUE>
005912F4 8985 D5084100 MOV DWORD PTR SS:[EBP+4108D5],EAX
005912FA E8 01AEFFFF CALL <sub_GetEBP > 005912FF C685 6CF74000 0>MOV BYTE PTR SS:[EBP+40F76C],0 ; 刚开始就设置为没有注册的标志
00591306 E8 F0D2FFFF CALL <sub_GETAPIAddress> ; 获取壳要用的API
0059130B E8 38F9FFFF CALL <COPY_Import table> ; 填充跳转表
00591310 E8 EBADFFFF CALL <sub_GetEBP > 00591315 8B85 6B814100 MOV EAX,DWORD PTR SS:[EBP+41816B]
0059131B 8985 7FFD4000 MOV DWORD PTR SS:[EBP+40FD7F],EAX
00591321 8B85 6F814100 MOV EAX,DWORD PTR SS:[EBP+41816F]
00591327 8985 83FD4000 MOV DWORD PTR SS:[EBP+40FD83],EAX
0059132D E8 66D0FFFF CALL <UnPack_sections> ; 解压程序各段
00591332 E8 1FFBFFFF CALL <Restore_JMP API TABLE> ; 还原壳的跳转表
00591337 E8 2EFDFFFF CALL <sub_SDK_Disposal> ; 处理用到SDK的地址代码
0059133C 43 INC EBX
0059133D 85F3 TEST EBX,ESI
0059133F 87D9 XCHG ECX,EBX
00591341 E8 01000000 CALL 00591347 ; 开始解压出下一段要执行的代码。
00591346 EA 83C4047D 028>JMP FAR 8502:7D04C483 ; Far jump
......
下面的代码就开始边走边解壳了:
......
0059142A E8 EF000000 CALL 0059151E
0059142F E8 04000000 CALL 00591438
00591434 0000 ADD BYTE PTR DS:[EAX],AL
00591436 0000 ADD BYTE PTR DS:[EAX],AL
00591438 5A POP EDX
00591439 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
0059143D 8B00 MOV EAX,DWORD PTR DS:[EAX]
0059143F 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
00591443 FF81 B8000000 INC DWORD PTR DS:[ECX+B8]
00591449 3D 03000080 CMP EAX,80000003
0059144E 75 4D JNZ SHORT 0059149D
00591450 8D82 02114000 LEA EAX,DWORD PTR DS:[EDX+401102]
00591456 2D 0E104000 SUB EAX,0040100E
0059145B 8941 04 MOV DWORD PTR DS:[ECX+4],EAX
0059145E 8D82 04114000 LEA EAX,DWORD PTR DS:[EDX+401104]
00591464 2D 0E104000 SUB EAX,0040100E
00591469 8941 08 MOV DWORD PTR DS:[ECX+8],EAX
0059146C 8D82 06114000 LEA EAX,DWORD PTR DS:[EDX+401106]
00591472 2D 0E104000 SUB EAX,0040100E
00591477 8941 0C MOV DWORD PTR DS:[ECX+C],EAX
0059147A 8D82 08114000 LEA EAX,DWORD PTR DS:[EDX+401108]
00591480 2D 0E104000 SUB EAX,0040100E
00591485 8941 10 MOV DWORD PTR DS:[ECX+10],EAX
00591488 33C0 XOR EAX,EAX
0059148A 8161 14 F00FFFF>AND DWORD PTR DS:[ECX+14],FFFF0FF0
00591491 C741 18 5501000>MOV DWORD PTR DS:[ECX+18],155
00591498 E9 80000000 JMP 0059151D
0059149D 3D 940000C0 CMP EAX,C0000094
005914A2 75 2A JNZ SHORT 005914CE
005914A4 C702 00000000 MOV DWORD PTR DS:[EDX],0
005914AA FF81 B8000000 INC DWORD PTR DS:[ECX+B8]
005914B0 33C0 XOR EAX,EAX
005914B2 2141 04 AND DWORD PTR DS:[ECX+4],EAX
005914B5 2141 08 AND DWORD PTR DS:[ECX+8],EAX
005914B8 2141 0C AND DWORD PTR DS:[ECX+C],EAX
005914BB 2141 10 AND DWORD PTR DS:[ECX+10],EAX
005914BE 8161 14 F00FFFF>AND DWORD PTR DS:[ECX+14],FFFF0FF0
005914C5 8161 18 00DC000>AND DWORD PTR DS:[ECX+18],0DC00
005914CC EB 4F JMP SHORT 0059151D
005914CE 3D 04000080 CMP EAX,80000004
......
0059160E 830424 06 ADD DWORD PTR SS:[ESP],6
00591612 C3 RETN
00591613 E8 A7B9FFFF CALL <sub_UnKnow>
00591618 E9 0B000000 JMP 00591628
......
005917E0 56 PUSH ESI
005917E1 8F05 DDCA5700 POP DWORD PTR DS:[57CADD]
005917E7 FF35 DDCA5700 PUSH DWORD PTR DS:[57CADD]
005917ED 56 PUSH ESI
005917EE C70424 05C95700 MOV DWORD PTR SS:[ESP],0057C905
005917F5 8F05 0DCA5700 POP DWORD PTR DS:[57CA0D]
005917FB 8B35 0DCA5700 MOV ESI,DWORD PTR DS:[57CA0D]
00591801 891E MOV DWORD PTR DS:[ESI],EBX
00591803 8F05 1DC95700 POP DWORD PTR DS:[57C91D]
00591809 FF35 1DC95700 PUSH DWORD PTR DS:[57C91D]
0059180F 5E POP ESI
00591810 FF35 05C95700 PUSH DWORD PTR DS:[57C905] ; 开始边走边唱了
00591816 892C24 MOV DWORD PTR SS:[ESP],EBP ; push ebp,这里开始执行了程序前面的代码
00591819 8925 99C85700 MOV DWORD PTR DS:[57C899],ESP
0059181F FF35 99C85700 PUSH DWORD PTR DS:[57C899]
00591825 8B2C24 MOV EBP,DWORD PTR SS:[ESP] ; mov ebp,esp
00591828 8F05 39C85700 POP DWORD PTR DS:[57C839]
0059182E 56 PUSH ESI
找Stolen Code比较简单,后面的代码我并没有注释下来。
......
00591953 83C4 04 ADD ESP,4
00591956 58 POP EAX
00591957 76 01 JBE SHORT 0059195A
00591959 48 DEC EAX
0059195A 03DA ADD EBX,EDX
0059195C 50 PUSH EAX
0059195D E8 01000000 CALL 00591963
00591962 ^ 7C 83 JL SHORT 005918E7
00591964 C40458 LES EAX,FWORD PTR DS:[EAX+EBX*2] ; Modification of segment register
00591967 E8 CDD3FFFF CALL <sub_Kernel> ; 这个call里面的东西应该是壳的核心了:-)
0059196C E9 06000000 JMP 00591977
很多解码之类的,跟踪时要小心点。
......
0059198D /76 7B JBE SHORT 00591A0A
0059198F |0366 8B ADD ESP,DWORD PTR DS:[ESI-75]
00591992 |C6 ??? ; Unknown command
00591993 |8919 MOV DWORD PTR DS:[ECX],EBX
00591995 |EB 01 JMP SHORT 00591998
00591997 |90 NOP
00591998 |E8 08E9FFFF CALL <Sub_Disposal IAT> ; 其实这里CALL的时候,前面的call kernel里已经处理过了,这里进去只是一个ret而已
0059199D |E9 05000000 JMP 005919A7
005919A2 |B8 0DB7D4E5 MOV EAX,E5D4B70D
005919A7 |81EA AE3A7D06 SUB EDX,67D3AAE
......
005919D0 /0F81 02000000 JNO 005919D8
005919D6 |87FD XCHG EBP,EDI
005919D8 \83C6 FF ADD ESI,-1
005919DB ^ 0F85 69FFFFFF JNZ 0059194A ; 循环解出后面的代码
005919E1 EB 01 JMP SHORT 005919E4
005919E3 ^ 76 E8 JBE SHORT 005919CD
005919E5 03C0 ADD EAX,EAX
005919E7 FFFF ??? ; Unknown command
005919E9 0F8C 02000000 JL 005919F1
005919EF 87E8 XCHG EAX,EBP
005919F1 B8 64000000 MOV EAX,64
005919F6 33D2 XOR EDX,EDX
005919F8 33DB XOR EBX,EBX
005919FA F7F3 DIV EBX ; 异常
005919FC 90 NOP
005919FD 64:8F05 0000000>POP DWORD PTR FS:[0]
00591A04 83C4 04 ADD ESP,4
00591A07 61 POPAD ;边执行程序的代码边解壳代码
00591A08 893C24 MOV DWORD PTR SS:[ESP],EDI
00591A0B C705 21CA5700 C>MOV DWORD PTR DS:[57CA21],0057C9C5
00591A15 8B3D 21CA5700 MOV EDI,DWORD PTR DS:[57CA21] ; MainCon.0057C9C5
00591A1B 891F MOV DWORD PTR DS:[EDI],EBX
00591A1D 8B3C24 MOV EDI,DWORD PTR SS:[ESP]
00591A20 8F05 79C85700 POP DWORD PTR DS:[57C879]
00591A26 FF35 C5C95700 PUSH DWORD PTR DS:[57C9C5]
00591A2C 891424 MOV DWORD PTR SS:[ESP],EDX
00591A2F C70424 FFFFFFFF MOV DWORD PTR SS:[ESP],-1 ; push -1 *********
00591A36 53 PUSH EBX
00591A37 8F05 2DCB5700 POP DWORD PTR DS:[57CB2D]
00591A3D FF35 2DCB5700 PUSH DWORD PTR DS:[57CB2D]
00591A43 890424 MOV DWORD PTR SS:[ESP],EAX
00591A46 891C24 MOV DWORD PTR SS:[ESP],EBX
00591A49 C70424 609F4B00 MOV DWORD PTR SS:[ESP],004B9F60 ; push 4b9f60 ***********
00591A50 53 PUSH EBX
00591A51 890424 MOV DWORD PTR SS:[ESP],EAX
00591A54 891424 MOV DWORD PTR SS:[ESP],EDX
00591A57 57 PUSH EDI
00591A58 60 PUSHAD
......
00591C1B 61 POPAD
00591C1C C70424 89C85700 MOV DWORD PTR SS:[ESP],0057C889
00591C23 8F05 01CB5700 POP DWORD PTR DS:[57CB01]
00591C29 8B15 01CB5700 MOV EDX,DWORD PTR DS:[57CB01]
00591C2F 890A MOV DWORD PTR DS:[EDX],ECX
00591C31 8F05 A5C95700 POP DWORD PTR DS:[57C9A5]
00591C37 FF35 A5C95700 PUSH DWORD PTR DS:[57C9A5]
00591C3D 5A POP EDX
00591C3E FF35 89C85700 PUSH DWORD PTR DS:[57C889]
00591C44 C70424 602F4B00 MOV DWORD PTR SS:[ESP],004B2F60 ; PUSH 4B2F60 *********
00591C4B 64:A1 00000000 MOV EAX,DWORD PTR FS:[0] ; MOV EAX,DWORD PTR FS:[0] **************
00591C51 56 PUSH ESI
00591C52 8F05 A9C85700 POP DWORD PTR DS:[57C8A9]
00591C58 FF35 A9C85700 PUSH DWORD PTR DS:[57C8A9]
00591C5E 891C24 MOV DWORD PTR SS:[ESP],EBX
00591C61 8935 91C85700 MOV DWORD PTR DS:[57C891],ESI
00591C67 90 NOP
00591C68 90 NOP
00591C69 60 PUSHAD
......
00591E1B F7F3 DIV EBX ; 除0异常
00591E1D 90 NOP
00591E1E 64:8F05 0000000>POP DWORD PTR FS:[0]
00591E25 83C4 04 ADD ESP,4
00591E28 61 POPAD
00591E29 FF35 91C85700 PUSH DWORD PTR DS:[57C891]
00591E2F C70424 A1CA5700 MOV DWORD PTR SS:[ESP],0057CAA1
00591E36 8F05 69C95700 POP DWORD PTR DS:[57C969]
00591E3C FF35 69C95700 PUSH DWORD PTR DS:[57C969]
00591E42 5B POP EBX
00591E43 8903 MOV DWORD PTR DS:[EBX],EAX
00591E45 8B1C24 MOV EBX,DWORD PTR SS:[ESP]
00591E48 8F05 B1CA5700 POP DWORD PTR DS:[57CAB1]
00591E4E FF35 A1CA5700 PUSH DWORD PTR DS:[57CAA1] ; PUSH EAX ************
00591E54 64:8925 0000000>MOV DWORD PTR FS:[0],ESP ; MOV DWORD PTR FS:[0],ESP ********
00591E5B 83EC 68 SUB ESP,68 ; ***************
00591E5E 56 PUSH ESI
00591E5F 8F05 D9CA5700 POP DWORD PTR DS:[57CAD9]
00591E65 FF35 D9CA5700 PUSH DWORD PTR DS:[57CAD9]
00591E6B 891C24 MOV DWORD PTR SS:[ESP],EBX
00591E6E 8F05 E5CA5700 POP DWORD PTR DS:[57CAE5]
00591E74 90 NOP
00591E75 90 NOP
00591E76 60 PUSHAD
......
00591FBB 83EA FC SUB EDX,-4
00591FBE 2B02 SUB EAX,DWORD PTR DS:[EDX]
00591FC0 83C2 FC ADD EDX,-4
00591FC3 E8 01000000 CALL 00591FC9 ; 这里不能像前面那样找到jnz xxx然后就在下面一行下断 的方式,那样类似这样东西就会不放过了:-)
00591FC8 90 NOP
00591FC9 83C4 04 ADD ESP,4
00591FCC E8 7FACFFFF CALL <sub_chekRing0's Debug> ; 检测系统级调试器
00591FD1 BF C64E0B93 MOV EDI,930B4EC6
00591FD6 66:8BFA MOV DI,DX
00591FD9 8902 MOV DWORD PTR DS:[EDX],EAX
00591FDB E8 01000000 CALL 00591FE1
00591FE0 ^ 74 83 JE SHORT 00591F65
00591FE2 C4041B LES EAX,FWORD PTR DS:[EBX+EBX] ; Modification of segment register
00591FE5 F785 FB81EDA1 8>TEST DWORD PTR SS:[EBP+A1ED81FB],78BBFB8>
00591FEF 0379 01 ADD EDI,DWORD PTR DS:[ECX+1]
00591FF2 7A E9 JPE SHORT 00591FDD
00591FF4 05 000000D3 ADD EAX,D3000000
00591FF9 D3C1 ROL ECX,CL
00591FFB C6 ??? ; Unknown command
00591FFC ^ 73 81 JNB SHORT 00591F7F
00591FFE C2 0400 RETN 4
00592001 0000 ADD BYTE PTR DS:[EAX],AL
00592003 50 PUSH EAX
00592004 E8 01000000 CALL 0059200A
00592009 ^ 7E 83 JLE SHORT 00591F8E
0059200B C40458 LES EAX,FWORD PTR DS:[EAX+EBX*2] ; Modification of segment register
0059200E 43 INC EBX
0059200F 0F81 03000000 JNO 00592018
00592015 66:8BF0 MOV SI,AX
00592018 83C1 FF ADD ECX,-1
0059201B ^ 0F85 70FFFFFF JNZ 00591F91 ; 循环解压代码
00592021 E8 01000000 CALL 00592027
00592026 ^ EB 83 JMP SHORT 00591FAB
00592028 C404E8 LES EAX,FWORD PTR DS:[EAX+EBP*8] ; Modification of segment register
0059202B 0ACD OR CL,CH
......
0059203E F7F3 DIV EBX
00592040 90 NOP
00592041 64:8F05 0000000>POP DWORD PTR FS:[0] ; 好多个这个结构的
00592048 83C4 04 ADD ESP,4
0059204B 61 POPAD
0059204C FF35 E5CA5700 PUSH DWORD PTR DS:[57CAE5]
00592052 8915 D1C95700 MOV DWORD PTR DS:[57C9D1],EDX
00592058 FF35 D1C95700 PUSH DWORD PTR DS:[57C9D1]
0059205E 53 PUSH EBX
0059205F BB B1C85700 MOV EBX,0057C8B1
00592064 8BD3 MOV EDX,EBX
00592066 5B POP EBX
00592067 8932 MOV DWORD PTR DS:[EDX],ESI
00592069 8F05 F5C85700 POP DWORD PTR DS:[57C8F5]
0059206F 8B15 F5C85700 MOV EDX,DWORD PTR DS:[57C8F5]
00592075 FF35 B1C85700 PUSH DWORD PTR DS:[57C8B1]
0059207B 8F05 FDC85700 POP DWORD PTR DS:[57C8FD]
00592081 FF35 FDC85700 PUSH DWORD PTR DS:[57C8FD]
00592087 52 PUSH EDX
00592088 8F05 19C95700 POP DWORD PTR DS:[57C919]
0059208E FF35 19C95700 PUSH DWORD PTR DS:[57C919]
00592094 893424 MOV DWORD PTR SS:[ESP],ESI
00592097 57 PUSH EDI
00592099 90 NOP
0059209A 60 PUSHAD
......
00592260 83C4 04 ADD ESP,4
00592263 61 POPAD
00592264 BF 1DCA5700 MOV EDI,0057CA1D
00592269 890F MOV DWORD PTR DS:[EDI],ECX
0059226B 5F POP EDI
0059226C FF35 1DCA5700 PUSH DWORD PTR DS:[57CA1D]
00592272 891D B1C95700 MOV DWORD PTR DS:[57C9B1],EBX
00592278 FF35 B1C95700 PUSH DWORD PTR DS:[57C9B1]
0059227E 51 PUSH ECX
0059227F B9 D1C85700 MOV ECX,0057C8D1
00592284 8BD9 MOV EBX,ECX
00592286 59 POP ECX
00592287 53 PUSH EBX
00592288 59 POP ECX
00592289 8F05 69C85700 POP DWORD PTR DS:[57C869]
0059228F 8B1D 69C85700 MOV EBX,DWORD PTR DS:[57C869]
00592295 890D 99C95700 MOV DWORD PTR DS:[57C999],ECX
0059229B FF35 99C95700 PUSH DWORD PTR DS:[57C999] ; MainCon.0057C8D1
005922A1 8F05 F5C95700 POP DWORD PTR DS:[57C9F5] ; MainCon.0057C8D1
005922A7 8B35 F5C95700 MOV ESI,DWORD PTR DS:[57C9F5] ; MainCon.0057C8D1
005922AD 8F05 49C85700 POP DWORD PTR DS:[57C849]
005922B3 56 PUSH ESI ; MainCon.0057C8D1
005922B4 60 PUSHAD
005922B5 E8 01000000 CALL 005922BB
......
005923FB 830424 06 ADD DWORD PTR SS:[ESP],6
005923FF C3 RETN
00592400 E9 02000000 JMP 00592407
00592405 87CB XCHG EBX,ECX
00592407 83EA FC SUB EDX,-4
0059240A 2B32 SUB ESI,DWORD PTR DS:[EDX]
0059240C 83C2 FC ADD EDX,-4
0059240F EB 01 JMP SHORT 00592412 ; 这里也暗蔵杀机哦:-)
00592411 90 NOP
00592412 E8 21B8FFFF CALL<chek IsDebuggerPresent> ; 再次检测有没有Ring 3级调试器
00592417 78 01 JS SHORT 0059241A
00592419 F9 STC
......
00592462 33DB XOR EBX,EBX
00592464 F7F3 DIV EBX
00592466 90 NOP
00592467 64:8F05 0000000>POP DWORD PTR FS:[0] ; SEH用来反调试同时也给我们指引了一条道路
0059246E 83C4 04 ADD ESP,4
00592471 61 POPAD
00592472 BE 49C85700 MOV ESI,0057C849
00592477 8B0E MOV ECX,DWORD PTR DS:[ESI]
00592479 5E POP ESI
0059247A 893E MOV DWORD PTR DS:[ESI],EDI
0059247C 8F05 ADCA5700 POP DWORD PTR DS:[57CAAD]
00592482 893D B5C95700 MOV DWORD PTR DS:[57C9B5],EDI
00592488 FF35 B5C95700 PUSH DWORD PTR DS:[57C9B5]
0059248E 51 PUSH ECX
0059248F B9 ADCA5700 MOV ECX,0057CAAD
00592494 8BF9 MOV EDI,ECX
00592496 59 POP ECX
00592497 8B37 MOV ESI,DWORD PTR DS:[EDI]
00592499 8B3C24 MOV EDI,DWORD PTR SS:[ESP]
0059249C 8F05 35CA5700 POP DWORD PTR DS:[57CA35]
005924A2 FF35 D1C85700 PUSH DWORD PTR DS:[57C8D1]
005924A8 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP ; **********
005924AB 33DB XOR EBX,EBX
005924AD 895D FC MOV DWORD PTR SS:[EBP-4],EBX ; ************
005924B0 52 PUSH EDX
005924B1 891C24 MOV DWORD PTR SS:[ESP],EBX
005924B4 68 09CB5700 PUSH 0057CB09
005924B9 5B POP EBX
005924BA 8913 MOV DWORD PTR DS:[EBX],EDX
005924BC 8F05 E5C85700 POP DWORD PTR DS:[57C8E5]
005924C2 60 PUSHAD
005924C3 E8 01000000 CALL 005924C9
......
005924BC 8F05 E5C85700 POP DWORD PTR DS:[57C8E5]
005924C2 60 PUSHAD
005924C3 E8 01000000 CALL 005924C9
005924C8 90 NOP
005924C9 83C4 04 ADD ESP,4
005924CC E8 D4DDFFFF CALL <Sub_Disposal IAT> ; iat已经处理过了,这里再进去只是一个ret而已
005924D1 E9 0D000000 JMP 005924E3
......
0059267C F7F3 DIV EBX
0059267E 90 NOP
0059267F 64:8F05 0000000>POP DWORD PTR FS:[0]
00592686 83C4 04 ADD ESP,4 ; 异常
00592689 61 POPAD
0059268A 8B1D E5C85700 MOV EBX,DWORD PTR DS:[57C8E5]
00592690 FF35 09CB5700 PUSH DWORD PTR DS:[57CB09]
00592696 53 PUSH EBX
00592697 BB 02000000 MOV EBX,2 ; ************
0059269C 891D 19CB5700 MOV DWORD PTR DS:[57CB19],EBX
005926A2 5B POP EBX
005926A3 FF35 19CB5700 PUSH DWORD PTR DS:[57CB19]
005926A9 8F05 3DC95700 POP DWORD PTR DS:[57C93D]
005926AF 53 PUSH EBX
005926B0 BB 3DC95700 MOV EBX,0057C93D
005926B5 8B13 MOV EDX,DWORD PTR DS:[EBX]
005926B7 5B POP EBX
005926B8 57 PUSH EDI
005926B9 891C24 MOV DWORD PTR SS:[ESP],EBX
005926BC C705 F9C85700 A>MOV DWORD PTR DS:[57C8F9],0057C8A1
005926C6 8B1D F9C85700 MOV EBX,DWORD PTR DS:[57C8F9]
005926CC 8913 MOV DWORD PTR DS:[EBX],EDX
005926CE 8F05 11CB5700 POP DWORD PTR DS:[57CB11]
005926D4 8B1D 11CB5700 MOV EBX,DWORD PTR DS:[57CB11]
005926DA 60 PUSHAD
005926DB E8 01000000 CALL 005926E1
......
00592880 83EB 01 SUB EBX,1
00592883 ^ 0F85 6EFFFFFF JNZ 005927F7 ; 循环解压代码
00592889 E8 01000000 CALL 0059288F
0059288E 90 NOP
0059288F 83C4 04 ADD ESP,4
00592892 E8 0CAFFFFF CALL <Shit Int3> ; shit int 3
00592897 E9 06000000 JMP 005928A2
0059289C 66:B8 065B MOV AX,5B06
005928A0 85C6 TEST ESI,EAX
005928A2 B8 64000000 MOV EAX,64
005928A7 33D2 XOR EDX,EDX
005928A9 33DB XOR EBX,EBX
005928AB F7F3 DIV EBX
005928AD 90 NOP
005928AE 64:8F05 0000000>POP DWORD PTR FS:[0] ; 到这里就看到希望了,后面很明显的看出是程序的代码
005928B5 83C4 04 ADD ESP,4
005928B8 61 POPAD
005928B9 8B1424 MOV EDX,DWORD PTR SS:[ESP]
005928BC 8F05 F9C95700 POP DWORD PTR DS:[57C9F9]
005928C2 FF35 A1C85700 PUSH DWORD PTR DS:[57C8A1] ; ***********
005928C8 FF15 14774B00 CALL DWORD PTR DS:[4B7714] ; msvcrt.__set_app_type
005928CE 8F05 EDCA5700 POP DWORD PTR DS:[57CAED]
005928D4 FF35 EDCA5700 PUSH DWORD PTR DS:[57CAED]
005928DA 8F05 25C85700 POP DWORD PTR DS:[57C825]
005928E0 FF35 25C85700 PUSH DWORD PTR DS:[57C825]
005928E6 59 POP ECX
005928E7 830D AC464D00 F>OR DWORD PTR DS:[4D46AC],FFFFFFFF
005928EE 830D B0464D00 F>OR DWORD PTR DS:[4D46B0],FFFFFFFF
005928F5 FF15 10774B00 CALL DWORD PTR DS:[4B7710] ; msvcrt.__p__fmode
005928FB FF35 70464D00 PUSH DWORD PTR DS:[4D4670]
00592901 8F05 19CA5700 POP DWORD PTR DS:[57CA19]
00592907 90 NOP
00592908 90 NOP
00592909 60 PUSHAD
0059290A E8 01000000 CALL 00592910
......
00592ACD B8 64000000 MOV EAX,64
00592AD2 33D2 XOR EDX,EDX
00592AD4 33DB XOR EBX,EBX
00592AD6 F7F3 DIV EBX
00592AD8 90 NOP
00592AD9 64:8F05 0000000>POP DWORD PTR FS:[0]
00592AE0 83C4 04 ADD ESP,4
00592AE3 61 POPAD
00592AE4 FF35 19CA5700 PUSH DWORD PTR DS:[57CA19]
00592AEA 8F05 5DC85700 POP DWORD PTR DS:[57C85D]
00592AF0 8B0D 5DC85700 MOV ECX,DWORD PTR DS:[57C85D]
00592AF6 8908 MOV DWORD PTR DS:[EAX],ECX ; **************
00592AF8 FF15 0C774B00 CALL DWORD PTR DS:[4B770C] ; msvcrt.__p__commode
00592AFE FF35 6C464D00 PUSH DWORD PTR DS:[4D466C]
00592B04 8F05 A9CA5700 POP DWORD PTR DS:[57CAA9]
00592B0A 8915 2DC95700 MOV DWORD PTR DS:[57C92D],EDX
00592B10 FF35 2DC95700 PUSH DWORD PTR DS:[57C92D]
00592B16 68 A9CA5700 PUSH 0057CAA9
00592B1B 5A POP EDX
00592B1C 8B0A MOV ECX,DWORD PTR DS:[EDX]
00592B1E 8B1424 MOV EDX,DWORD PTR SS:[ESP]
00592B21 8F05 C1C95700 POP DWORD PTR DS:[57C9C1]
00592B27 8908 MOV DWORD PTR DS:[EAX],ECX
00592B29 A1 08774B00 MOV EAX,DWORD PTR DS:[4B7708]
00592B2E 8B00 MOV EAX,DWORD PTR DS:[EAX]
00592B30 90 NOP
00592B31 90 NOP
00592B32 60 PUSHAD
00592B33 E8 01000000 CALL 00592B39
......
00592C7E 83C4 04 ADD ESP,4
00592C81 66:BB 9B5E MOV BX,5E9B
00592C85 F9 STC
00592C86 8929 MOV DWORD PTR DS:[ECX],EBP
00592C88 EB 01 JMP SHORT 00592C8B
00592C8A 90 NOP
00592C8B E8 94A6FFFF CALL <sub_Check_UnhandledExceptionFilter> ; 检测UnhandledExceptionFilter入口有没有处CC断点
00592C90 66:23DD AND BX,BP
00592C93 81E8 C1E0555F SUB EAX,5F55E0C1
00592C99 E8 01000000 CALL 00592C9F
00592C9E ^ 79 83 JNS SHORT 00592C23
00592CA0 C40466 LES EAX,FWORD PTR DS:[ESI] ; Modification of segment register
00592CA3 BB 82FFF981 MOV EBX,81F9FF82
00592CA8 C10400 00 ROL DWORD PTR DS:[EAX+EAX],0 ; Shift constant out of range 1..31
00592CAC 00E8 ADD AL,CH
00592CAE 0100 ADD DWORD PTR DS:[EAX],EAX
00592CB0 0000 ADD BYTE PTR DS:[EAX],AL
00592CB2 ^ 76 83 JBE SHORT 00592C37
00592CB4 04 24 ADD AL,24
00592CB6 06 PUSH ES
00592CB7 C3 RETN
00592CB8 4A DEC EDX
00592CB9 85F3 TEST EBX,ESI
00592CBB 83EF 01 SUB EDI,1
00592CBE ^ 0F85 88FFFFFF JNZ 00592C4C ; 循环解压
00592CC4 E8 01000000 CALL 00592CCA
......
00592E8E 23CE AND ECX,ESI
00592E90 45 INC EBP
00592E91 83E8 01 SUB EAX,1
00592E94 ^ 0F85 5BFFFFFF JNZ 00592DF5 ; 到了这里还循环解压代码
00592E9A EB 01 JMP SHORT 00592E9D
00592E9C ^ 7C 85 JL SHORT 00592E23
00592E9E CD 66 INT 66
00592EA0 33CD XOR ECX,EBP
00592EA2 B8 64000000 MOV EAX,64
00592EA7 33D2 XOR EDX,EDX
00592EA9 33DB XOR EBX,EBX
00592EAB F7F3 DIV EBX
00592EAD 90 NOP
00592EAE 64:8F05 0000000>POP DWORD PTR FS:[0]
00592EB5 83C4 04 ADD ESP,4
00592EB8 E8 4392FFFF CALL <sub_GetEBP > ; 准备跳去执行程序的代码了
00592EBD 6A 00 PUSH 0
00592EBF E8 0A000000 CALL <sub_GOTO_END>
00592EC4 41 INC ECX
......
00592EC5 43 INC EBX
00592EC6 50 PUSH EAX
00592EC7 72 6F JB SHORT 00592F38
00592EC9 74 65 JE SHORT 00592F30
00592ECB 90 NOP
00592ECC 90 NOP
00592ECD 90 NOP
00592ECE > E8 25000000 CALL <GOTO END>
00592ED3 42 INC EDX
00592ED4 79 20 JNS SHORT 00592EF6
00592ED6 54 PUSH ESP
00592ED7 72 69 JB SHORT 00592F42
00592ED9 61 POPAD
00592EDA 6C INS BYTE PTR ES:[EDI],DX ; I/O command
00592EDB 2041 43 AND BYTE PTR DS:[ECX+43],AL
00592EDE 50 PUSH EAX
00592EDF 72 6F JB SHORT 00592F50
00592EE1 74 65 JE SHORT 00592F48
00592EE3 637400 73 ARPL WORD PTR DS:[EAX+EAX+73],SI
00592EE7 74 65 JE SHORT 00592F4E
00592EE9 72 65 JB SHORT 00592F50
00592EEB 64:2041 43 AND BYTE PTR FS:[ECX+43],AL
00592EEF 50 PUSH EAX
00592EF0 72 6F JB SHORT 00592F61
00592EF2 74 65 JE SHORT 00592F59
00592EF4 637421 00 ARPL WORD PTR DS:[ECX],SI
00592EF8 > 6A 00 PUSH 0 ; GOTO END改为jmp [addr] 的方式执行到fake OEP地址
00592EFA 83C4 10 ADD ESP,10 ; 到了这里,只剩跳去fake oep都要加密一下
00592EFD 90 NOP
......
005930A9 E8 5290FFFF CALL <sub_GetEBP > 005930AE 8B85 4B814100 MOV EAX,DWORD PTR SS:[EBP+41814B]
005930B4 0385 46F84000 ADD EAX,DWORD PTR SS:[EBP+40F846]
005930BA 8985 4B814100 MOV DWORD PTR SS:[EBP+41814B],EAX ; 要去执行的地址
005930C0 E8 3B90FFFF CALL <sub_GetEBP > 005930C5 C685 08814100 E>MOV BYTE PTR SS:[EBP+418108],0E8
005930CC E8 2F90FFFF CALL <sub_GetEBP > 005930D1 C785 09814100 F>MOV DWORD PTR SS:[EBP+418109],25FF ; 改成jmp [address]的方式
005930DB 8D85 4B814100 LEA EAX,DWORD PTR SS:[EBP+41814B]
005930E1 8985 0B814100 MOV DWORD PTR SS:[EBP+41810B],EAX
005930E7 E8 1490FFFF CALL <sub_GetEBP > 005930EC 8DBD B87E4100 LEA EDI,DWORD PTR SS:[EBP+417EB8]
005930F2 8D8D FD804100 LEA ECX,DWORD PTR SS:[EBP+4180FD]
005930F8 2BCF SUB ECX,EDI
005930FA C1E9 02 SHR ECX,2
005930FD > E8 CC87FFFF CALL <Get_RND_VALUE> ; Fill junk code
00593102 AB STOS DWORD PTR ES:[EDI]
00593103 ^ E2 F8 LOOPD SHORT <sub_fill_Junk> ; 循环填上垃圾代码,
00593105 61 POPAD
00593106 EB 01 JMP SHORT 00593109
00593108 90 NOP
00593109 - FF25 4B315900 JMP DWORD PTR DS:[59314B] ; JMP to FAKE OEP
.......
004B2DE9 A3 A8464D00 MOV DWORD PTR DS:[4D46A8],EAX ; fake OEP
004B2DEE E8 6B010000 CALL 004B2F5E
004B2DF3 391D 782F4C00 CMP DWORD PTR DS:[4C2F78],EBX
004B2DF9 75 0C JNZ SHORT 004B2E07
分析完整理一下得出Stolen code长这么个模样:
004B2D84 55 PUSH EBP
004B2D85 8BEC MOV EBP,ESP
004B2D87 6A FF PUSH -1
004B2D89 68 609F4B00 PUSH 004B9F60
004B2D8E 68 602F4B00 PUSH 004B2F60 ; JMP to msvcrt._except_handler3
004B2D93 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004B2D99 50 PUSH EAX
004B2D9A 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
004B2DA1 83EC 68 SUB ESP,68
004B2DA4 53 PUSH EBX
004B2DA5 56 PUSH ESI
004B2DA6 57 PUSH EDI
004B2DA7 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
004B2DAA 33DB XOR EBX,EBX
004B2DAC 895D FC MOV DWORD PTR SS:[EBP-4],EBX
004B2DAF 6A 02 PUSH 2
004B2DB1 5F POP EDI
004B2DB2 57 PUSH EDI
004B2DB3 FF15 14774B00 CALL DWORD PTR DS:[4B7714] ; msvcrt.__set_app_type
004B2DB9 59 POP ECX
004B2DBA 830D AC464D00 F>OR DWORD PTR DS:[4D46AC],FFFFFFFF
004B2DC1 830D B0464D00 F>OR DWORD PTR DS:[4D46B0],FFFFFFFF
004B2DC8 FF15 10774B00 CALL DWORD PTR DS:[4B7710] ; msvcrt.__p__fmode
004B2DCE 8B0D 70464D00 MOV ECX,DWORD PTR DS:[4D4670]
004B2DD4 8908 MOV DWORD PTR DS:[EAX],ECX
004B2DD6 FF15 0C774B00 CALL DWORD PTR DS:[4B770C] ; msvcrt.__p__commode
004B2DDC 8B0D 6C464D00 MOV ECX,DWORD PTR DS:[4D466C]
004B2DE2 8908 MOV DWORD PTR DS:[EAX],ECX
004B2DE4 A1 08774B00 MOV EAX,DWORD PTR DS:[4B7708]
sub_RePlace_code:
0057D02E > 60 PUSHAD ; sub_Restore_Replace_Code
0057D02F 90 NOP
0057D030 90 NOP
0057D031 90 NOP
0057D032 90 NOP
......
0057D1D9 E8 22EF0000 CALL <sub_GetEBP > 0057D1DE 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20] ; 取call这个处理模块的地址
0057D1E2 33C9 XOR ECX,ECX
0057D1E4 8B9C8D 812E4000 MOV EBX,DWORD PTR SS:[EBP+ECX*4+402E81]
0057D1EB 039D 46F84000 ADD EBX,DWORD PTR SS:[EBP+40F846]
0057D1F1 3BC3 CMP EAX,EBX
0057D1F3 74 07 JE SHORT 0057D1FC ; 表 里查到符合条件的则跳
0057D1F5 90 NOP
0057D1F6 90 NOP
0057D1F7 90 NOP
0057D1F8 90 NOP
0057D1F9 41 INC ECX
0057D1FA ^ EB E8 JMP SHORT 0057D1E4 ; 循 环查表
0057D1FC 8DB5 615D4000 LEA ESI,DWORD PTR SS:[EBP+405D61]
0057D202 B8 0A000000 MOV EAX,0A
0057D207 F7E1 MUL ECX
0057D209 03F0 ADD ESI,EAX
0057D20B 8DBD 07184000 LEA EDI,DWORD PTR SS:[EBP+401807]
0057D211 0FB6840D C92240>MOVZX EAX,BYTE PTR SS:[EBP+ECX+4022C9]
0057D219 FEC0 INC AL
0057D21B 88840D C9224000 MOV BYTE PTR SS:[EBP+ECX+4022C9],AL
0057D222 3C 20 CMP AL,20
0057D224 75 13 JNZ SHORT 0057D239
0057D226 90 NOP
0057D227 90 NOP
0057D228 90 NOP
0057D229 90 NOP
0057D22A 8BBD 4AF84000 MOV EDI,DWORD PTR SS:[EBP+40F84A]
0057D230 B8 0A000000 MOV EAX,0A
0057D235 F7E1 MUL ECX
0057D237 03F8 ADD EDI,EAX
0057D239 8A9D 1E204000 MOV BL,BYTE PTR SS:[EBP+40201E]
0057D23F B9 0A000000 MOV ECX,0A
0057D244 > AC LODS BYTE PTR DS:[ESI] ; 还 原出正确的代码,加了垃圾代码的
0057D245 32C3 XOR AL,BL
0057D247 AA STOS BYTE PTR ES:[EDI]
0057D248 ^ E2 FA LOOPD SHORT <Decrypt_Replaced_CODE>
0057D24A 83EF 0A SUB EDI,0A
0057D24D 57 PUSH EDI
0057D24E 8DB5 07184000 LEA ESI,DWORD PTR SS:[EBP+401807]
0057D254 33F7 XOR ESI,EDI
0057D256 74 19 JE SHORT 0057D271
0057D258 90 NOP
0057D259 90 NOP
0057D25A 90 NOP
0057D25B 90 NOP
0057D25C 8B7424 24 MOV ESI,DWORD PTR SS:[ESP+24]
0057D260 83EE 04 SUB ESI,4
0057D263 AD LODS DWORD PTR DS:[ESI]
0057D264 81EF 2E204000 SUB EDI,0040202E
0057D26A 2BFD SUB EDI,EBP
0057D26C 03C7 ADD EAX,EDI
0057D26E 8946 FC MOV DWORD PTR DS:[ESI-4],EAX
0057D271 5F POP EDI
0057D272 57 PUSH EDI
0057D273 33C9 XOR ECX,ECX
0057D275 83F9 08 CMP ECX,8
0057D278 74 0E JE SHORT 0057D288
0057D27A 90 NOP
0057D27B 90 NOP
0057D27C 90 NOP
0057D27D 90 NOP
0057D27E 8B448C 04 MOV EAX,DWORD PTR SS:[ESP+ECX*4+4]
0057D282 89048C MOV DWORD PTR SS:[ESP+ECX*4],EAX
0057D285 41 INC ECX
0057D286 ^ EB ED JMP SHORT 0057D275
0057D288 893C8C MOV DWORD PTR SS:[ESP+ECX*4],EDI
......
0057D2C7 61 POPAD
0057D2C8 C3 RETN
进了程序代码空间后,现在分三个任务完成脱壳:去除Acprotect 用到的SDK保护Embedd Protect,去除Replace Code.
去除Acprotect 用到的SDK保护Embedd Protect:
按照任务的顺序一个一个来,我们先解决最大的拌脚石,ACProtect的Embedd Protect应该这个壳里的最大亮点之一。
加上了对程序的保护加强了不少。下面看看我们就去搬走这块石头。
由上篇的文章里的分析,我写个了脚本方便很快就去关键地方,脚本如下:
/*
Set break point at Embedd protect start address
*/
var bpaddr
start:
bprm 401000,b6000 //在Code section处下断点
esto
bpmc
bp 591079 //断下后,在处理SDK的那个关键地方下个断
lbl1:
eob lbl2
run
lbl2:
cmp esi,0
je lbl3
cob
mov bpaddr,esi
add bpaddr,400000 //取出sdk的具体地址,然后在相关地址处下断
mov addrval,[bpaddr]
bp bpaddr
jmp lbl1
lbl3:
cob
bc 591079 //如果处理完了就结束这个脚本,清除上面的关键断点
ret
写好后,设置OD忽略全部异常。运行脚本后最后结束在这里:
00591079 0BF6 OR ESI,ESI ; 如果没有用SDK或SDK处理部分已经操作完成则跳
0059107B 74 31 JE SHORT <finished>
0059107D 90 NOP
0059107E 90 NOP
0059107F 90 NOP
断下后,alt+B打开断点窗口:把非pushad处设置的断点取消:
Breakpoints
Address Module Active Disassembly Comment
0040CC05 MainCon Always PUSHAD
0040FE71 MainCon Always SUB BYTE PTR DS:[ECX],2D ;Clear it
004132D7 MainCon Always PUSHAD
004166D1 MainCon Always PUSHAD
00419A9B MainCon Always PUSHAD
0041CCD6 MainCon Always CMP AL,0A3 ;Clear it
0042089A MainCon Always PUSHAD
00423ADF MainCon Always CMC ;Clear it
00427422 MainCon Always PUSHAD
0042ABD1 MainCon Always PUSHAD
0042DEA1 MainCon Always PUSHAD
004317A2 MainCon Always PUSHAD
00436067 MainCon Always PUSHAD
0043930F MainCon Always JBE SHORT 00439375 ;Clear it
0043C77D MainCon Always PUSHAD
0043FA3D MainCon Always PUSHAD
00442DBD MainCon Always PUSHAD
0044607D MainCon Always PUSHAD
0044933D MainCon Always PUSHAD
0044C600 MainCon Always PUSHAD
0044F8DD MainCon Always PUSHAD
00452C0F MainCon Always PUSHAD
00455EF0 MainCon Always PUSHAD
00459389 MainCon Always PUSHAD
0045C95D MainCon Always PUSHAD
0045FC38 MainCon Always PUSHAD
00462EC8 MainCon Always PUSHAD
0046618B MainCon Always PUSHAD
004696FF MainCon Always PUSHAD
0046C932 MainCon Always INS BYTE PTR ES:[EDI],DX ;Clear it
004708D9 MainCon Always PUSHAD
00474389 MainCon Always PUSHAD
004775C3 MainCon Always OR DH,BYTE PTR DS:[EAX+6F] ;Clear it
0047A80F MainCon Always MOV AL,BYTE PTR DS:[C095E1F] ;Clear it
0047DE02 MainCon Always PUSHAD
00481126 MainCon Always PUSHAD
00484396 MainCon Always INT1 ;Clear it
取消相关的断点后,F9运行后,中断下来:
0042089A 60 PUSHAD ; 运行后中断在这里
0042089B F8 CLC
0042089C 66:2BCD SUB CX,BP
0042089F 87C1 XCHG ECX,EAX
......
00420A62 0000 ADD BYTE PTR DS:[EAX],AL
00420A64 47 INC EDI
00420A65 4F DEC EDI
00420A66 83E8 01 SUB EAX,1
00420A69 ^ 0F85 81FFFFFF JNZ 004209F0 ; 循环解压代码后面有很多的东西
00420A6F 7A 03 JPE SHORT 00420A74
......
00420D64 /E9 08000000 JMP 00420D71
00420D69 |79 03 JNS SHORT 00420D6E
00420D6B |C1EE 47 SHR ESI,47 ;解压了几个回合到一个远程jmp处,不要以为这里就差不多到头哦,后面还有很长的路,
00420D6E |66:8BCE MOV CX,SI
00420D71 \E9 E91D0000 JMP 00422B5F
......
00422B5F E8 8FFDFFFF CALL <sub_Copy code> ; 这里进去复制代码
00422B64 33C2 XOR EAX,EDX
00422B66 EB 01 JMP SHORT 00422B69
00422B68 73 40 JNB SHORT 00422BAA
......
00422C1F 03FD ADD EDI,EBP
00422C21 E8 01000000 CALL 00422C27
00422C26 90 NOP
00422C27 83C4 04 ADD ESP,4
00422C2A E8 37E5FFFF CALL <Check Debugger>
00422C2F 66:C1C6 B1 ROL SI,0B1 ; Shift constant out of range 1..31
00422C33 46 INC ESI
00422C34 C1CF 1E ROR EDI,1E
00422C37 7C 03 JL SHORT 00422C3C
00422C39 7D 01 JGE SHORT 00422C3C
00422C3B ^ 73 E9 JNB SHORT 00422C26
......
00422C6C E8 01000000 CALL 00422C72
00422C71 90 NOP
00422C72 83C4 04 ADD ESP,4
00422C75 E8 3AE8FFFF CALL <Crc File>
00422C7A 66:C1D6 21 RCL SI,21 ; Shift constant out of range 1..31
00422C7E 81C5 19AA764B ADD EBP,4B76AA19
......
00422E90 830424 06 ADD DWORD PTR SS:[ESP],6
00422E94 C3 RETN
00422E95 E8 8DF1FFFF CALL <sub_Anti_Fake_Unpack> ; 检测是否被脱壳了,
00422E9A 8BD5 MOV EDX,EBP
00422E9C 81EF 6D259939 SUB EDI,3999256D
00422EA2 50 PUSH EAX
00422EA3 E8 01000000 CALL 00422EA9
00422EA8 EA 83C40458 66C>JMP FAR C166:5804C483 ; Far jump
00422EAF FA CLI
00422EB0 F1 INT1
00422EB1 83C1 04 ADD ECX,4
00422EB4 E8 01000000 CALL 00422EBA
00422EB9 ^ 7D 83 JGE SHORT 00422E3E
00422EBB C404BA LES EAX,FWORD PTR DS:[EDX+EDI*4] ; Modification of segment register
00422EBE 41 INC ECX
00422EBF 0D AE870F87 OR EAX,870F87AE
00422EC4 0100 ADD DWORD PTR DS:[EAX],EAX
00422EC6 0000 ADD BYTE PTR DS:[EAX],AL
00422EC8 43 INC EBX
00422EC9 83C5 FF ADD EBP,-1
00422ECC ^ 0F85 6AFFFFFF JNZ 00422E3C ; 循环解压代码
00422ED2 E8 01000000 CALL 00422ED8
00422ED7 9A 83C40487 D86>CALL FAR 66D8:8704C483 ; Far call
00422EDE 81C0 56FFE800 ADD EAX,0E8FF56
......
0042327E 83C4 04 ADD ESP,4 ; 过了一段漫长的路,到这里
00423281 58 POP EAX
00423282 E8 84E4FFFF CALL <sub_INT 1_Check_Debug>
00423287 47 INC EDI
00423288 83C1 04 ADD ECX,4
0042328B 2B11 SUB EDX,DWORD PTR DS:[ECX]
......
004232F5 90 NOP
004232F6 61 POPAD ; 一堆检测过后,解开被保护的代码
004232F7 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10] ; 程序代码
004232FA 68 01010100 PUSH 10101
004232FF 68 EBEBEB00 PUSH 0EBEBEB
00423304 90 NOP
00423305 90 NOP
00423306 60 PUSHAD ; 后面还代码,这里继续
00423307 E8 00000000 CALL 0042330C
0042330C 5D POP EBP
......
0042334F /74 03 JE SHORT 00423354
00423351 |75 01 JNZ SHORT 00423354
00423353 |90 NOP
00423354 \E8 12E6FFFF CALL <sub_Fuck_int3> ;这里进去的int3会清除硬件的
00423359 85FD TEST EBP,EDI
0042335B 0F80 02000000 JO 00423363
......
004235B9 81C5 E47934EE ADD EBP,EE3479E4
004235BF EB 01 JMP SHORT 004235C2
004235C1 90 NOP
004235C2 E8 CAF0FFFF CALL <Anti_Fake_Unpack_check_Import> ;反脱壳的检测还真不少
004235C7 E9 02000000 JMP 004235CE
004235CC 87CF XCHG EDI,ECX
......
00423926 830424 06 ADD DWORD PTR SS:[ESP],6
0042392A C3 RETN
0042392B E9 04000000 JMP 00423934
00423930 8BF8 MOV EDI,EAX
00423932 03F9 ADD EDI,ECX
00423934 E9 82010000 JMP 00423ABB ; 跳去执行程序的代码了
00423939 EB 01 JMP SHORT 0042393C
......
00423ABB 61 POPAD
00423ABC 90 NOP
00423ABD 90 NOP
00423ABE 90 NOP
00423ABF 90 NOP
00423AC0 90 NOP
00423AC1 90 NOP
00423AC2 90 NOP
00423AC3 90 NOP
00423AC4 90 NOP
00423AC5 90 NOP
00423AC6 90 NOP
00423AC7 90 NOP
00423AC8 90 NOP ; 这里又是程序代码了
00423AC9 E8 96F10800 CALL 004B2C64 ; JMP to MFC42.#5943
00423ACE 60 PUSHAD
00423ACF 6A 05 PUSH 5
00423AD1 6A 00 PUSH 0
00423AD3 6A 00 PUSH 0
00423AD5 6A FF PUSH -1
00423AD7 FF15 C8784B00 CALL DWORD PTR DS:[4B78C8] ; <MainCon.sub_SDK_Disposal>
这里跟进去可以看到SDK处理的核心部分sub_EmbeddProtect
00423ADD 61 POPAD
00423ADE 90 NOP
......
00423FA9 /E9 08000000 JMP 00423FB6
00423FAE |66:81D3 A6AF ADC BX,0AFA6
00423FB3 |66:03D9 ADD BX,CX
00423FB6 \E9 E91D0000 JMP 00425DA4 ; 呵呵又一个远程跳,必有动作
00423FBB 0000 ADD BYTE PTR DS:[EAX],AL
......
00426066 /79 01 JNS SHORT 00426069
00426068 |90 NOP
00426069 \E8 68F8FFFF CALL <Anti_Fake_Unpack_check_Import>
0042606E 0F83 02000000 JNB 00426076
00426074 D3DE RCR ESI,CL
00426076 8BCD MOV ECX,EBP
......
00426242 ^\71 83 JNO SHORT 004261C7
00426244 C40458 LES EAX,FWORD PTR DS:[EAX+EBX*2] ; Modification of segment register
00426247 E8 5FE1FFFF CALL <sub_Fuck_RING0'Debugger>
0042624C 87C7 XCHG EDI,EAX ; MainCon.004262F6
0042624E 4F DEC EDI
......
004266AB 830424 06 ADD DWORD PTR SS:[ESP],6
004266AF C3 RETN
004266B0 E8 3DE7FFFF CALL <sub_check_ring3_debug>
004266B5 E9 10000000 JMP 004266CA
004266BA 0F84 02000000 JE 004266C2
004266C0 87D1 XCHG ECX,EDX
......
0042670C E8 01000000 CALL 00426712
00426711 - E9 83C40458 JMP 58472B99
00426716 E8 DEDFFFFF CALL <SUB_CRC>
0042671B 0BCF OR ECX,EDI
0042671D 87D9 XCHG ECX,EBX
0042671F E8 00000000 CALL 00426724
......
00426B78 4F DEC EDI
00426B79 E9 82010000 JMP 00426D00 ; 跳去执行程序代码了
00426B7E E8 01000000 CALL 00426B84
......
00426D00 61 POPAD ; 又开始程序代码
00426D01 E8 58BF0800 CALL 004B2C5E ; JMP to MFC42.#1168
00426D06 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
00426D09 6A 00 PUSH 0
00426D0B 6A 00 PUSH 0
00426D0D 68 8C164C00 PUSH 004C168C ; ASCII "Demo"
00426D12 50 PUSH EAX
00426D13 E8 940F0600 CALL 00487CAC
00426D18 60 PUSHAD
00426D19 6A 04 PUSH 4 ; 为4时表示加密
00426D1B 6A 00 PUSH 0
00426D1D 6A 00 PUSH 0
00426D1F 6A FF PUSH -1
00426D21 FF15 C8784B00 CALL DWORD PTR DS:[4B78C8] ; <MainCon.sub_SDK_Disposal>
00426D27 EB 1E JMP SHORT 00426D47
00426D29 7D 66 JGE SHORT 00426D91
00426D2B 99 CDQ
00426D2C - E9 6E3956CB JMP CB98A69F
00426D31 67:A8 69 TEST AL,69 ; Superfluous prefix
00426D34 DF59 E5 FISTP WORD PTR DS:[ECX-1B]
00426D37 0000 ADD BYTE PTR DS:[EAX],AL
00426D39 0000 ADD BYTE PTR DS:[EAX],AL
00426D3B 0000 ADD BYTE PTR DS:[EAX],AL
00426D3D 0000 ADD BYTE PTR DS:[EAX],AL
00426D3F 0000 ADD BYTE PTR DS:[EAX],AL
00426D41 0000 ADD BYTE PTR DS:[EAX],AL
00426D43 0000 ADD BYTE PTR DS:[EAX],AL
00426D45 0000 ADD BYTE PTR DS:[EAX],AL
00426D47 61 POPAD ; 下面又是程序代码了,...
00426D48 68 84164C00 PUSH 004C1684 ; ASCII "Skin"
00426D4D 68 7C164C00 PUSH 004C167C ; ASCII "Skin1"
00426D52 6A 00 PUSH 0
00426D54 E8 FE130600 CALL 00488157
00426D59 60 PUSHAD
00426D5A 6A 04 PUSH 4
00426D5C 6A 00 PUSH 0
00426D5E 6A 00 PUSH 0
00426D60 6A FF PUSH -1
00426D62 FF15 C8784B00 CALL DWORD PTR DS:[4B78C8] ; <MainCon.sub_SDK_Disposal>
00426D68 EB 1E JMP SHORT 00426D88 ; 这里跳去就结束这个sdk 的处理、执行了
00426D6A 52 PUSH EDX
00426D6B EE OUT DX,AL ; I/O command
00426D6C B3 68 MOV BL,68
00426D6E B9 20AC0B71 MOV ECX,710BAC20
00426D73 CF IRETD
00426D74 D019 RCR BYTE PTR DS:[ECX],1
00426D76 8ADD MOV BL,CH
00426D78 0000 ADD BYTE PTR DS:[EAX],AL
00426D7A 0000 ADD BYTE PTR DS:[EAX],AL
00426D7C 0000 ADD BYTE PTR DS:[EAX],AL
00426D7E 0000 ADD BYTE PTR DS:[EAX],AL
00426D80 0000 ADD BYTE PTR DS:[EAX],AL
00426D82 0000 ADD BYTE PTR DS:[EAX],AL
00426D84 0000 ADD BYTE PTR DS:[EAX],AL
00426D86 0000 ADD BYTE PTR DS:[EAX],AL
00426D88 61 POPAD
00426D89 6A 00 PUSH 0 ; 又正常执行程序代码了
00426D8B 8D8D 9497FFFF LEA ECX,DWORD PTR SS:[EBP+FFFF9794]
00426D91 E8 9AA50000 CALL 00431330
......
ok,关于Embedd Protect的分析就结束了,再分析几个地方就可以得到一定的规律。找回正常的代码也就是件很简单的事了,只需要一定的时间就可以了。
这里的正确代码就应该为:
00420889 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
0042088C 68 01010100 PUSH 10101
00420891 68 EBEBEB00 PUSH 0EBEBEB
00420896 E8 C9230900 CALL <JMP.&MFC42.#5943>
0042089B E8 BE230900 CALL <JMP.&MFC42.#1168>
004208A0 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
004208A3 6A 00 PUSH 0
004208A5 6A 00 PUSH 0
004208A7 68 8C164C00 PUSH 004C168C ; ASCII "Demo"
004208AC 50 PUSH EAX
004208AD E8 FA730600 CALL 00487CAC
004208B2 68 84164C00 PUSH 004C1684 ; ASCII "Skin"
004208B7 68 7C164C00 PUSH 004C167C ; ASCII "Skin1"
004208BC 6A 00 PUSH 0
004208BE E8 94780600 CALL 00488157
004208C3 E9 C1640000 JMP 00426D89 ; JMP to MFC42.#5943
经过N久的时间把全部的正确代码找回来了之后,dump下code段,第一个任务就算完成了,接下来完成第二个任务。
去除Replace Code:
这个任务也算是ACProtect 的一样法宝吧,替换了很多的代码。每次替换5个字节的代码,方式为3+2或2+3,壳
解压出来时已经加了垃圾代码。
重来,载入目标,先在rdata段下断点,断下后,在text段下断,运行停止在fake oep后,在最后一个段下内存写
入断点。再运行,这样就中断在Replace Code的关键代码处了:
sub_Restore_Replace_Code:
0057D02E > 60 PUSHAD ; sub_Restore_Replace_Code
0057D02F 4A DEC EDX
0057D030 FC CLD
......
0057D0EB 8945 1D MOV DWORD PTR SS:[EBP+1D],EAX ; 中断在这里
0057D0EE EB 01 JMP SHORT 0057D0F1
......
0057D1C5 83E9 01 SUB ECX,1
0057D1C8 ^ 0F85 69FFFFFF JNZ 0057D137 ; 循环解压代码
0057D1CE EB 01 JMP SHORT 0057D1D1
0057D1D0 71 72 JNO SHORT <Decrypt_Replaced_CODE>
0057D1D2 06 PUSH ES
0057D1D3 81E7 B34D2A57 AND EDI,572A4DB3
0057D1D9 E8 22EF0000 CALL <sub_GetEBP > 0057D1DE 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20] ; 取call这个处理模块的地址
0057D1E2 33C9 XOR ECX,ECX
0057D1E4 8B9C8D 812E4000 MOV EBX,DWORD PTR SS:[EBP+ECX*4+402E81>; 指向一个表,通过在表里查询来还原代码
0057D1EB 039D 46F84000 ADD EBX,DWORD PTR SS:[EBP+40F846]
0057D1F1 3BC3 CMP EAX,EBX
0057D1F3 74 07 JE SHORT 0057D1FC ; 表里查到符合条件的则跳
0057D1F5 90 NOP
0057D1F6 90 NOP
0057D1F7 90 NOP
0057D1F8 90 NOP
0057D1F9 41 INC ECX
0057D1FA ^ EB E8 JMP SHORT 0057D1E4 ; 循环查表
0057D1FC 8DB5 615D4000 LEA ESI,DWORD PTR SS:[EBP+405D61]
0057D202 B8 0A000000 MOV EAX,0A
0057D207 F7E1 MUL ECX
0057D209 03F0 ADD ESI,EAX
0057D20B 8DBD 07184000 LEA EDI,DWORD PTR SS:[EBP+401807]
0057D211 0FB6840D C92240>MOVZX EAX,BYTE PTR SS:[EBP+ECX+4022C9]
0057D219 FEC0 INC AL
0057D21B 88840D C9224000 MOV BYTE PTR SS:[EBP+ECX+4022C9],AL
0057D222 3C 20 CMP AL,20
0057D224 75 13 JNZ SHORT 0057D239
0057D226 90 NOP
0057D227 90 NOP
0057D228 90 NOP
0057D229 90 NOP
0057D22A 8BBD 4AF84000 MOV EDI,DWORD PTR SS:[EBP+40F84A]
0057D230 B8 0A000000 MOV EAX,0A
0057D235 F7E1 MUL ECX
0057D237 03F8 ADD EDI,EAX
0057D239 8A9D 1E204000 MOV BL,BYTE PTR SS:[EBP+40201E] ; [EBP+40201E]中保存着解密的Key
0057D23F B9 0A000000 MOV ECX,0A
0057D244 > AC LODS BYTE PTR DS:[ESI] ; 还原出正确的代码,加了垃圾代码的
0057D245 32C3 XOR AL,BL
0057D247 AA STOS BYTE PTR ES:[EDI]
0057D248 ^ E2 FA LOOPD SHORT <Decrypt_Replaced_CODE>
0057D24A 83EF 0A SUB EDI,0A
0057D24D 57 PUSH EDI
0057D24E 8DB5 07184000 LEA ESI,DWORD PTR SS:[EBP+401807]
0057D254 33F7 XOR ESI,EDI
0057D256 74 19 JE SHORT 0057D271
0057D258 90 NOP
0057D259 90 NOP
0057D25A 90 NOP
0057D25B 90 NOP
0057D25C 8B7424 24 MOV ESI,DWORD PTR SS:[ESP+24]
0057D260 83EE 04 SUB ESI,4
0057D263 AD LODS DWORD PTR DS:[ESI]
0057D264 81EF 2E204000 SUB EDI,0040202E
0057D26A 2BFD SUB EDI,EBP
0057D26C 03C7 ADD EAX,EDI
0057D26E 8946 FC MOV DWORD PTR DS:[ESI-4],EAX
0057D271 5F POP EDI
0057D272 57 PUSH EDI
0057D273 33C9 XOR ECX,ECX
0057D275 83F9 08 CMP ECX,8
0057D278 74 0E JE SHORT 0057D288
0057D27A 90 NOP
0057D27B 90 NOP
0057D27C 90 NOP
0057D27D 90 NOP
0057D27E 8B448C 04 MOV EAX,DWORD PTR SS:[ESP+ECX*4+4]
0057D282 89048C MOV DWORD PTR SS:[ESP+ECX*4],EAX
0057D285 41 INC ECX
0057D286 ^ EB ED JMP SHORT 0057D275
0057D288 893C8C MOV DWORD PTR SS:[ESP+ECX*4],EDI
0057D28B 60 PUSHAD ; 加密代码
0057D28C E8 00000000 CALL 0057D291
0057D291 5E POP ESI
0057D292 83EE 06 SUB ESI,6
0057D295 B9 B2000000 MOV ECX,0B2
0057D29A 29CE SUB ESI,ECX
0057D29C BA 41A20ADC MOV EDX,DC0AA241
0057D2A1 C1E9 02 SHR ECX,2
0057D2A4 83E9 02 SUB ECX,2
0057D2A7 83F9 00 CMP ECX,0
0057D2AA 7C 1A JL SHORT 0057D2C6
0057D2AC 8B048E MOV EAX,DWORD PTR DS:[ESI+ECX*4]
0057D2AF 8B5C8E 04 MOV EBX,DWORD PTR DS:[ESI+ECX*4+4]
0057D2B3 33C3 XOR EAX,EBX
0057D2B5 C1C8 15 ROR EAX,15
0057D2B8 33C2 XOR EAX,EDX
0057D2BA 81EA 417BCDED SUB EDX,EDCD7B41
0057D2C0 89048E MOV DWORD PTR DS:[ESI+ECX*4],EAX
0057D2C3 49 DEC ECX
0057D2C4 ^ EB E1 JMP SHORT 0057D2A7
0057D2C6 61 POPAD
0057D2C7 61 POPAD
0057D2C8 C3 RETN ; 返回到要执行的代码处
分析出这些代码后,写了个修复代码,这个修复代码是我上次看到股林精怪写的,既然这的这么好,我就直接
搬来过借用下:-),修复代码如下:
.386
.model flat,stdcall
;-------------------------------------------------------------
;
; ACProtect v1.41 Replace Code Fix Application
;
;-------------------------------------------------------------
.code
start:
PUSHAD
XOR EAX,EAX
MOV EDI,580d61h ;LEA ESI,DWORD PTR SS:[EBP+405D61] EBP+405D61=525d61
L003:
CMP DWORD PTR DS:[EAX+EDI],0
JE L008
XOR BYTE PTR DS:[EAX+EDI],0D7h ;MOV BL,BYTE PTR SS:[EBP+40201E] [0052201e]=22
INC EAX
JMP L003
L008:
XOR ECX,ECX
L009:
MOV ESI,DWORD PTR DS:[ECX*4+57de81h] ;MOV EBX,DWORD PTR SS:[EBP+ECX*4+402E81] EBP+402E81=522e81
CMP ESI,0
JNZ L015
POPAD
SUB DWORD PTR SS:[ESP],5h
RETN
L015:
MOV EDI,580d61h ;LEA ESI,DWORD PTR SS:[EBP+405D61] EBP+405D61=525d61
ADD ESI,3FFFFBh
MOV EAX,0Ah
MUL ECX
ADD EDI,EAX
XOR EAX,EAX
L021:
CMP BYTE PTR DS:[EAX+EDI],3h
JE L074
CMP BYTE PTR DS:[EAX+EDI],33h
JE L114
CMP BYTE PTR DS:[EAX+EDI],40h
JB L029
CMP BYTE PTR DS:[EAX+EDI],58h
JB L031
L029:
INC EAX
JMP L021
L031:
MOV DL,BYTE PTR DS:[EAX+EDI]
ADD DL,8
MOV EBX,EAX
L034:
INC EBX
CMP DL,BYTE PTR DS:[EBX+EDI]
JE L040
CMP EBX,8
JB L034
JMP L029
L040:
SUB EBX,EAX
CMP EAX,0
JNZ L058
CMP EBX,2
JB L029
DEC EBX
INC EDI
XOR EBP,EBP
L048:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EBX,EBP
JNZ L048
INC EDI
XOR EBX,EBX
JMP L048
L058:
CMP EBX,2
JE L029
XOR EBP,EBP
L061:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EAX,EBP
JNZ L061
INC EDI
XOR EAX,EAX
CMP EBX,1
JNZ L061
INC EDI
JMP L061
L074:
MOV DX,WORD PTR DS:[EAX+EDI]
ADD DX,28h
MOV EBX,EAX
INC EBX
L078:
INC EBX
CMP WORD PTR DS:[EBX+EDI],DX
JE L084
CMP EBX,8
JB L078
JMP L029
L084:
CMP EAX,0
JNZ L099
LEA EAX,DWORD PTR DS:[EBX-2]
ADD EDI,2
XOR EBP,EBP
L089:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EAX,EBP
JNZ L089
ADD EDI,2
XOR EAX,EAX
JMP L089
L099:
SUB EBX,EAX
XOR EBP,EBP
L101:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EAX,EBP
JNZ L101
ADD EDI,2
XOR EAX,EAX
CMP EBX,2
JNZ L101
ADD EDI,2
JMP L101
L114:
MOV DX,WORD PTR DS:[EAX+EDI]
MOV EBX,EAX
INC EBX
L117:
INC EBX
CMP WORD PTR DS:[EBX+EDI],DX
JE L123
CMP EBX,8
JB L117
JMP L029
L123:
CMP EAX,0
JNZ L138
LEA EAX,DWORD PTR DS:[EBX-2]
ADD EDI,2
XOR EBP,EBP
L128:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EAX,EBP
JNZ L128
ADD EDI,2
XOR EAX,EAX
JMP L128
L138:
SUB EBX,EAX
XOR EBP,EBP
L140:
MOV DL,BYTE PTR DS:[EDI+EBP]
MOV BYTE PTR DS:[ESI+EBP],DL
CMP EBP,4
JE L153
INC EBP
CMP EAX,EBP
JNZ L140
ADD EDI,2
XOR EAX,EAX
CMP EBX,2
JNZ L140
ADD EDI,2
JMP L140
L153:
INC ECX
JMP L009
end start
写好代码后,重新加载目标文件,忽略全部异常,直接在rdata处下断,运行中断后
005906B7 33C0 XOR EAX,EAX ;直接运行到这里
005906B9 B9 00010000 MOV ECX,100
运行后断在5906b7处后,把eip改为sub_Restore_Replace_Code(先选择57d02e,然后CTRL+*),
然后贴上修复代码,贴上后执行到结束处:
0057D02E > 60 PUSHAD ; sub_Restore_Replace_Code
0057D02F 33C0 XOR EAX,EAX
0057D031 BF 610D5800 MOV EDI,00580D61
0057D036 833C07 00 CMP DWORD PTR DS:[EDI+EAX],0
0057D03A 74 07 JE SHORT 0057D043
0057D03C 803407 D7 XOR BYTE PTR DS:[EDI+EAX],0D7
0057D040 40 INC EAX
0057D041 ^ EB F3 JMP SHORT 0057D036
0057D043 33C9 XOR ECX,ECX
0057D045 8B348D 81DE5700 MOV ESI,DWORD PTR DS:[ECX*4+57DE81]
0057D04C 83FE 00 CMP ESI,0
0057D04F 75 06 JNZ SHORT 0057D057
0057D051 61 POPAD
0057D052 832C24 05 SUB DWORD PTR SS:[ESP],5 ; f4直接执行到这里
0057D056 C3 RETN
执行完毕后把eip改回原处修复好replace code和embedd protect code之后,修复一下iat和oep信息就可以运行了。
总结一下,为了方便自己操作,我写了一段脚本。
/*
ACPROTCT 1.4 Unpack script v0.1
*/
var addr
var mbase //module base
var rmaddr
var rmsize
var IATVA
var tmpval
start:
gmi eip,MODULEBASE
mov mbase,$RESULT
gpa "GetModuleHandleA","kernel32.dll"
mov addr,$RESULT
bprm addr,0A
esto
lbl1:
bpmc
findop eip,#F3AA# //Find command 'REP STOSB'
cmp $RESULT,0
je lblabort
go $RESULT
mov addr,$RESULT
add addr,2
mov eip,addr
mov rmaddr,4b7000 //rdata段的开始地址
mov rmsize,a000 //rdata段的大小
bpwm rmaddr,rmsize
esto
lbl2:
bpmc
mov IATVA,esi
mov tmpval,esi
sub IATVA,mbase //计算iat的地始地址VA
findop eip,#83660C00# //find command 'AND DWORD PTR DS:[ESI+C],0'
cmp $RESULT,0
je lblabort
fill $RESULT,4,90
repl eip,#602BC0880343380375F961#,#9090909090909090909090#,500 //把清除名字的代码给nop掉
find $RESULT,#618907#
cmp $RESULT,0
je lblabort
go $RESULT
mov addr,$RESULT
inc addr
fill addr,2,90
findop addr,#33C0#
cmp $RESULT,0
je lblabort
mov addr,$RESULT
go addr
log IATVA
fill 6909c7,1,eb
ret
lblabort:
msg "Error!"
ret
用od载入目标程序,运行该脚本,然后把前面dump下来修复好的Embedd Protect代码段替换这个现在正在操作的这个目标,然后用修复Replace code
的代码修复Replace code,修复完,被上程序的oep被抽的代码,然后dump下目标程序的整个内存,修改OEP,修改正确的IAT信息,iat信息由分析篇
得之:OEP RVA=000B2D84 IAT RVA=000BEB88 SIZE=00002398,修复好后程序就可以运行了。这样就算是比较完整的脱壳了,最后我自己还有一个问题
哪位会的朋友指点下,谢谢,问题:壳把部分资源放到最后一个节去了,如何修复资源呢?, 对这个我一点都不会:-(。如果资源修复好了,最后一个节
应该可以去掉吧。
在脱其它的acprotect的程序时发现有时还会有调用壳的api的代码,我这里附上修复调用壳api的代码:
.386
.model flat,stdcall
.code
FillCode proc cmpaddr:DWORD,waddr:DWORD
;----------------
;cmpaddr 表示比较地址
;waddr 要写入地址
pushad
mov edi,401000h
mov ecx,0baf00h
@loop1:
cmp word ptr [edi],25ffh
jnz jmpn
mov ebx,[edi+2]
cmp ebx,401000h
jb jmpn
cmp ebx,521000h
ja jmpn
mov ebx,[ebx]
cmp cmpaddr,ebx
jnz @F
mov ebx,edi
mov eax,waddr
sub ebx,eax
sub ebx,5
mov dword ptr [eax+1],ebx
jmp @end
@@:
add edi,4
sub ecx,4
jmpn:
inc edi
dec ecx
jnz @loop1
@end:
popad
ret 8
FillCode endp
@calld52 proc
pushad
CALL @F ;CALL 531100 Get EBP value
MOV EAX,DWORD PTR SS:[ESP+24h]
SUB EAX,DWORD PTR SS:[EBP+40F846h]
MOV ECX,3E9h
LEA EDI,DWORD PTR SS:[EBP+40D563h]
REPNE SCAS DWORD PTR ES:[EDI]
OR ECX,ECX
JNZ @F
NOP
NOP
NOP
NOP
@@:
SUB ECX,3E9h
NOT ECX
MOVZX EBX,BYTE PTR SS:[EBP+ECX+40E503h]
LEA EAX,DWORD PTR SS:[EBP+EBX*4+40E8EBh]
mov eax,[eax]
mov EDX,DWORD PTR SS:[ESP+24h]
sub edx,5
cmp eax,5000000h
ja @F
mov ebx,[eax+8]
mov eax,[eax+1]
xor eax,ebx
@@:
invoke FillCode,eax,edx
popad
ret 4
@calld52 endp
start:
pushad
mov edi,401000h
mov ecx,0baf00h
@loop1:
cmp byte ptr [edi],0e8h
jnz @F
mov ebx,[edi+1]
lea ebx,[ebx+edi+5]
cmp ebx,52d30bh ;判断是否为call去解码处
jnz @Not52d
lea ebx,[edi+5]
push ebx
call @calld52
jmp @add4
@Not52d:
cmp ebx,521000h
jb @F
cmp ebx,538fd2h
ja @F
cmp word ptr [ebx+1],25ffh
jnz @F
mov ebx,[ebx+3]
mov ebx,[ebx]
invoke FillCode,ebx,edi
@add4:
add edi,4
sub ecx,4
@@:
inc edi
dec ecx
jnz @loop1
popad
end start
漫漫长路,终到尽头。分析了这么多,现在看来又好像什么都没有哦:-),花了很多时间,今天终于把ACPROTECT给吃下来了。如果有兴趣可以试试做
脱壳机的,我自己看了分析后认为做这个的脱壳机应该是可行的(如果不行,不能怪我哦:-P)。有所收获有所失去。牺牲了睡眠换来了近视:-9。收工zzZZZZ。
---------------------------各模块代码------------------------------------
sub_EmbeddProtect:
0058AE31 > 837C24 04 FF CMP DWORD PTR SS:[ESP+4],-1 ; 处理SDK的关键代码
0058AE36 74 13 JE SHORT 0058AE4B
0058AE38 90 NOP
0058AE39 90 NOP
0058AE3A 90 NOP
0058AE3B 90 NOP
0058AE3C 55 PUSH EBP
0058AE3D E8 BE120000 CALL <sub_GetEBP > 0058AE42 8BC5 MOV EAX,EBP
0058AE44 5D POP EBP
0058AE45 FFA0 C4FD4000 JMP DWORD PTR DS:[EAX+40FDC4]
0058AE4B 90 NOP
......
0058AFF7 55 PUSH EBP
0058AFF8 E8 03110000 CALL <sub_GetEBP > ; 这里是关键代码,用于加密解密代码的
0058AFFD 8BC5 MOV EAX,EBP
0058AFFF 5D POP EBP
0058B000 837C24 04 FF CMP DWORD PTR SS:[ESP+4],-1
0058B005 74 25 JE SHORT 0058B02C
0058B007 90 NOP
0058B008 90 NOP
0058B009 90 NOP
0058B00A 90 NOP
0058B00B 8B98 2C854100 MOV EBX,DWORD PTR DS:[EAX+41852C]
0058B011 803B CC CM |