wu0o0pj 发表于 2019-5-6 11:10

新手脱壳练习实践_求助区某vfp管理系统脱壳



进入吾爱有段时间了,教程看了很多,当然会手痒忍不住动手玩玩喽

看到求助区有个软件加了ASPack 壳,嗯,好像很容易欺负,那就蹂躏它吧
(原帖https://www.52pojie.cn/thread-946792-1-1.html)

萌新首帖,一步步记录过程,希望能给其他新货们灵感,共同进步吧


https://static.52pojie.cn/static/image/hrline/4.gifhttps://static.52pojie.cn/static/image/hrline/4.gifhttps://static.52pojie.cn/static/image/hrline/4.gif



首先查壳
   

嗯,工具查看,是带着 ASPack,那拖入OD,ESP 就能搞定了,赶紧试试吧{:301_978:}

带壳拖入OD,停在这:
00429B68 >55            push ebp
00429B69    52            push edx                                 ; ntdll.KiFastSystemCallRet
00429B6A    53            push ebx
00429B6B    51            push ecx
00429B6C    57            push edi
00429B6D    56            push esi
00429B6E    E8 01000000   call tjydhenz.00429B74
00429B73    3058 2D         xor byte ptr ds:,bl
00429B76    0B10            or edx,dword ptr ds:


额,好像不是我了解的ASPack特征啊
试试 ESP 定律,好吧,程序飞了,这让我怎么欺负它呀

怎么办呢,记住以下的大致方案:
无从下手的时候 F8 单步跟
向上跳转时,F4下一句
程序跑飞时,记住位置,F7 步入
奔溃时,找到位置,看能不能跳过,或者NOP掉

OK,撸起袖子从头开始,开干{:301_992:}

在入口点往下拖
00429BC2    58            pop eax                                  ; kernel32.7C817077
00429BC3    5E            pop esi                                  ; kernel32.7C817077
00429BC4    5E            pop esi                                  ; kernel32.7C817077
00429BC5    5F            pop edi                                  ; kernel32.7C817077
00429BC6    59            pop ecx                                  ; kernel32.7C817077
00429BC7    5B            pop ebx                                  ; kernel32.7C817077
00429BC8    5A            pop edx                                  ; kernel32.7C817077
00429BC9    5D            pop ebp                                  ; kernel32.7C817077
00429BCA    FFE0            jmp eax                                  ; 下断,F9运行到这,而后F8


来到这
00426001    60            pushad
00426002    E8 03000000   call tjydhenz.0042600A                   ; F8会挂,所以F7进入
00426007- E9 EB045D45   jmp 459F64F7
0042600C    55            push ebp                                 ; tjydhenz.00426008
0042600D    C3            retn


0042602F   /0F85 65030000   jnz tjydhenz.0042639A                  ; 发现下面有个Call会奔溃
00426035   |8D85 2E040000   lea eax,dword ptr ss:
0042603B   |50            push eax                                 ; tjydhenz.00426001
0042603C   |FF95 4D0F0000   call dword ptr ss:            ; kernel32.GetModuleHandleA
00426042   |8985 26040000   mov dword ptr ss:,eax         ; tjydhenz.00426001
00426048   |8BF8            mov edi,eax                              ; tjydhenz.00426001
0042604A   |8D5D 5E         lea ebx,dword ptr ss:
0042604D   |53            push ebx                                 ; tjydhenz.00400000
0042604E   |50            push eax                                 ; tjydhenz.00426001
0042604F   |FF95 490F0000   call dword ptr ss:            ; kernel32.GetProcAddress
00426055   |8985 4D050000   mov dword ptr ss:,eax         ; tjydhenz.00426001
0042605B   |8D5D 6B         lea ebx,dword ptr ss:
0042605E   |53            push ebx                                 ; tjydhenz.00400000
0042605F   |57            push edi
00426060   |FF95 493C0000   call dword ptr ss:         ; 这个Call,执行会奔溃
00426066   |8985 51050000   mov dword ptr ss:,eax         ; tjydhenz.00426001
0042606C   |8D45 77         lea eax,dword ptr ss:


正常调试时,上面的跳转未实现,一直往下会执行“00426060 |FF95 493C0000 call dword ptr ss:”,从而奔溃

重新载入,运行到该跳转,修改 ZF 标记,使其跳转实现,再几次 F8 后 会发现执行到这,显然这是未解密的代码,所以跳转不能实现,还是老老实实的吧
00419743   .0000          add byte ptr ds:,al
00419745   ?0000          add byte ptr ds:,al
00419747   ?0000          add byte ptr ds:,al
00419749   $0000          add byte ptr ds:,al
0041974B   ?0000          add byte ptr ds:,al
0041974D   ?0000          add byte ptr ds:,al
0041974F   ?0000          add byte ptr ds:,al
00419751   ?0000          add byte ptr ds:,al
00419753   ?0000          add byte ptr ds:,al
00419755   ?0000          add byte ptr ds:,al



那崩溃的Call怎么办呢,NOP掉,当然,记得将它的参数一起NOP

0042604E    50            push eax                                 ; kernel32.VirtualAlloc
0042604F    FF95 490F0000   call dword ptr ss:            ; kernel32.GetProcAddress
00426055    8985 4D050000   mov dword ptr ss:,eax         ; kernel32.VirtualAlloc
0042605B    8D5D 6B         lea ebx,dword ptr ss:
0042605E    90            nop
0042605F    90            nop
00426060    90            nop                                    ; 这个Call,执行会奔溃
00426061    90            nop
00426062    90            nop
00426063    90            nop
00426064    90            nop
00426065    90            nop
00426066    8985 51050000   mov dword ptr ss:,eax         ; kernel32.VirtualAlloc
0042606C    8D45 77         lea eax,dword ptr ss:


一路单步执行,最终来到这
00419743   .60            pushad
00419744   .E8 00000000   call tjydhenz.00419749                   ;F7 跟入
00419749   $5D            pop ebp                                  ;0012FFC8
0041974A   .81ED 06104000 sub ebp,tjydhenz.00401006
00419750   .8D85 56104000 lea eax,dword ptr ss:


同样 CALL F8会跑飞,就 F7 跟入,期间经过一段系统领空,出来后到这
00419767   .64:8F05 00000>pop dword ptr fs:                     ;0012FFE0
0041976E   .83C4 04       add esp,0x4
00419771   .74 05         je short tjydhenz.00419778
00419773   .75 03         jnz short tjydhenz.00419778
00419775   .EB 07         jmp short tjydhenz.0041977E
00419777   .59            pop ecx                                  ;0012FFE0
00419778   >8D9D 00104000 lea ebx,dword ptr ss:
0041977E   >53            push ebx
0041977F   .5F            pop edi                                  ;0012FFE0
00419780   .2BFA          sub edi,edx
00419782   .57            push edi                                 ;ntdll.KiFastSystemCallRet
00419783   >8A03          mov al,byte ptr ds:
00419785   .3007          xor byte ptr ds:,al
00419787   .43            inc ebx
00419788   .47            inc edi                                  ;ntdll.KiFastSystemCallRet
00419789   .^ E2 F8         loopd short tjydhenz.00419783
0041978B   .58            pop eax                                  ;0012FFE0
0041978C   .894424 1C   mov dword ptr ss:,eax          ;tjydhenz.00419799
00419790   .61            popad
00419791   .FFE0          jmp eax                                  ;tjydhenz.00419799 ; 跳到OEP


最后的 jmp eax 就是飞向OEP了

00418810/.55            push ebp                                 ;OEP
00418811|.8BEC          mov ebp,esp
00418813|.B9 07000000   mov ecx,0x7
00418818|>6A 00         /push 0x0
0041881A|.6A 00         |push 0x0
0041881C|.49            |dec ecx
0041881D|.^ 75 F9         \jnz short tjydhenz.00418818
0041881F|.53            push ebx
00418820|.56            push esi
00418821|.57            push edi                                 ;ntdll.KiFastSystemCallRet
00418822|.B8 78874100   mov eax,tjydhenz.00418778
00418827|.E8 68D3FEFF   call tjydhenz.00405B94
0041882C|.BE A8C94100   mov esi,tjydhenz.0041C9A8
00418831|.33C0          xor eax,eax                              ;tjydhenz.00418810
00418833|.55            push ebp                                 ;tjydhenz.00426001
00418834|.68 02944100   push tjydhenz.00419402
00418839|.64:FF30       push dword ptr fs:
0041883C|.64:8920       mov dword ptr fs:,esp
0041883F|.33C0          xor eax,eax                              ;tjydhenz.00418810
00418841|.A3 90C94100   mov dword ptr ds:,eax          ;tjydhenz.00418810
00418846|.64:8B05 30000>mov eax,dword ptr fs:
0041884D|.0FB640 02   movzx eax,byte ptr ds:
00418851|.08C0          or al,al
00418853|.74 0A         je short tjydhenz.0041885F


其实是不是OEP,心里没底,不是VC/C++,VB,易语言,有点像Delphi,但比对 H大 教程例子中的Delphi程序入口,又不是

不管了,先当这就是吧,老套路,LordPE dump,ImportREC 修复
{:301_1009:}嗯,IAT 也没问题,难道成功了??

试试吧,运行修复后的文件
{:301_987:}好激动,真的成功了


https://static.52pojie.cn/static/image/hrline/4.gifhttps://static.52pojie.cn/static/image/hrline/4.gif

后记:脱壳除了ESP外,还有二次镜像、模拟跟踪 等等方法,那这个程序呢

         ALT+O,打开调试设置窗口,将 SFX 选项卡 按照以下设置,点击确定,而后清理所有断点
         

         重新载入,会发现程序停在以下位置,熟悉吧,最后一句就是跳转到 OEP 的关键跳啊
00419785   .3007          xor byte ptr ds:,al
00419787   .43            inc ebx                                  ;tjydhenz.00419743
00419788   .47            inc edi                                  ;tjydhenz.00418810
00419789   .^ E2 F8         loopd short tjydhenz.00419783
0041978B   .58            pop eax                                  ;tjydhenz.00418810
0041978C   .894424 1C   mov dword ptr ss:,eax          ;tjydhenz.00419760
00419790   .61            popad
00419791   .^ FFE0          jmp eax                                  ;tjydhenz.00419760



         dump后进行修复,程序同样能够跑起来,成功,这个够省力吧,但不推荐,为啥,我是来练习的,结果是重要,但过程更重要

         先到这吧,等有时间试试其他方法


wu0o0pj 发表于 2019-7-30 16:22

lyqcx 发表于 2019-7-30 15:52
你好,这是我现在遇到的问题,能帮我看看嘛?


你在那 F8 单步后程序跑飞,那就 F7 跟进就行了

文中是一笔带过的,其实 int3 中断后进入了系统领空

7C92E460    8B1C24          mov ebx,dword ptr ss:
7C92E463    51            push ecx
7C92E464    53            push ebx
7C92E465    E8 E6C40100   call ntdll.7C94A950
7C92E46A    0AC0            or al,al
7C92E46C    74 0C         je short ntdll.7C92E47A
7C92E46E    5B            pop ebx                                  ; 0012FCC4
7C92E46F    59            pop ecx                                  ; 0012FCC4
7C92E470    6A 00         push 0x0
7C92E472    51            push ecx
7C92E473    E8 C8EBFFFF   call ntdll.ZwContinue


调试多了就知道 最后的 “call ntdll.ZwContinue” 必须 F7 跟进

而后再几次 F7 单步,就回到了用户领空
之后就能跑到 跳到 OEP 的那行 “jmp eax” 了




wu0o0pj 发表于 2020-8-22 10:35

千刀 发表于 2020-8-22 01:05
学习了。好贴。请问可以私信一下关于端口占用的解决方法吗
是你很久前发帖询问的问题吗 https://www.52pojie.cn/thread-1128786-1-1.html

这个帖子你本身的贴图中已经跟踪到函数内部 绑定端口 8099 的地方

687F34   ex,    -- 这个 就是 外部传进来的参数

可以直接在这 把 9099 赋值给 ex
或者在调用此函数的地方 把 8099 改成 9099 就行了

直接汇编 mov ex, 0x238B    -- 0x238B = 9099
二进制刚好是 4字节(66 B8 8B 23),不多不少,直接 修改

loqiu 发表于 2019-5-6 15:57

学习了,加油

drneko 发表于 2019-5-6 17:11

学习了,加油

白日梦梦妖 发表于 2019-5-7 00:21

加油啊,共勉

abc220 发表于 2019-5-8 05:58

新手学习中,还不会,改天也实践一下。

maheadst 发表于 2019-5-10 15:26

跳飞了是啥意思啊。。是大跳转吗,还是跳不动了,F8都没反应了?

wu0o0pj 发表于 2019-5-11 08:10

maheadst 发表于 2019-5-10 15:26
跳飞了是啥意思啊。。是大跳转吗,还是跳不动了,F8都没反应了?

就是程序跑起来了

lyqcx 发表于 2019-7-30 15:52

你好,这是我现在遇到的问题,能帮我看看嘛?

7001 发表于 2019-8-6 13:21

学习VFP的破解。
页: [1] 2
查看完整版本: 新手脱壳练习实践_求助区某vfp管理系统脱壳