首页
社区
课程
招聘
[原创]手脱WinUpack 0.399壳
发表于: 2007-12-29 19:43 5893

[原创]手脱WinUpack 0.399壳

2007-12-29 19:43
5893
////////////////////////////////////////////////////////////////////////////////////////////
文件名称:手脱WinUpack 0.399壳
目标程序:病毒样本“泡泡”恶意程序
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2007年12月16日
联系方式:coderui@163.com
作者博客:114K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3c8W2M7Y4g2A6

---------------------------------------------------------------------------------------------
介绍:

    0.399版的WinUpack壳会使PEID在扫描时崩溃。使OD在加载时提示“错误:32 位可执行文件 'C:\auto.exe' 的格式错误或格式未知”,确定后OD停在ntdll里,无法返回到主程序领空。
    一年前就遇到过这个壳,以前不知道叫什么名字,后来得到了这个壳的加壳程序,终于知道是什么壳了,但一直还是不会脱(因为无法跟,加载后停在系统DLL里,单步跟N久后还是在系统DLL里转,一生气想用[ALT+F9]返回主程序领空,结果程序就会跑飞运行了)。
    今天因为要动态调试分析一个病毒,结果加的就是这个壳,郁闷。这个病毒会释放不只一个DLL恶意组件加载运行(超级流氓软件类),被我跑飞2次,呵呵。后来一个网上的朋友帮用脱壳机给脱掉了,然后发给了我。虽然把脱掉壳后的病毒分析完了,心理感觉不爽,既然脱壳机可以脱,我就一定要手脱。结果发现,原来使用对“GetProcAddress”API下断脱这个壳这么简单(使用类似技术的壳都可以拿这种方法去对付),所以就记录下了手脱的过程。在网上没找到0.399版WinUpack壳的脱文,为了方便就发出来与大家分享下吧,希望对需要的朋友有帮助~_~。
---------------------------------------------------------------------------------------------
重点:

    方法1:OD设置:不忽略任何异常。

OD加载程序停在入口点->下命令bp GetProcAddress断点->[F9]运行(可能需要运行多次才能看到返回值是到主程序领空)->当返回值到主程序领空时,[F2]清除断点->下当前函数返回用户空间地址的断点(方法1:硬件断点hr esp值。方法2:在反汇编窗口按[SHIFT+G],输入“[esp]”包括大括号,而且esp是字母,不是esp值)->确定->返回到用户空间后,向下找2条指令,第一个retn指令(JMP指令后边的retn指令),它指向的就是入口点了->然后用工具修复输入表就可以了。

    方法2:OD设置:不忽略任何异常。

OD加载程序停在入口点->下命令bp LoadLibraryA断点->[F9]运行->[F2]清除断点->下当前函数返回用户空间地址的断点(方法1:硬件断点hr esp值。方法2:在反汇编窗口按[SHIFT+G],输入“[esp]”包括大括号,而且esp是字母,不是esp值)->确定->返回到用户空间后,向下找(20条指令之内)第一个retn指令,它指向的就是入口点了->然后用工具修复输入表就可以了。
---------------------------------------------------------------------------------------------
OD设置:不忽略任何异常。

7C921231    C3              RETN                                     ;载入后停在这里。我们对“GetProcAddress”API下断(BP GetProcAddress)后F9运行。
7C921232    8BFF            MOV EDI,EDI
7C921234    90              NOP
7C921235    90              NOP
7C921236    90              NOP
7C921237    90              NOP
7C921238    90              NOP
7C921239 > CC              INT3
7C92123A    C3              RETN
7C92123B    90              NOP
7C92123C    8BFF            MOV EDI,EDI
7C92123E    90              NOP
7C92123F    90              NOP
7C921240    90              NOP
7C921241    90              NOP
7C921242    90              NOP
7C921243    8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]
7C921247    CC              INT3
7C921248    C2 0400         RETN 4
            .
            .
            .
7C80ADA0 > 8BFF            MOV EDI,EDI                              ;运行后停在这里。我们看 CALL GetProcAddress 的返回地址,当前是77C079C2(地址不唯一),不在主程序领空(如果地址开头是004这样的,在主程序领空的话,就不要F9了),我们继续F9一次。
7C80ADA2    55              PUSH EBP
7C80ADA3    8BEC            MOV EBP,ESP
7C80ADA5    51              PUSH ECX
7C80ADA6    51              PUSH ECX
7C80ADA7    53              PUSH EBX
7C80ADA8    57              PUSH EDI
7C80ADA9    8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
7C80ADAC    BB FFFF0000     MOV EBX,0FFFF
7C80ADB1    3BFB            CMP EDI,EBX
7C80ADB3 ^ 0F86 D1F2FFFF   JBE kernel32.7C80A08A
7C80ADB9    57              PUSH EDI
7C80ADBA    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
7C80ADBD    50              PUSH EAX
7C80ADBE    FF15 8812807C   CALL DWORD PTR DS:[<&ntdll.RtlInitString>; ntdll.RtlInitString
            .
            .
            .
7C80ADA0 > 8BFF            MOV EDI,EDI                              ;运行后停在这里(老地方正常,因为我们就只在这一个地方下断了)。我们看 CALL GetProcAddress 的返回地址,当前是0041EEF4(地址不唯一),因为是004所以在主程序领空了,我们F2取消断点,然后跟随到返回地址处(快捷键按[Ctrl+G])输入0041EEF4,确定。
7C80ADA2    55              PUSH EBP
7C80ADA3    8BEC            MOV EBP,ESP
7C80ADA5    51              PUSH ECX
7C80ADA6    51              PUSH ECX
7C80ADA7    53              PUSH EBX
7C80ADA8    57              PUSH EDI
7C80ADA9    8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
7C80ADAC    BB FFFF0000     MOV EBX,0FFFF
7C80ADB1    3BFB            CMP EDI,EBX
7C80ADB3 ^ 0F86 D1F2FFFF   JBE kernel32.7C80A08A
7C80ADB9    57              PUSH EDI
7C80ADBA    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
7C80ADBD    50              PUSH EAX
7C80ADBE    FF15 8812807C   CALL DWORD PTR DS:[<&ntdll.RtlInitString>; ntdll.RtlInitString
            .
            .
            .
0041EEF4    AB              STOS DWORD PTR ES:[EDI]                  ;跟随到这里后,在这里按F2下断,然后F9运行,运行后就会停在这里。现在终于来到主程序领空了,F2取消断点后F8单步向下走。
0041EEF5 ^ EB E7           JMP SHORT auto.0041EEDE                  ;到这里不要跳,回头看看上边的代码。因为怕混了,我把从这里分界的上下代码重新贴在下边,标注为“分界线处”。
0041EEF7    C3              RETN                                     ;其实这里就是飞出壳,到程序真正入口的关键跳。看下边单拿出来的代码段有详细注解。
0041EEF8    0070 01         ADD BYTE PTR DS:[EAX+1],DH
0041EEFB    0000            ADD BYTE PTR DS:[EAX],AL
0041EEFD    1000            ADC BYTE PTR DS:[EAX],AL
            .
            .
            .
0041EECF    5E              POP ESI
0041EED0    5D              POP EBP
0041EED1    59              POP ECX
0041EED2    46              INC ESI
0041EED3    AD              LODS DWORD PTR DS:[ESI]
0041EED4    85C0            TEST EAX,EAX
0041EED6    74 1F           JE SHORT auto.0041EEF7
0041EED8    51              PUSH ECX
0041EED9    56              PUSH ESI
0041EEDA    97              XCHG EAX,EDI
0041EEDB    FFD1            CALL ECX
0041EEDD    93              XCHG EAX,EBX
0041EEDE    AC              LODS BYTE PTR DS:[ESI]
0041EEDF    84C0            TEST AL,AL
0041EEE1 ^ 75 FB           JNZ SHORT auto.0041EEDE
0041EEE3    3806            CMP BYTE PTR DS:[ESI],AL
0041EEE5 ^ 74 EA           JE SHORT auto.0041EED1
0041EEE7    8BC6            MOV EAX,ESI
0041EEE9    79 05           JNS SHORT auto.0041EEF0
0041EEEB    46              INC ESI
0041EEEC    33C0            XOR EAX,EAX
0041EEEE    66:AD           LODS WORD PTR DS:[ESI]
0041EEF0    50              PUSH EAX
0041EEF1    53              PUSH EBX
0041EEF2    FFD5            CALL EBP
0041EEF4    AB              STOS DWORD PTR ES:[EDI]
0041EEF5 ^ EB E7           JMP SHORT auto.0041EEDE                  ;分界线处。这里会回跳,不要跳。分析完这里回跳所牵扯到的所有跳转范围是从0041EED6到0041EEF5,里边也没有外调的CALL,所以可以在这里的下一行下断然后F9(分析完了,就不会跑飞了)。
0041EEF7    C3              RETN                                     ;这里F2下断,F9运行(程序会运行一会才停下来,因为是在解被加密的输入表),然后停在这里。停下后F8单步一次,返回(跳转)。
0041EEF8    0070 01         ADD BYTE PTR DS:[EAX+1],DH
0041EEFB    0000            ADD BYTE PTR DS:[EAX],AL
0041EEFD    1000            ADC BYTE PTR DS:[EAX],AL
0041EEFF    00F0            ADD AL,DH
0041EF01    0100            ADD DWORD PTR DS:[EAX],EAX
0041EF03    0010            ADD BYTE PTR DS:[EAX],DL
0041EF05    0000            ADD BYTE PTR DS:[EAX],AL
            .
            .
            .
0040338F    55              PUSH EBP                                 ;返回(跳转)到了这里,这里就是程序的真正入口点了,DUMP保存、修复和优化吧。
00403390    8BEC            MOV EBP,ESP
00403392    6A FF           PUSH -1
00403394    68 68414000     PUSH auto.00404168
00403399    68 10354000     PUSH auto.00403510                       ; JMP 到 MSVCRT._except_handler3
0040339E    64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004033A4    50              PUSH EAX
004033A5    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
004033AC    83EC 68         SUB ESP,68
004033AF    53              PUSH EBX
004033B0    56              PUSH ESI
004033B1    57              PUSH EDI
004033B2    8965 E8         MOV DWORD PTR SS:[EBP-18],ESP
004033B5    33DB            XOR EBX,EBX
004033B7    895D FC         MOV DWORD PTR SS:[EBP-4],EBX
004033BA    6A 02           PUSH 2
004033BC    FF15 DC404000   CALL DWORD PTR DS:[4040DC]               ; MSVCRT.__set_app_type
004033C2    59              POP ECX
004033C3    830D 60524100 F>OR DWORD PTR DS:[415260],FFFFFFFF
004033CA    830D 64524100 F>OR DWORD PTR DS:[415264],FFFFFFFF
004033D1    FF15 E0404000   CALL DWORD PTR DS:[4040E0]               ; MSVCRT.__p__fmode
004033D7    8B0D 5C524100   MOV ECX,DWORD PTR DS:[41525C]
004033DD    8908            MOV DWORD PTR DS:[EAX],ECX
004033DF    FF15 E4404000   CALL DWORD PTR DS:[4040E4]               ; MSVCRT.__p__commode
---------------------------------------------------------------------------------------------
总结:

    上边是采用方法1手动脱壳的,对GetProcAddress下断后需要F9很多次(次数不固定,和调用的API个数成正比)。如果采用方法2的话,对LoadLibraryA下断后只要F9一次就可以了。都是脱壳的好方法,掌握多些比较好。本文描述的很详细,希望大家喜欢。
---------------------------------------------------------------------------------------------

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
2
壳的讨论,请到 『软件保护与分析』
2007-12-31 21:57
0
雪    币: 288
活跃值: (53)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
哦,谢谢。
那请斑竹把我发的帖子都转过去吧?可以吗?
2008-1-2 09:35
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习一下。。。。
2008-1-4 15:42
0
雪    币: 255
活跃值: (207)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
5
我一般直接 PEExplorer 静态脱壳。
2008-1-5 11:38
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
狂热支持呀.
2008-1-5 16:09
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
楼主厉害,支持呀.
2008-1-5 16:10
0
雪    币: 288
活跃值: (53)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
8
直接 PEExplorer 静态脱壳?这个我没使用过,是软件吧?

我只是菜鸟,大家一起努力吧。^_^
2008-1-6 19:13
0
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我也想知道用PEExplorer怎么脱
2008-1-7 12:46
0
雪    币: 288
活跃值: (53)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
PEExplorer是做什么用的软件?
2008-1-7 15:47
0
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
PE Explorer 1.98 功能强大的资源工具,可直接浏览、修改软件资源,包括菜单、对话框、字符串表等;另外,还具备有 W32DASM 软件的反编译能力和 PEditor 软件的PE文件头编辑功能;该软件支持插件。
主页->工具下载->PE相关工具
2008-1-7 16:21
0
雪    币: 288
活跃值: (53)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
12
那么貌似这个程序不可以脱壳哦?只可以支持部分几种壳的识别吧?还不支持变种壳。
2008-1-8 12:09
0
游客
登录 | 注册 方可回帖
返回