梦影 发表于 2011-2-23 12:36

新手第一脱 UPX壳 献给比我还菜的人,大家一起学

本帖最后由 梦影 于 2011-2-23 12:45 编辑

这几天在论坛看帖子,看到不少人都说UPX是最容易脱的壳了,于是找了个自己熟悉的程序加了个UPX壳,见附件

HideW.exe为加壳后的程序,~HideW.exe为脱壳后的程序
未加壳的程序见这个帖子(含源码的)http://wt.52pojie.cn/thread-81036-1-1.html
随便问个问题,加壳前程序大小是4KB,加壳后3KB,但是我脱壳后成了65KB,不知道怎么回事,还是我的操作有误,请高人指点

作为新手的我,看不懂别人的脱壳文章,说得太快,所以我尽量详细地写。
以下是我的脱壳过程大牛飞过吧



0040E410 > [        DISCUZ_CODE_6        ]nbsp; 60            pushad                                 ;;OD载入后停在了这里f8单步往下走
0040E411   .BE 00E04000   mov esi,HideW.0040E000
0040E416   .8DBE 0030FFFF lea edi,dword ptr ds:
0040E41C   .57            push edi
0040E41D   .EB 0B         jmp XHideW.0040E42A                      ;;往下跳的,就允许了
0040E41F      90            nop
0040E420   >8A06          mov al,byte ptr ds:
0040E422   .46            inc esi
0040E423   .8807          mov byte ptr ds:,al
0040E425   .47            inc edi
0040E426   >01DB          add ebx,ebx
0040E428   .75 07         jnz XHideW.0040E431
0040E42A   >8B1E          mov ebx,dword ptr ds:               ;;从上面跳过来的
0040E42C   .83EE FC       sub esi,-0x4
0040E42F   .11DB          adc ebx,ebx
0040E431   >^ 72 ED         jb XHideW.0040E420                     ;;老是跳到上面0040E420处,好像是个什么循环
0040E433   .B8 01000000   mov eax,0x1                              ;;上面0040E428的JNZ最终也会到这上面的一句的,所以直接F4到这了
0040E438   >01DB          add ebx,ebx
0040E43A   .75 07         jnz XHideW.0040E443                      ;;往下的,继续了
0040E43C   .8B1E          mov ebx,dword ptr ds:
0040E43E   .83EE FC       sub esi,-0x4
0040E441   .11DB          adc ebx,ebx
0040E443   >11C0          adc eax,eax
0040E445   .01DB          add ebx,ebx
0040E447   .^ 73 EF         jnb XHideW.0040E438                      ;;这个跳转是没有实现的,继续
0040E449   .75 09         jnz XHideW.0040E454                      ;;往下跳的,继续F8
0040E44B   .8B1E          mov ebx,dword ptr ds:
0040E44D   .83EE FC       sub esi,-0x4
0040E450   .11DB          adc ebx,ebx
0040E452   .^ 73 E4         jnb XHideW.0040E438
0040E454   >31C9          xor ecx,ecx
0040E456   .83E8 03       sub eax,0x3
0040E459   .72 0D         jb XHideW.0040E468                     ;;也是没跳转的
0040E45B   .C1E0 08       shl eax,0x8
0040E45E   .8A06          mov al,byte ptr ds:
0040E460   .46            inc esi
0040E461   .83F0 FF       xor eax,0xFFFFFFFF
0040E464   .74 74         je XHideW.0040E4DA                     ;;没跳的
0040E466   .89C5          mov ebp,eax
0040E468   >01DB          add ebx,ebx
0040E46A   .75 07         jnz XHideW.0040E473                      ;;往下跳的
0040E46C   .8B1E          mov ebx,dword ptr ds:
0040E46E   .83EE FC       sub esi,-0x4
0040E471   .11DB          adc ebx,ebx
0040E473   >11C9          adc ecx,ecx
0040E475   .01DB          add ebx,ebx
0040E477   .75 07         jnz XHideW.0040E480                      ;;还是往下跳的
0040E479   .8B1E          mov ebx,dword ptr ds:
0040E47B   .83EE FC       sub esi,-0x4
0040E47E   .11DB          adc ebx,ebx
0040E480   >11C9          adc ecx,ecx
0040E482   .75 20         jnz XHideW.0040E4A4                      ;;跳转到下面的
0040E484   .41            inc ecx
0040E485   >01DB          add ebx,ebx
0040E487   .75 07         jnz XHideW.0040E490
0040E489   .8B1E          mov ebx,dword ptr ds:
0040E48B   .83EE FC       sub esi,-0x4
0040E48E   .11DB          adc ebx,ebx
0040E490   >11C9          adc ecx,ecx
0040E492   .01DB          add ebx,ebx
0040E494   .^ 73 EF         jnb XHideW.0040E485
0040E496   .75 09         jnz XHideW.0040E4A1
0040E498   .8B1E          mov ebx,dword ptr ds:
0040E49A   .83EE FC       sub esi,-0x4
0040E49D   .11DB          adc ebx,ebx
0040E49F   .^ 73 E4         jnb XHideW.0040E485
0040E4A1   >83C1 02       add ecx,0x2
0040E4A4   >81FD 00F3FFFF cmp ebp,-0xD00                           ;;到这了
0040E4AA   .83D1 01       adc ecx,0x1
0040E4AD   .8D142F      lea edx,dword ptr ds:
0040E4B0   .83FD FC       cmp ebp,-0x4
0040E4B3   .76 0F         jbe XHideW.0040E4C4                      ;往下跳的
0040E4B5   >8A02          mov al,byte ptr ds:
0040E4B7   .42            inc edx
0040E4B8   .8807          mov byte ptr ds:,al
0040E4BA   .47            inc edi
0040E4BB   .49            dec ecx
0040E4BC   .^ 75 F7         jnz XHideW.0040E4B5
0040E4BE   .^ E9 63FFFFFF   jmp HideW.0040E426
0040E4C3      90            nop
0040E4C4   >8B02          mov eax,dword ptr ds:
0040E4C6   .83C2 04       add edx,0x4
0040E4C9   .8907          mov dword ptr ds:,eax
0040E4CB   .83C7 04       add edi,0x4
0040E4CE   .83E9 04       sub ecx,0x4
0040E4D1   .^ 77 F1         ja XHideW.0040E4C4                     ;;跳转不未实现
0040E4D3   .01CF          add edi,ecx
0040E4D5   .^ E9 4CFFFFFF   jmp HideW.0040E426                     ;;跳过去的那个地方好像执行过
0040E4DA   >5E            pop esi                                  ;;不懂,算了,F4到这里吧(反正上面也没有跳到比这句更下面的)
0040E4DB   .89F7          mov edi,esi
0040E4DD   .B9 1D000000   mov ecx,0x1D
0040E4E2   >8A07          mov al,byte ptr ds:
0040E4E4   .47            inc edi
0040E4E5   .2C E8         sub al,0xE8
0040E4E7   >3C 01         cmp al,0x1
0040E4E9   .^ 77 F7         ja XHideW.0040E4E2                     ;;有点晕了
0040E4EB   .803F 00       cmp byte ptr ds:,0x0
0040E4EE   .^ 75 F2         jnz XHideW.0040E4E2                      ;;和上面的一样 往上重复执行这一段
0040E4F0   .8B07          mov eax,dword ptr ds:               ;;F4执行到这里好了 上面的实在是晕
0040E4F2   .8A5F 04       mov bl,byte ptr ds:
0040E4F5   .66:C1E8 08    shr ax,0x8
0040E4F9   .C1C0 10       rol eax,0x10
0040E4FC   .86C4          xchg ah,al
0040E4FE   .29F8          sub eax,edi
0040E500   .80EB E8       sub bl,0xE8
0040E503   .01F0          add eax,esi
0040E505   .8907          mov dword ptr ds:,eax
0040E507   .83C7 05       add edi,0x5
0040E50A   .88D8          mov al,bl
0040E50C   .^ E2 D9         loopd XHideW.0040E4E7                  ;;循环,直接F4执行到下一句
0040E50E   .8DBE 00C00000 lea edi,dword ptr ds:      ;;到这了
0040E514   >8B07          mov eax,dword ptr ds:
0040E516   .09C0          or eax,eax
0040E518   .74 3C         je XHideW.0040E556                     ;;未实现跳转的
0040E51A   .8B5F 04       mov ebx,dword ptr ds:
0040E51D   .8D8430 58E000>lea eax,dword ptr ds:
0040E524   .01F3          add ebx,esi
0040E526   .50            push eax
0040E527   .83C7 08       add edi,0x8
0040E52A   .FF96 94E00000 call dword ptr ds:         ;;看到call LoadLibraryA了 F8步过了,系统领空我也搞不明白 先在这里F2下个断点(好像没用,第二次执行时取消了)
0040E530   .95            xchg eax,ebp
0040E531   >8A07          mov al,byte ptr ds:
0040E533   .47            inc edi
0040E534   .08C0          or al,al
0040E536   .^ 74 DC         je XHideW.0040E514                     ;;未实现的
0040E538   .89F9          mov ecx,edi
0040E53A   .57            push edi
0040E53B   .48            dec eax
0040E53C   .F2:AE         repne scas byte ptr es:
0040E53E   .55            push ebp
0040E53F   .FF96 98E00000 call dword ptr ds:         ;;GetProcAddress 还是不懂 F8步过,继续往下
0040E545   .09C0          or eax,eax
0040E547   .74 07         je XHideW.0040E550
0040E549   .8903          mov dword ptr ds:,eax
0040E54B   .83C3 04       add ebx,0x4
0040E54E   .^ EB E1         jmp XHideW.0040E531                      ;;住上的循环,这里F4往下后,发现程序已运行了。哎,下个断点,重新执行。第二次到这里时不知道怎么办了,好在下面也没多少代码了,一条条看过去,发现POPAD了,最后面有个很远的跳转,就F4到那了
0040E550   >FF96 A8E00000 call dword ptr ds:
0040E556   >8BAE 9CE00000 mov ebp,dword ptr ds:
0040E55C   .8DBE 00F0FFFF lea edi,dword ptr ds:
0040E562   .BB 00100000   mov ebx,0x1000
0040E567   .50            push eax
0040E568   .54            push esp
0040E569   .6A 04         push 0x4
0040E56B   .53            push ebx
0040E56C   .57            push edi
0040E56D   .FFD5          call ebp
0040E56F   .8D87 D7010000 lea eax,dword ptr ds:
0040E575   .8020 7F       and byte ptr ds:,0x7F
0040E578   .8060 28 7F    and byte ptr ds:,0x7F
0040E57C   .58            pop eax
0040E57D   .50            push eax
0040E57E   .54            push esp
0040E57F   .50            push eax
0040E580   .53            push ebx
0040E581   .57            push edi
0040E582   .FFD5          call ebp
0040E584   .58            pop eax
0040E585   .61            popad
0040E586   .8D4424 80   lea eax,dword ptr ss:
0040E58A   >6A 00         push 0x0
0040E58C   .39C4          cmp esp,eax
0040E58E   .^ 75 FA         jnz XHideW.0040E58A
0040E590   .83EC 80       sub esp,-0x80
0040E593   .- E9 A72BFFFF   jmp HideW.0040113F                     ;;到这后,F8跟过去




然后就到了这里了

0040113F    6A 00         push 0x0                                 ; ;哦耶,太熟悉不过了,这不是我写的代码的第一条语句么
00401141    E8 86010000   call HideW.004012CC                      ; jmp 到 kernel32.GetModuleHandleA
00401146    A3 18304000   mov dword ptr ds:,eax
0040114B    C705 3C304000 3>mov dword ptr ds:,0x30
00401155    C705 40304000 0>mov dword ptr ds:,0x3
0040115F    C705 44304000 0>mov dword ptr ds:,HideW.004010>
00401169    C705 48304000 0>mov dword ptr ds:,0x0
00401173    C705 4C304000 1>mov dword ptr ds:,0x1E
0040117D    FF35 18304000   push dword ptr ds:
00401183    8F05 50304000   pop dword ptr ds:
00401189    C705 5C304000 1>mov dword ptr ds:,0x10
00401193    C705 60304000 0>mov dword ptr ds:,0x0
0040119D    C705 64304000 0>mov dword ptr ds:,HideW.004030>; ASCII "DLGCLASS"
004011A7    68 007F0000   push 0x7F00
004011AC    6A 00         push 0x0
004011AE    E8 DD000000   call HideW.00401290                      ; jmp 到 user32.LoadIconA
004011B3    A3 54304000   mov dword ptr ds:,eax
004011B8    A3 68304000   mov dword ptr ds:,eax
004011BD    68 007F0000   push 0x7F00
004011C2    6A 00         push 0x0
004011C4    E8 C1000000   call HideW.0040128A                      ; jmp 到 user32.LoadCursorA
004011C9    A3 58304000   mov dword ptr ds:,eax
004011CE    68 3C304000   push HideW.0040303C
004011D3    E8 C4000000   call HideW.0040129C                      ; jmp 到 user32.RegisterClassExA
004011D8    6A 00         push 0x0
004011DA    68 00104000   push HideW.00401000
004011DF    6A 00         push 0x0
004011E1    6A 65         push 0x65
004011E3    FF35 18304000   push dword ptr ds:
004011E9    E8 78000000   call HideW.00401266                      ; jmp 到 user32.CreateDialogParamA
004011EE    A3 1C304000   mov dword ptr ds:,eax
004011F3    68 64B04000   push HideW.0040B064
004011F8    6A 00         push 0x0
004011FA    68 73204000   push HideW.00402073                      ; ASCII "ShowSelf"
004011FF    68 6B204000   push HideW.0040206B                      ; ASCII "Default"
00401204    E8 C9000000   call HideW.004012D2                      ; jmp 到 kernel32.GetPrivateProfileIntA
00401209    50            push eax
0040120A    FF35 1C304000   push dword ptr ds:
00401210    E8 99000000   call HideW.004012AE                      ; jmp 到 user32.ShowWindow
00401215    FF35 1C304000   push dword ptr ds:
0040121B    E8 9A000000   call HideW.004012BA                      ; jmp 到 user32.UpdateWindow
00401220    6A 00         push 0x0
00401222    6A 00         push 0x0
00401224    6A 00         push 0x0
00401226    68 20304000   push HideW.00403020
0040122B    E8 4E000000   call HideW.0040127E                      ; jmp 到 user32.GetMessageA
00401230    0BC0            or eax,eax
00401232    74 2A         je XHideW.0040125E
00401234    68 20304000   push HideW.00403020
00401239    FF35 1C304000   push dword ptr ds:
0040123F    E8 40000000   call HideW.00401284                      ; jmp 到 user32.IsDialogMessageA
00401244    0BC0            or eax,eax
00401246    75 14         jnz XHideW.0040125C
00401248    68 20304000   push HideW.00403020
0040124D    E8 62000000   call HideW.004012B4                      ; jmp 到 user32.TranslateMessage
00401252    68 20304000   push HideW.00403020
00401257    E8 16000000   call HideW.00401272                      ; jmp 到 user32.DispatchMessageA
0040125C^ EB C2         jmp XHideW.00401220
0040125E    6A 00         push 0x0
00401260    E8 5B000000   call HideW.004012C0                      ; jmp 到 kernel32.ExitProcess




选中上面的第一行,点插件,Ollydump,脱壳在当前调试的进程,弹出个窗口



入口点就是我选中的那行,所以不用改了,直接点脱壳,另存为EXE文件即可


用PEID查下脱壳后的吧



运行一下,功能正常

这是未脱壳的



不知道为什么,我的PEID查不出来是什么壳,不过我明明加的就是UPX壳。是PEID的版本过低么?

梦影 发表于 2011-2-23 12:44

本帖最后由 梦影 于 2011-2-23 12:49 编辑

{:1_885:}   注释前的分号OD自己加上去了,我还写个,汗,多此一举了(第一次,不了解,高手勿笑)

总算是进了脱壳的门了吧   徘徊了好几天了,一直没有真正动手实践过


ShellYu 发表于 2011-2-23 14:01

俺是看不懂的新手。。。

topcookie 发表于 2011-2-23 14:15

现在的upx都是变种壳了,用这个方法脱不掉了,还是感谢楼主的分享精神

梦影 发表于 2011-2-23 14:57

topcookie 发表于 2011-2-23 14:15 static/image/common/back.gif
现在的upx都是变种壳了,用这个方法脱不掉了,还是感谢楼主的分享精神

:(eew有空我看看其他版本的   


接下来打算看ASPack 和 nSPack 以及FSG   

单步跟踪法应该是通用的吧
捷径法是不是指直接搜索popad呢?
ESP定律,经常看到这个词,但还是不了解

另外我发现UPX壳在popad前都会GetProcAddress取原来程序中调用的API地址这个应该也可以作为一种方法吧

huitian200 发表于 2011-2-23 15:01

谢谢分享!楼主辛苦了!

Mr.Q 发表于 2011-2-23 15:06

好东西,好好看看

梦影 发表于 2011-2-23 16:28

回Mr.Q:
加壳比脱壳简单几百倍 直接用命令 ”upx 待加壳文件“就OK了
虽然脱壳也可以用命令,但是本着学习的目的 。。
再说了,要用对应版本的UPX才能正确脱壳吧(或者更高版本)

跑飞了就是直接运行了,没找到程序入口点   应该是这样的,开始我也不知道
比如我第一次的时候
0040E54E   .^ EB E1         jmp XHideW.0040E531
到这F4,结果就飞了,只好重来了

梦影 发表于 2011-2-23 16:28

本帖最后由 梦影 于 2011-2-23 19:40 编辑

捷径法 就是直达法吧
载入后直接右键,查找 命令 输入popad直接F4到最下面的JMP那里,然后F8到达OEP

奇怪 发表于 2011-2-23 17:52

页: [1] 2 3 4
查看完整版本: 新手第一脱 UPX壳 献给比我还菜的人,大家一起学