首页
社区
课程
招聘
[原创]新手补给之脱壳2——ExeCryptor
发表于: 2009-6-25 23:58 2613

[原创]新手补给之脱壳2——ExeCryptor

2009-6-25 23:58
2613
  【文章标题】: 新手补给之脱壳2——ExeCryptor
  【文章作者】: rocktx
  【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
  --------------------------------------------------------------------------------
  【详细过程】
  
  为了方便新手了解 ExeCryptor 的常规脱法,特炮制下面两篇脱文,希望有所帮助;
  加壳程序链接:
  1、鸡蛋壳的notepad1:http://bbs.pediy.com/showthread.php?p=66978#poststop
  2、happytown的unpackme:http://bbs.pediy.com/showthread.php?p=283261#poststop
  
  所用工具:
  Ollydbg v1.1 with HideOD v0.181插件or StrongOD 插件
  ImportRec v1.6 with Execryptor插件
  LorePE;
  
  OD设置:
  【调试设置】-【事件】-【首次暂停的停止位置】-【系统断点】、忽略所有异常(即:异常选项全部打勾)
  ------------------------------------------------------------------------
  
  脱文一:鸡蛋壳的notepad1
  
  一、寻找OEP
  
  OD载入,停在
  
  7C901231     C3                            retn
  7C901232     8BFF                          mov edi,edi
  7C901234     90                            nop
  7C901235     90                            nop
  7C901236     90                            nop
  7C901237     90                            nop
  7C901238     90                            nop
  7C901239 n>  CC                            int3
  7C90123A     C3                            retn
  
  Alt+B检查一下,清除所有断点,HideOD隐藏一下,Alt+M打开内存镜像,在code段下内存访问断点,Shift+F9运行几次,直到
  
  0103425B     AA                            stos byte ptr es:[edi]                 ; 停在这里,清除内存断点
  0103425C   ^ EB E9                         jmp short notepad1.01034247
  0103425E     E8 FC000000                   call notepad1.0103435F
  01034263     0F82 97000000                 jb notepad1.01034300
  01034269     E8 F1000000                   call notepad1.0103435F
  0103426E     73 5B                         jnb short notepad1.010342CB
  01034270     B9 04000000                   mov ecx,4
  01034275     E8 FD000000                   call notepad1.01034377
  0103427A     48                            dec eax
  
  往下找到
  
  01034383     31C9                          xor ecx,ecx
  01034385     41                            inc ecx
  01034386     E8 D4FFFFFF                   call notepad1.0103435F
  0103438B     11C9                          adc ecx,ecx
  0103438D     E8 CDFFFFFF                   call notepad1.0103435F
  01034392   ^ 72 F2                         jb short notepad1.01034386
  01034394     C3                            retn
  01034395     8BE5                          mov esp,ebp
  01034397     5D                            pop ebp
  01034398     C3                            retn                                   ; F4到这里
  01034399     90                            nop
  0103439A     0F85 66110000                 jnz notepad1.01035506
  
  再去内存镜像code段下个内存访问断点,Shift+F9运行,断在
  
  01023112     AC                            lods byte ptr ds:[esi]                 ; 停在这里,清除内存断点
  01023113     D0E8                          shr al,1
  01023115     80F8 74                       cmp al,74
  01023118     75 0E                         jnz short notepad1.01023128
  0102311A     8B06                          mov eax,dword ptr ds:[esi]
  0102311C     0FC8                          bswap eax
  0102311E     01C8                          add eax,ecx
  01023120     8906                          mov dword ptr ds:[esi],eax
  01023122     83C6 04                       add esi,4
  01023125     83E9 04                       sub ecx,4
  01023128     49                            dec ecx
  01023129   ^ 7F E7                         jg short notepad1.01023112
  0102312B     59                            pop ecx
  0102312C     5E                            pop esi
  0102312D     C3                            retn                                   ; F4到这里
  
  再到内存镜像的code段下内存访问断点,Shift+F9运行,断在:
  
  01019B93     F700 0000FFFF                 test dword ptr ds:[eax],FFFF0000       
  01019B99     0F85 18460000                 jnz notepad1.0101E1B7
  01019B9F     E9 4C8F0000                   jmp notepad1.01022AF0                  
  01019BA4     81CA E12D00BF                 or edx,BF002DE1
  01019BAA     81C2 5F2EC9BB                 add edx,BBC92E5F
  01019BB0     03D5                          add edx,ebp
  01019BB2     81C2 A2D39084                 add edx,8490D3A2
  
  按照常规,如果程序是用Delphi写的,这一步可以直达OEP,但由于VC程序输入表也在code段,所以这里一般是壳代码在处理IAT;
  现在清除内存断点,F4到 01019B9F 处后,到code段下内存访问断点,Shift+F9运行两次,断在:
  
  0101E1B5     8902                          mov dword ptr ds:[edx],eax               ; GDI32.TextOutW
  0101E1B7     8345 E8 04                    add dword ptr ss:[ebp-18],4
  0101E1BB   ^ E9 DB3FFFFF                   jmp notepad1.0101219B
  0101E1C0   ^ 0F8E 53D4FFFF                 jle notepad1.0101B619
  
  想研究壳是怎么处理IAT的,从这里开始跟就可以了;
  清除内存断点,F8单步跟踪,来到
  
  010224ED     FF45 E0                       inc dword ptr ss:[ebp-20]
  010224F0     FF4D D4                       dec dword ptr ss:[ebp-2C]
  010224F3   ^ 0F85 C85DFFFF                 jnz notepad1.010182C1
  010224F9   ^ E9 5EA1FFFF                   jmp notepad1.0101C65C                    ; F4到这里
  
  继续跟踪到
  
  0101D8CC   ^\0F80 50A8FFFF                 jo notepad1.01018122
  0101D8D2     8B45 FC                       mov eax,dword ptr ss:[ebp-4]
  0101D8D5     8378 04 00                    cmp dword ptr ds:[eax+4],0
  0101D8D9     0F87 481A0000                 ja notepad1.0101F327
  0101D8DF   ^ E9 A677FFFF                   jmp notepad1.0101508A                    ; F4到这里
  
  最后再到code段下内存访问断点,Shift+F9运行,如果跳出未注册提示,点确定即可到达OEP:
  
  01006420     55                            push ebp
  01006421     8BEC                          mov ebp,esp
  01006423     6A FF                         push -1
  01006425     68 88180001                   push notepad1.01001888
  0100642A     68 D0650001                   push notepad1.010065D0                   ; jmp 到
  0100642F     64:A1 00000000                mov eax,dword ptr fs:[0]
  01006435     50                            push eax
  01006436     64:8925 00000000              mov dword ptr fs:[0],esp
  0100643D     83C4 98                       add esp,-68
  01006440     53                            push ebx
  01006441     56                            push esi
  01006442     57                            push edi
  01006443     8965 E8                       mov dword ptr ss:[ebp-18],esp
  01006446     C745 FC 00000000              mov dword ptr ss:[ebp-4],0
  0100644D     6A 02                         push 2
  0100644F     FF15 60110001                 call dword ptr ds:[1001160]              ; msvcrt.__set_app_type
  01006455     83C4 04                       add esp,4
  
  dump一下吧,推荐使用LordPE;
  
  二、修复IAT
  
  dump后,关闭OD,直接运行程序,用ImportRec载入,用OEP的RVA自动获取IAT,无效指针先用跟踪级别3修复,然后用Execryptor插件修复剩余的,最后剪切掉无效指针,Fix dump即可;
  
  三、优化减肥
  
  1、用LordPE将脱壳后程序的Tls表清零,以解决程序运行异常的问题;
  2、将BaseOfCode改成1000,解决代码无法分析的问题;
  3、删除倒数第2~4三个区段,把壳扔掉;
  
  提示:如果在脱壳过程中,程序跑飞,一般是OD没隐藏好;
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  脱文二:happytown的unpackme
  
  一、寻找OEP
  
  OD载入程序,用HideOD隐藏一下,清除所有断点,Alt+M打开内存镜像,在code段下内存访问断点,Shift+F9运行,断在:
  
  004A1001     F3:A4                         rep movs byte ptr es:[edi],byte ptr ds>        ; 断在这里
  004A1003     31DB                          xor ebx,ebx
  004A1005     5E                            pop esi
  004A1006   ^ EB 9D                         jmp short Unpackme.004A0FA5
  004A1008     89F0                          mov eax,esi
  004A100A     5B                            pop ebx
  004A100B     5F                            pop edi
  004A100C     5E                            pop esi
  004A100D     C3                            retn                                           ; 清除内存断点,F4到这里
  
  继续在code段下内存访问断点,Shift+F9运行,断在:
  
  0046013E     AC                            lods byte ptr ds:[esi]                         ; 断在这里
  0046013F     D0E8                          shr al,1
  00460141     80F8 74                       cmp al,74
  00460144     75 0E                         jnz short Unpackme.00460154
  00460146     8B06                          mov eax,dword ptr ds:[esi]
  00460148     0FC8                          bswap eax
  0046014A     01C8                          add eax,ecx
  0046014C     8906                          mov dword ptr ds:[esi],eax
  0046014E     83C6 04                       add esi,4
  00460151     83E9 04                       sub ecx,4
  00460154     49                            dec ecx
  00460155   ^ 7F E7                         jg short Unpackme.0046013E
  00460157     59                            pop ecx
  00460158     5E                            pop esi
  00460159     C3                            retn                                           ; 清除内存断点,F4到这里
  
  继续在code段下内存访问断点,Shift+F9运行,断在OEP处:
  
  00401E73     81C3 FE36B5A8                 add ebx,A8B536FE                               ; 断在这里
  00401E79   - E9 82110200                   jmp Unpackme.00423000
  00401E7E     3F                            aas
  00401E7F     3A2E                          cmp ch,byte ptr ds:[esi]
  00401E81     5C                            pop esp
  00401E82     C8 506489                     enter 6450,89
  00401E86     25 00000000                   and eax,0
  00401E8B     83EC 58                       sub esp,58
  00401E8E     53                            push ebx
  00401E8F     56                            push esi
  00401E90     57                            push edi
  00401E91     8965 E8                       mov dword ptr ss:[ebp-18],esp
  00401E94     FF15 AC314100                 call dword ptr ds:[4131AC]                     ; Unpackme.00436679
  
  虽然OEP处有Stolen Code,但是从 00401E8B 处开始是正常代码, 所以清除内存断点,直接F4到 00401E8B,查看堆栈:
  
  0013FCC8   0013FCDC  指针到下一个 SEH 记录
  0013FCCC   00404A90  SE 句柄
  0013FCD0   00414558  Unpackme.00414558
  0013FCD4   FFFFFFFF
  0013FCD8   0013FFF0
  
  由于是VC写的,可将OEP代码还原为:
  
  00401E6E d>/$  55                          push ebp
  00401E6F   |.  8BEC                        mov ebp,esp
  00401E71   |.  6A FF                       push -1
  00401E73   |.  68 58454100                 push dumped_1.00414558
  00401E78   |.  68 904A4000                 push dumped_1.00404A90                
  00401E7D   |.  64:A1 00000000              mov eax,dword ptr fs:[0]
  00401E83   |.  50                          push eax
  00401E84   |.  64:8925 00000000            mov dword ptr fs:[0],esp
  00401E8B   |.  83EC 58                     sub esp,58
  00401E8E   |.  53                          push ebx
  00401E8F   |.  56                          push esi
  00401E90   |.  57                          push edi
  00401E91   |.  8965 E8                     mov dword ptr ss:[ebp-18],esp
  00401E94     FF15 AC314100                 call dword ptr ds:[4131AC]                     ; Unpackme.00436679
  
  现在的OEP是 00401E6E,dump吧;
  
  二、获取IAT
  参照脱文一;
  
  二、优化减肥
  参照脱文一;
  ----------------------------------------------------------------------------
  
  附:
  1、wynney的ExeCryptor 2.2.X 脱壳:http://bbs.pediy.com/showthread.php?p=213209#poststop
  2、一篇英文教程:Unpacking ExeCryptor 2.2.4 (见附件)

  
  --------------------------------------------------------------------------------
  【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年06月26日 0:13:09

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回