ASPROTECT 1.23RC4 脱壳分析

类别:编程语言 点击:0 评论:0 推荐:
ASPR1.23RC4脱壳之advanced im password Recovery+简单MD5【目    标】: advanced im password Recovery v2.31
【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F ASPRDBGR1.0,IDA
【任    务】:先脱马甲,然后hehe……
【操作平台】:WINXP pro sp1
【作    者】:loveboom[DFCG][FCG]
【相关链接】: www.elcomsoft.com
【简要说明】:也算有一段时间没有发破文了,因水平菜,时间等问题,所以难的搞不定,易的已经有很多朋友写了,这篇文章也算是搞一点积分吧,再则,很久没看见自己的贴有个精,所以想这篇文章看看能不能再混个精,其它就没多少研究价值了。【详细过程】:       用PEID查一下发现是ASProtect 1.23 RC4 - 1.3.08.24 -> Alexey Solodovnikov,一开始还以为是ASPR1.3XXX的呢,所以有点想打道回府,但又想,既然来了,不管怎么样也要试上把,反正输了,也没有人知道,最多是“浪费”一点时间。还好有惊无险,跟到后面发现原来是个软柿子,让我占了个便宜。好了,留点口水到后面用。打开OD设置为取消忽略内存异常,去掉RING3的检测,一路shift+f9飞到最后一次异常(我这里是第25次后到最后异常):009C39EC    3100            XOR DWORD PTR DS:[EAX],EAX009C39EE    64:8F05 0000000>POP DWORD PTR FS:[0]009C39F5    58              POP EAX009C39F6    833D B07E9C00 0>CMP DWORD PTR DS:[9C7EB0],0009C39FD    74 14           JE SHORT 009C3A13009C39FF    6A 0C           PUSH 0C009C3A01    B9 B07E9C00     MOV ECX,9C7EB0009C3A06    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]009C3A09    BA 04000000     MOV EDX,4009C3A0E    E8 2DD1FFFF     CALL 009C0B40009C3A13    FF75 FC         PUSH DWORD PTR SS:[EBP-4]009C3A16    FF75 F8         PUSH DWORD PTR SS:[EBP-8]009C3A19    8B45 F4         MOV EAX,DWORD PTR SS:[EBP-C]009C3A1C    8338 00         CMP DWORD PTR DS:[EAX],0009C3A1F    74 02           JE SHORT 009C3A23009C3A21    FF30            PUSH DWORD PTR DS:[EAX]009C3A23    FF75 F0         PUSH DWORD PTR SS:[EBP-10]009C3A26    FF75 EC         PUSH DWORD PTR SS:[EBP-14]009C3A29    C3              RETN                   ;这里下断看到了c3吧,对就这里下断,在009c3a29处下f2断点,然后shift+f9就会断下来。断下后取消该断点(怎么取消,晕倒,对没有一点基础知识的朋友,请去看相关文档,不用来问我了,因我没有这么多时间来回答,这里也随便回答一下,上次有朋友问我,用了我的幻影的脱壳脚本后如何dump+fixdump,这个问题我不好怎么讲,只能说你们自己去看看最基础的东西先)唔,开小差就开到这里先,取消断点后下硬件访问断点hr [ESP+C](这里也就相当于hr 12ffa4),下断完毕当然是F9运行了,下面的东西要有一点基础,要不看那些代码就有点飞的感觉。运行后这里断下,断下后取消硬件访问断点:009D5CA3    F3:             PREFIX REP:            ; 这里断下009D5CA4    EB 02           JMP SHORT 009D5CA8下面就要小心点按F8来找到stolen code,009D5CF5    BE C55C9D00     MOV ESI,9D5CC5009D5CFA    FF56 3F         CALL DWORD PTR DS:[ESI+3F]  ;这里F7跟进去,要不就真的飞了,进去后就按f8一直跟到stolen code处009D5D67    896C24 00       MOV DWORD PTR SS:[ESP],EBP ;*****       ;这里就是push ebp了009D5D6B    8BEC            MOV EBP,ESP  ;*****009D5D6D    6A FF           PUSH –1 ;*****009D5D6F    68 48A44200     PUSH 42A448 ;*****009D5D74    68 F4514200     PUSH 4251F4 ;*****009D5D79    64:A1 00000000  MOV EAX,DWORD PTR FS:[0]  ;*****009D5D7F    66:8105 895D9D0>ADD WORD PTR DS:[9D5D89],4916……009D5DBB    894424 00       MOV DWORD PTR SS:[ESP],EAX       ;*****009D5DBF    64:8925 0000000>MOV DWORD PTR FS:[0],ESP            ;*****009D5DC6    83EC 58         SUB ESP,58                  ;*****……009D5E05    895C24 00       MOV DWORD PTR SS:[ESP],EBX       ;*****……009D5E45    897424 00       MOV DWORD PTR SS:[ESP],ESI        ;*****      ……009D5E85    897C24 00       MOV DWORD PTR SS:[ESP],EDI    ;*****           ; ntdll.77F944A8009D5E89    8965 E8         MOV DWORD PTR SS:[EBP-18],ESP     ;*****009D5E8C    F3:             PREFIX REP:        009D5E95    68 F8FF4100     PUSH 41FFF8              ;看到这里,只要跟过aspr的朋友都知道下面就是清场代码,我们没必要去跟。009D5E9A    68 015C9D00     PUSH 9D5C01009D5E9F    C3              RETN现在我们直接执行g 41fff8,这样就到这里停下来了.0041FFF8    FF15 C4914200   CALL DWORD PTR DS:[4291C4]  ;到这里下车0041FFFE    33D2            XOR EDX,EDX00420000    8AD4            MOV DL,AH00420002    8915 84BE4300   MOV DWORD PTR DS:[43BE84],EDX00420008    8BC8            MOV ECX,EAX好了,现在总结一下stolen code:0041FFD2    55              PUSH EBP0041FFD3    8BEC            MOV EBP,ESP0041FFD5    6A FF           PUSH -10041FFD7    68 48A44200     PUSH AIMPR.0042A4480041FFDC    68 F4514200     PUSH AIMPR.004251F40041FFE1    64:A1 00000000  MOV EAX,DWORD PTR FS:[0]0041FFE7    50              PUSH EAX0041FFE8    64:8925 0000000>MOV DWORD PTR FS:[0],ESP0041FFEF    83EC 58         SUB ESP,580041FFF2    53              PUSH EBX0041FFF3    56              PUSH ESI0041FFF4    57              PUSH EDI0041FFF5    8965 E8         MOV DWORD PTR SS:[EBP-18],ESP补上这些代码后,打开asprdbgr 1.0并载入目标,加载后,出现对框就点yes直到目标程序运行:AsprDbgr v1.0beta (:P) Made by me... Manko.   iEP=401000 (C:\Program Files\AIMPR\AIMPR.exe)   GST returns to: 9B2667    Trick aspr GST... (EAX=12121212h)  GV returns to: 9C1A61    IAT Start: 429000          End: 42938C       Length: 38C      IATentry 4290E4 = 9C1CF0 resolved as FreeResource      IATentry 4290E8 = 9C1C64 resolved as GetModuleHandleA      IATentry 4290F4 = 9C1CC8 resolved as LockResource      IATentry 42913C = 9C17A4 resolved as GetProcAddress      IATentry 4291A4 = 9C1CB8 resolved as GetCurrentProcess      IATentry 4291C4 = 9C1C8C resolved as GetVersion      IATentry 4291CC = 9C1CD8 resolved as GetCommandLineA      IATentry 4292C8 = 9C1D14 resolved as DialogBoxParamA    0 invalid entries erased.  Dip-Table at adress: 9C7AB4    0 0 0 0 0 0 0 0 0 0 41DA10 41DA00 41D9F0 0  Last SEH passed. Searching for signatures. Singlestepping to OEP!    Call + OEP-jump-setup at: 9D5E3F ( Code: E8000000 5D81ED )    Mutated, stolen bytes at: 9D5E8A ( Code: 61F3EB02 CD20F3EB )    Erase of stolen bytes at: 9D5DEE ( Code: 9CFCBF2D 5E9D00B9 )      Repz ... found. Skipping erase of stolen bytes. ;)  Dip from pre-OEP: 41FFF8 (Reached from: 9D5DFF)现在打开imp设置OEP为1fff8,然后就可以得到全部的iat,真是好东西,给我等懒人用最好不过了.得到全部输入表后把oep改回1FFD2,当然,如果你喜欢的话也可以一开始就设OEP 为1FFD2。现在DUMP+FIXDUMP后程序就能运行了,到此脱壳也就算完成了衣服已经脱掉了,现在我们就要进行强暴(强力暴破,你可不要想坏了哦,本来想不脱衣服直接强暴,但又想一下,如果直接强暴的话,不就文字太少了,也就不能成为一篇文章嘛)了,载入脱后的文件,运行之,打开注册对话框输入你的大名,然后下断bpx GetDlgitemTextA这样断在这里:lbl_GetSN:                              ; CODE XREF: seg000:0041DE61jseg000:0041DE70                 mov     eax, ds:dword_43BE3Cseg000:0041DE75                 xor     ecx, ecxseg000:0041DE77                 mov     cx, [eax+300h]seg000:0041DE7E                 add     eax, 200hseg000:0041DE83                 push    ecx             ; Countseg000:0041DE84                 push    eax             ; 缓冲区,等下会返回注册码的长度seg000:0041DE85                 push    0FFAh           ; 这里就是ID了seg000:0041DE8A                 push    edi             ; 这个就是句柄来的seg000:0041DE8B                 call    ds:GetDlgItemTextAseg000:0041DE91                 mov     edx, ds:dword_43BE3Cseg000:0041DE97                 add     edx, 200hseg000:0041DE9D                 push    edx             ; EDX保存了我们输入的注册码seg000:0041DE9E                 call    lbl_CheckSn     ; 这里跟进,要不就over了seg000:0041DEA3                 add     esp, 4seg000:0041DEA6                 test    eax, eaxseg000:0041DEA8                 jnz     short loc_41DEB3 ; 这里要注意了,不要以为这里改成jmp就会okseg000:0041DEA8                                         ; 了,这里改是没有用的,因为后面还会进上面seg000:0041DEA8                                         ; 那个CALL里检查是否正确seg000:0041DEAA                 push    ediseg000:0041DEAB                 call    sub_41DD80seg000:0041DEB0                 add     esp, 4进入上面的call到这里lbl_CheckSn     proc near               ; CODE XREF: seg000:0041DE9Epseg000:0041DB90                                         ; sub_41E030+12p ...seg000:0041DB90 seg000:0041DB90 var_6C          = dword ptr -6Chseg000:0041DB90 var_5C          = dword ptr -5Chseg000:0041DB90 arg_0           = dword ptr  4seg000:0041DB90 seg000:0041DB90                 sub     esp, 6Chseg000:0041DB93                 or      ecx, 0FFFFFFFFhseg000:0041DB96                 xor     eax, eaxseg000:0041DB98                 push    ebxseg000:0041DB99                 push    ebpseg000:0041DB9A                 mov     ebp, [esp+74h+arg_0]seg000:0041DB9E                 push    ediseg000:0041DB9F                 mov     edi, ebpseg000:0041DBA1                 repne scasb             ; 这里也就是得出注册码的长度seg000:0041DBA3                 not     ecxseg000:0041DBA5                 dec     ecxseg000:0041DBA6                 cmp     ecx, 6          ; 比较注册长度是否大于六,不就是over了seg000:0041DBA9                 jge     short lbl_Next1 ; 如果没问题的话,就跳去下一步seg000:0041DBAB                 pop     ediseg000:0041DBAC                 pop     ebpseg000:0041DBAD                 pop     ebxseg000:0041DBAE                 add     esp, 6Chseg000:0041DBB1                 retn                    ; 如果到了这里的RET的话,就要重来了seg000:0041DBB2 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━seg000:0041DBB2 seg000:0041DBB2 lbl_Next1:                              ; CODE XREF: lbl_CheckSn+19jseg000:0041DBB2                 and     ecx, 80000001hseg000:0041DBB8                 jns     short loc_41DBBF ; 这里跳,seg000:0041DBBA                 dec     ecxseg000:0041DBBB                 or      ecx, 0FFFFFFFEhseg000:0041DBBE                 inc     ecxseg000:0041DBBF seg000:0041DBBF loc_41DBBF:                             ; CODE XREF: lbl_CheckSn+28jseg000:0041DBBF                 jz      short lbl_Next2 ; 这里也跳,这两个地方我们一般不用管它seg000:0041DBC1                 pop     ediseg000:0041DBC2                 pop     ebpseg000:0041DBC3                 xor     eax, eaxseg000:0041DBC5                 pop     ebxseg000:0041DBC6                 add     esp, 6Chseg000:0041DBC9                 retn                    ; 到这里的话也是over哦seg000:0041DBCA ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━seg000:0041DBCA seg000:0041DBCA lbl_Next2:                              ; CODE XREF: lbl_CheckSn+2Fjseg000:0041DBCA                 mov     edi, ebp        ; 注册码入ediseg000:0041DBCC                 or      ecx, 0FFFFFFFFhseg000:0041DBCF                 xor     eax, eaxseg000:0041DBD1                 push    esiseg000:0041DBD2                 repne scasb             ; 这里再次计算注册码的长度seg000:0041DBD4                 not     ecxseg000:0041DBD6                 dec     ecxseg000:0041DBD7                 lea     eax, [esp+7Ch+var_5C]seg000:0041DBDB                 mov     ebx, ecx        ; 注册码长度入EBXseg000:0041DBDD                 push    eaxseg000:0041DBDE                 add     ebx, 4seg000:0041DBE1                 shr     ebx, 1          ; 如果没有什么意外的话就到这里seg000:0041DBE3                 call    lbl_InitMD5     ; 这里跟进后可以看到是MD5算法来的进来看看吧:seg000:0041C7F0 ; 〓〓〓〓〓〓〓〓 S U B R O U T I N E  〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓seg000:0041C7F0 seg000:0041C7F0 seg000:0041C7F0 lbl_InitMD5     proc near               ; CODE XREF: sub_409E20+128pseg000:0041C7F0                                         ; sub_414D80+8p ...seg000:0041C7F0 seg000:0041C7F0 arg_0           = dword ptr  4seg000:0041C7F0 seg000:0041C7F0                 mov     eax, [esp+arg_0]seg000:0041C7F4                 xor     ecx, ecxseg000:0041C7F6                 mov     dword ptr [eax], 67452301h            ;看到这些东西就不用我再说了吧seg000:0041C7FC                 mov     dword ptr [eax+4], 0EFCDAB89hseg000:0041C803                 mov     dword ptr [eax+8], 98BADCFEhseg000:0041C80A                 mov     dword ptr [eax+0Ch], 10325476hseg000:0041C811                 mov     [eax+10h], ecxseg000:0041C814                 mov     [eax+14h], ecxseg000:0041C817                 mov     [eax+58h], ecxseg000:0041C81A                 retnseg000:0041C81A lbl_InitMD5     endpseg000:0041C81A seg000:0041C81A ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━看完后,回到老地方:seg000:0041DBE9                 lea     ecx, [esp+84h+var_5C]seg000:0041DBED                 push    ebp             ; 注册码入栈seg000:0041DBEE                 push    ecxseg000:0041DBEF                 call    sub_41C820seg000:0041DBF4                 lea     edx, [esp+8Ch+var_5C]seg000:0041DBF8                 lea     eax, [esp+8Ch+var_6C]seg000:0041DBFC                 push    edxseg000:0041DBFD                 push    eaxseg000:0041DBFE                 call    sub_41D8B0seg000:0041DC03                 add     esp, 18hseg000:0041DC06                 mov     ecx, 4seg000:0041DC0B                 mov     edi, offset unk_43714Cseg000:0041DC10                 lea     esi, [esp+7Ch+var_6C]seg000:0041DC14                 xor     edx, edxseg000:0041DC16                 repe cmpsdseg000:0041DC18                 pop     esiseg000:0041DC19                 jz      short lbl_Next3 ; ****  看到MD5我就头疼,一疼就一直按f8跑到这里,seg000:0041DC19                                         ; 这里一定要跳,seg000:0041DC1B                 pop     ediseg000:0041DC1C                 pop     ebpseg000:0041DC1D                 xor     eax, eaxseg000:0041DC1F                 pop     ebxseg000:0041DC20                 add     esp, 6Chseg000:0041DC23                 retnseg000:0041DC24 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━seg000:0041DC24 seg000:0041DC24 lbl_Next3:                              ; CODE XREF: lbl_CheckSn+89jseg000:0041DC24                 lea     eax, [esp+78h+var_5C]seg000:0041DC28                 push    eaxseg000:0041DC29                 call    lbl_InitMD5seg000:0041DC2E                 mov     edi, ebpseg000:0041DC30                 or      ecx, 0FFFFFFFFhseg000:0041DC33                 xor     eax, eaxseg000:0041DC35                 repne scasbseg000:0041DC37                 not     ecxseg000:0041DC39                 dec     ecxseg000:0041DC3A                 push    ecxseg000:0041DC3B                 lea     ecx, [esp+80h+var_5C]seg000:0041DC3F                 push    ebp             ; 注册码入栈seg000:0041DC40                 push    ecxseg000:0041DC41                 call    sub_41C820seg000:0041DC46                 lea     edx, [esp+88h+var_5C]seg000:0041DC4A                 lea     eax, [esp+88h+var_6C]seg000:0041DC4E                 push    edxseg000:0041DC4F                 push    eaxseg000:0041DC50                 call    sub_41D8B0seg000:0041DC55                 lea     ecx, [esp+90h+var_6C]seg000:0041DC59                 push    ecxseg000:0041DC5A                 call    sub_41DB20seg000:0041DC5F                 add     esp, 1Chseg000:0041DC62                 test    eax, eaxseg000:0041DC64                 jnz     short lbl_Next4 ; ***** 不一会按F8到了这里,这里也要跳哦.seg000:0041DC66                 pop     ediseg000:0041DC67                 pop     ebpseg000:0041DC68                 pop     ebxseg000:0041DC69                 add     esp, 6Chseg000:0041DC6C                 retnseg000:0041DC6D ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━seg000:0041DC6D seg000:0041DC6D lbl_Next4:                              ; CODE XREF: lbl_CheckSn+D4jseg000:0041DC6D                 mov     eax, ds:dword_43BE40seg000:0041DC72                 test    eax, eaxseg000:0041DC74                 jnz     short lbl_RegOK ; ***** 呵呵一不小心就跳到光明之处了,这里也跳,不跳也完了seg000:0041DC76                 push    ebxseg000:0041DC77                 push    ebpseg000:0041DC78                 call    sub_41DA80seg000:0041DC7D                 add     esp, 8seg000:0041DC80                 mov     ds:dword_43BE40, 1seg000:0041DC8A seg000:0041DC8A lbl_RegOK:                              ; CODE XREF: lbl_CheckSn+E4jseg000:0041DC8A                 pop     ediseg000:0041DC8B                 pop     ebp             ; 呵呵看到注册码出栈了吧seg000:0041DC8C                 mov     eax, 1          ; 这里赋eax为1,如果注册成功的话seg000:0041DC91                 pop     ebxseg000:0041DC92                 add     esp, 6Chseg000:0041DC95                 retnseg000:0041DC95 lbl_CheckSn     endp 到这里就知道怎么强暴了吧,改那几个用*的地方,改成jmp XXX:0041DC19   . EB 09         JMP SHORT dumped1_.0041DC240041DC64   . EB 07         JMP SHORT dumped1_.0041DC6D0041DC74   . EB 14         JMP SHORT dumped1_.0041DC8A改好后,保存一下,再运行看一下,是不是已经注册了,这样就收工了?你不觉得改三个地方,改的太多了点吗?既然是强暴,当然要怎么样快就改哪里了,我的改法:seg000:0041DB90 seg000:0041DB90                 sub     esp, 6Ch        ;改这里seg000:0041DB93                 or      ecx, 0FFFFFFFFhseg000:0041DB96                 xor     eax, eaxseg000:0041DB98                 push    ebx改为:0041DB90   B8 01000000   MOV EAX,10041DB95  C3            RETN这里够爽了吧,到了这里也就全部操作完成,因这个软件纯用来做教学的,所以不敢保证没有暗桩哦,如果你发现有暗桩或有什么别人好的方法或搞定了全部的算法,请告之本人,谢谢!   特别感谢老菜鸟给我一个好我武器IDA,没有他,可能我今天还是用w32dasm写文章给大家看.也算是我的IDA NO1 TUT吧!Greetz: Fly.Jingulong,yock,tDasm.David.ahao.vcasm.UFO(brother).alan(sister).all of my friends and you! By loveboom[DFCG][FCG]Email:[email protected] 

本文地址:http://com.8s8s.com/it/it22392.htm