[原创] 简单修复Themida加壳的VC7+去除软件自校验 您所在的位置:网站首页 0012ff60 [原创] 简单修复Themida加壳的VC7+去除软件自校验

[原创] 简单修复Themida加壳的VC7+去除软件自校验

2023-09-30 14:43| 来源: 网络整理| 查看: 265

【文章标题】: 简单修复Themida加壳的VC7+去除软件自校验 【文章作者】: wuhanqi 【作者邮箱】: [email protected] 【下载地址】: 自己搜索下载 【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! -------------------------------------------------------------------------------- 【详细过程】   题外话:    其实这个VC7的程序我本来都放一边了,因为实在是找不到对比OEP的无壳程序,可是昨天Nisy 老大发给我一个蛮有意思的注册验证程序,DJ Java Decompiler 3.11,无壳的,我用OD载入后一看到Push 60就一下子想起了这个TMD加壳的VC7,遂有了此文。      加壳程序是国产的。我就不透漏名称了。      这就是无壳程序的OEP:   00477F88 > $  6A 60         PUSH 60   00477F8A   .  68 30805000   PUSH 00508030   00477F8F   .  E8 744D0000   CALL 0047CD08   00477F94   .  BF 94000000   MOV EDI,94   00477F99   .  8BC7          MOV EAX,EDI   00477F9B   .  E8 70FEFFFF   CALL 00477E10   00477FA0   .  8965 E8       MOV DWORD PTR SS:[EBP-18],ESP   00477FA3   .  8BF4          MOV ESI,ESP   00477FA5   .  893E          MOV DWORD PTR DS:[ESI],EDI   00477FA7   .  56            PUSH ESI                                 ; /pVersionInformation   00477FA8   .  FF15 78934F00 CALL DWORD PTR DS:[; \GetVersionExA   00477FAE   .  8B4E 10       MOV ECX,DWORD PTR DS:[ESI+10]   00477FB1   .  890D CC465400 MOV DWORD PTR DS:[5446CC],ECX   00477FB7   .  8B46 04       MOV EAX,DWORD PTR DS:[ESI+4]   00477FBA   .  A3 D8465400   MOV DWORD PTR DS:[5446D8],EAX   00477FBF   .  8B56 08       MOV EDX,DWORD PTR DS:[ESI+8]   00477FC2   .  8915 DC465400 MOV DWORD PTR DS:[5446DC],EDX   00477FC8   .  8B76 0C       MOV ESI,DWORD PTR DS:[ESI+C]   00477FCB   .  81E6 FF7F0000 AND ESI,7FFF   00477FD1   .  8935 D0465400 MOV DWORD PTR DS:[5446D0],ESI   00477FD7   .  83F9 02       CMP ECX,2   00477FDA   .  74 0C         JE SHORT 00477FE8   00477FDC   .  81CE 00800000 OR ESI,8000   00477FE2   .  8935 D0465400 MOV DWORD PTR DS:[5446D0],ESI   00477FE8   >  C1E0 08       SHL EAX,8   00477FEB   .  03C2          ADD EAX,EDX   00477FED   .  A3 D4465400   MOV DWORD PTR DS:[5446D4],EAX   00477FF2   .  33F6          XOR ESI,ESI   00477FF4   .  56            PUSH ESI                                 ; /pModule => NULL   00477FF5   .  8B3D 5C934F00 MOV EDI,DWORD PTR DS:[; |kernel32.GetModuleHandleA   00477FFB   .  FFD7          CALL EDI                                 ; \GetModuleHandleA   00477FFD   .  66:8138 4D5A  CMP WORD PTR DS:[EAX],5A4D   00478002   .  75 1F         JNZ SHORT 00478023         废话不多说了,OD载入程序打开内存镜像看TMDBASE是多少,565000,用编辑工具修改一下Nooby牛的脚本,然后跑脚本...这个过程我就不多叙述了。   脚本结束后停在OEP附近的第一个CALL中。   00471940    68 A0F14600     push 0046F1A0   00471945    64:A1 00000000  mov eax,dword ptr fs:[0]   0047194B    50              push eax   0047194C    8B4424 10       mov eax,dword ptr ss:[esp+10]   00471950    896C24 10       mov dword ptr ss:[esp+10],ebp   00471954    8D6C24 10       lea ebp,dword ptr ss:[esp+10]   00471958    2BE0            sub esp,eax   0047195A    53              push ebx   0047195B    56              push esi   0047195C    57              push edi   0047195D    8B45 F8         mov eax,dword ptr ss:[ebp-8]   00471960    8965 E8         mov dword ptr ss:[ebp-18],esp   00471963    50              push eax   00471964    8B45 FC         mov eax,dword ptr ss:[ebp-4]   00471967    C745 FC FFFFFFF>mov dword ptr ss:[ebp-4],-1   0047196E    8945 F8         mov dword ptr ss:[ebp-8],eax   00471971    8D45 F0         lea eax,dword ptr ss:[ebp-10]   00471974    64:A3 00000000  mov dword ptr fs:[0],eax   0047197A    C3              retn      看堆栈:   0012FF54   007FE908  SuperRec.007FE908   0012FF58   0049F740  SuperRec.0049F740  第②句PUSH   0012FF5C   00000060                     第①句PUSH   0012FF60   00400208  ASCII "   "   0012FF64   0012FFC4   0012FF68   00792EB8  SuperRec.00792EB8      可以猜出前三句OEP为   push 60   push 0049f740   call 00471940      接下来走出这个call。   007FE908    68 16EB2925     push 2529EB16   007FE90D  ^ E9 29B9FFFF     jmp 007FA23B      单步走过上面的jmp,来到:   007FA23B    6A 00           push 0   007FA23D    0F89 15000000   jns 007FA258      打开内存镜像。在00401000段F2,然后F9,停在OEP附近第二个call处。   00470540    3D 00100000     cmp eax,1000   00470545    73 0E           jnb short 00470555   00470547    F7D8            neg eax   00470549    03C4            add eax,esp   0047054B    83C0 04         add eax,4   0047054E    8500            test dword ptr ds:[eax],eax   00470550    94              xchg eax,esp   00470551    8B00            mov eax,dword ptr ds:[eax]   00470553    50              push eax   00470554    C3              retn      此时可以对比无壳的程序看一下代码,这是无壳的前几句:   00477F88 > $  6A 60         PUSH 60   00477F8A   .  68 30805000   PUSH 00508030   00477F8F   .  E8 744D0000   CALL 0047CD08   00477F94   .  BF 94000000   MOV EDI,94   00477F99   .  8BC7          MOV EAX,EDI   00477F9B   .  E8 70FEFFFF   CALL 00477E10   00477FA0   .  8965 E8       MOV DWORD PTR SS:[EBP-18],ESP      再看看我们的寄存器。   EAX 00000094   ECX 00020048   EDX 00020048   EBX 0012FF64   ESP 0012FEDC   EBP 0012FF5C   ESI F63945F1   EDI 00000094   EIP 00470540 SuperRec.00470540      的确EDI与EAX都变红而且都为94      那接下来三句就是 mov edi,94 mov eax,edi call 00470540      接下来走出这个call:   007FE91A    68 7FE9110B     push 0B11E97F   007FE91F  ^ E9 17B9FFFF     jmp 007FA23B      依旧走过这个jmp后在code段下断再F9   此时停在这里:   019F8947    FF33            push dword ptr ds:[ebx]                  ; kernel32.GetVersionExA   019F8949  ^ E9 F580F5FF     jmp 01950A43      看信息窗口:   ds:[004932AC]=77AB9D76 (kernel32.GetVersionExA)      这个地址很关键,我们可以对照着看无壳程序的OEP,在下一个call就是call这个函数,   那这个call就应该这样写了:call dword ptr ds:[004932ac]      又因为VC7的OEP相对固定,   那接下来几句就是:   MOV DWORD PTR SS:[EBP-18],ESP   MOV ESI,ESP   MOV DWORD PTR DS:[ESI],EDI   PUSH ESI      call dword ptr ds:[004932ac]       插句题外话:其实你记不住这个地址也没问题,因为GetVersionExA和GetModuleHandleA在IAT输入表里很接近.而程序下面就就有调用GetModuleHandleA,找到了GetModuleHandleA就等于找到了GetVersionExA.   我们再继续走jmp下code段的断点。此过程我就不做记录了。   值的注意的是走到这里的时候:   019FD621    F3:A4           rep movs byte ptr es:[edi],byte ptr ds:[>   019FD623    68 016D0000     push 6D01   019FD628    890C24          mov dword ptr ss:[esp],ecx      在019fd621需要是F7再F8,否则程序跑飞,前功尽弃。   最终我们停在这里:   0046EF05    A3 00B65100     mov dword ptr ds:[51B600],eax   0046EF0A    8B56 08         mov edx,dword ptr ds:[esi+8]   0046EF0D    8915 04B65100   mov dword ptr ds:[51B604],edx   0046EF13    8B76 0C         mov esi,dword ptr ds:[esi+C]   0046EF16    81E6 FF7F0000   and esi,7FFF   0046EF1C    8935 F8B55100   mov dword ptr ds:[51B5F8],esi   0046EF22    83F9 02         cmp ecx,2   0046EF25    74 0C           je short 0046EF33   0046EF27    81CE 00800000   or esi,8000   0046EF2D    8935 F8B55100   mov dword ptr ds:[51B5F8],esi   0046EF33    C1E0 08         shl eax,8   0046EF36    03C2            add eax,edx   0046EF38    A3 FCB55100     mov dword ptr ds:[51B5FC],eax   0046EF3D    33F6            xor esi,esi   0046EF3F    56              push esi   0046EF40    8B3D A8324900   mov edi,dword ptr ds:[4932A8]            ; kernel32.GetModuleHandleA   0046EF46    FFD7            call edi   0046EF48    66:8138 4D5A    cmp word ptr ds:[eax],5A4D      上面距离call GetVersionExA 这个函数依旧还有三句话:   这是无壳程序的那三句话:   00477FAE   .  8B4E 10       MOV ECX,DWORD PTR DS:[ESI+10]   00477FB1   .  890D CC465400 MOV DWORD PTR DS:[5446CC],ECX   00477FB7   .  8B46 04       MOV EAX,DWORD PTR DS:[ESI+4]   00477FBA   .  A3 D8465400   MOV DWORD PTR DS:[5446D8],EAX      这下有人晕了,这可怎么搞,没有地址怎么修复?   其实很简单,我们用无壳程序的这两句地址相减,即5446d8-5446cc=c   那我们需要的那个地址就应该是 51b600-c=51B5F4      那我们加壳程序的接下来三句就应该是:   MOV ECX,DWORD PTR DS:[ESI+10]   MOV DWORD PTR DS:[51B5F4],ECX   MOV EAX,DWORD PTR DS:[ESI+4]      总结一下被偷的OEP就是:   push 60   push 0049f740   call 00471940   mov edi,94   mov eax,edi   call 00470540   MOV DWORD PTR SS:[EBP-18],ESP   MOV ESI,ESP   MOV DWORD PTR DS:[ESI],EDI   PUSH ESI      call dword ptr ds:[004932ac]   MOV ECX,DWORD PTR DS:[ESI+10]   MOV DWORD PTR DS:[51B5F4],ECX   MOV EAX,DWORD PTR DS:[ESI+4]         这样脱好壳之后,运行程序,窗口一闪而过。   自校验。。   我用的是bp GetFileSize   因为程序是窗口一闪而过,所以要在显示窗口后再返回程序。   返回程序领空只需要F8即可来到这里:   0042A126   > \3B7424 20     cmp esi,dword ptr ss:[esp+20]   0042A12A   .  74 14         je short 0042A140   0042A12C   .  8B5424 24     mov edx,dword ptr ss:[esp+24]   0042A130   .  8B42 2C       mov eax,dword ptr ds:[edx+2C]   0042A133   .  53            push ebx                                 ; /lParam   0042A134   .  53            push ebx                                 ; |wParam   0042A135   .  6A 12         push 12                                  ; |Message = WM_QUIT   0042A137   .  50            push eax                                 ; |ThreadId   0042A138   .  90            nop                                      ; |   0042A139   .  E8 50DB1877   call user32.PostThreadMessageW           ; \PostThreadMessageW   0042A13E   .  EB 15         jmp short 0042A155   0042A140   >  57            push edi   0042A141   .  E8 FC580500   call 0047FA42   0042A146   .  8B8D 68AB0200 mov ecx,dword ptr ss:[ebp+2AB68]   0042A14C   .  83C4 04       add esp,4   0042A14F   .  C701 08000000 mov dword ptr ds:[ecx],8   0042A155   >  8D4C24 28     lea ecx,dword ptr ss:[esp+28]   0042A159   .  885C24 40     mov byte ptr ss:[esp+40],bl   0042A15D   .  E8 6A700500   call 004811CC   0042A162   .  5D            pop ebp      把42a12a的74改成eb即可。   第一次看到结束程序用PostThreadMessageW的这个函数的。。    -------------------------------------------------------------------------------- 【经验总结】   其实VC7的OEP真的很好修复的.不是一般的好修复.   只不过很难找到一个门当户对的无壳程序来对比OEP修复.   这次是我运气好,也感谢Nisy老大~呵呵.    -------------------------------------------------------------------------------- 【版权声明】: 菜鸟一个,没啥版权..                                                        2009年08月10日 8:59:29

[培训]《安卓高级研修班(网课)》月薪三万计划



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有