中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
AcProtect 1.41 外壳分析
作者:未知 时间:2005-07-27 23:27 出处:CSDN 责编:chinaitpower
              摘要:AcProtect 1.41 外壳分析
【目    标】: 应作者要求,这里不贴上软件名
【工    具】: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