手脱MoleBox(学习历程)
声明:1.纪录自己成长历程,与大家分享
2.由于技术与能力,如有疏漏错误,欢迎指出,高手轻喷
简述:
吾爱破解脱壳练习-----MoleBox V2.6.5,这一期研究的有些时候了,MoleBox这个壳找到OEP不难,但是修复却让我投入了很多时间,于是我开始逐步研究该贴下的所有脱文,感谢unpack关于该壳的详细分析,
解决了我的一些困惑。之后我继续在论坛里搜索,发现该壳还可以更加困难,涉及到了解捆绑文件的问题,让我头疼了一阵。下面以一个例子先逐步分析一下MoleBox的壳.
相关经验来自:http://www.52pojie.cn/thread-11306-2-1.html
http://www.52pojie.cn/forum.php?mod=viewthread&tid=12149
例子来源:http://www.52pojie.cn/thread-233561-1-1.html
1.发送到PEID查壳,插件核心扫描:
PESniffer:MoleBox V2.X -> MoleStudio.com
PEiDDSCAN:Microsoft Visual C++ 6.0
2.寻找OEP,这个壳的OEP用ESP定理法就能快速找到,虽然简单,但是我们还是来看一下。
004E3BD3 >E8 00000000 call 多记忆桌.004E3BD8 ;//加载OD程序停在此处
004E3BD8 60 pushad
004E3BD9 E8 4F000000 call 多记忆桌.004E3C2D ;//此处可以用ESP定理法(hr 12ffa0)
F9后来到OEP的特征入口
004E37B1 58 pop eax ; 多记忆桌.004E3BD8
004E37B2 58 pop eax
004E37B3 FFD0 call eax ;//F7跟进就到OEP了
0045159E 55 push ebp ;//OEP
0045159F 8BEC mov ebp,esp
004515A1 6A FF push -0x1
004515A3 68 78034800 push 多记忆桌.00480378
004515A8 68 843D4500 push 多记忆桌.00453D84
004515AD 64:A1 00000000mov eax,dword ptr fs:
004515B3 50 push eax
004515B4 64:8925 0000000>mov dword ptr fs:,esp
004515BB 83EC 58 sub esp,0x58
004515BE 53 push ebx
004515BF 56 push esi
004515C0 57 push edi
004515C1 8965 E8 mov dword ptr ss:,esp
修复才是这个壳的重头戏,用importREC修复一共有19个指针无效,用等级1就全部修复完了。但是我们在记录窗口可以看到语句
-------------------------------------------------------------------------------------------------------
恭喜!已没有无效的指针,但现在的问题是:它能运行吗?:-)
-------------------------------------------------------------------------------------------------------
果然这个程序没有那么简单就运行起来,有了ORiEN的经验我们可以用LoadPE检查一下是不是区段出现了问题,但这里不是。我们手动修复指针,
因为这个壳在解密指针后的某一步又加密了指针,我们需要把它找出来。在importREC中可以看到首个无效指针是:rva:000711E4 pte:004F0A70
在711E4加上基址400000后4711E4,等一下要跟踪观察该指针的变化来寻找出错的那步。
ctrl+F2重新载入OD,首先在命令中下d 4711E4,注意观察数据窗口的变化
004711E4C055741C ;//下硬件访问断点,每一步都要注意这一步的变化
004711E827BBD7D5
004711EC8E87F457
004711F08F487B49
F9 6次之后数据访问断点出现了变化。
004711E47C8322D4kernel32.UnlockFile
004711E80008924C
程序也来到了,这时候要单步跟,否则我们可能因为程序跑的太快错过了细节
004EAEF8 /EB 2C jmp short 多记忆桌.004EAF26
004EAEFA |8B55 F4 mov edx,dword ptr ss:
004EAEFD |8B02 mov eax,dword ptr ds:
004EAEFF |25 FFFF0000 and eax,0xFFFF
004EAF04 |8945 D0 mov dword ptr ss:,eax
004EAF07 |8B4D D0 mov ecx,dword ptr ss:
004EAF0A |51 push ecx
004EAF0B |8B55 EC mov edx,dword ptr ss:
004EAF0E |52 push edx
004EAF0F |FF15 BC774F00 call dword ptr ds: ; kernel32.GetProcAddress
004EAF15 |8945 D4 mov dword ptr ss:,eax
004EAF18 |837D D4 00 cmp dword ptr ss:,0x0
004EAF1C |74 08 je short 多记忆桌.004EAF26
004EAF1E |8B45 E0 mov eax,dword ptr ss:
004EAF21 |8B4D D4 mov ecx,dword ptr ss:
004EAF24 |8908 mov dword ptr ds:,ecx
004EAF26 \8B55 F0 mov edx,dword ptr ss:
单步到下面
004EAF41 52 push edx
004EAF42 E8 D9060000 call 多记忆桌.004EB620 ;//call是绕不过的,指针的变化也出现在这里
004EAF47 83C4 0C add esp,0xC ;//在这句下硬件执行断点运行后会发现,到这步变化的数据消失了
004EAF4A^ E9 32FFFFFF jmp 多记忆桌.004EAE81 ;//上面的尝试重复说明了call这步指针又重新加密了
F7跟进后来到此处,此时单步跟,并且也要注意寄存器窗口
004EB620 55 push ebp
004EB621 8BEC mov ebp,esp
004EB623 83EC 10 sub esp,0x10
004EB626 C745 FC 0000000>mov dword ptr ss:,0x0
004EB62D 833D 5CC14F00 0>cmp dword ptr ds:,0x0
004EB634 75 0A jnz short 多记忆桌.004EB640
004EB636 B9 0A0000EF mov ecx,0xEF00000A
004EB63B E8 D72F0000 call 多记忆桌.004EE617
004EB640 8B45 08 mov eax,dword ptr ss:
004EB643 8B08 mov ecx,dword ptr ds:
004EB645 51 push ecx
004EB646 8B0D 5CC14F00 mov ecx,dword ptr ds:
004EB64C E8 13650000 call 多记忆桌.004F1B64
004EB651 8945 F8 mov dword ptr ss:,eax
004EB654 837D F8 00 cmp dword ptr ss:,0x0
004EB658 74 45 je short 多记忆桌.004EB69F
004EB65A 8D55 F0 lea edx,dword ptr ss:
004EB65D 52 push edx
004EB65E 6A 04 push 0x4
004EB660 6A 04 push 0x4
004EB662 8B45 08 mov eax,dword ptr ss:
004EB665 50 push eax
004EB666 FF15 40784F00 call dword ptr ds: ; kernel32.VirtualProtect
004EB66C 85C0 test eax,eax
004EB66E 75 0A jnz short 多记忆桌.004EB67A
004EB670 B9 0B0000EF mov ecx,0xEF00000B
004EB675 E8 9D2F0000 call 多记忆桌.004EE617
004EB67A 8B4D 08 mov ecx,dword ptr ss:
004EB67D 8B55 F8 mov edx,dword ptr ss:
004EB680 8B02 mov eax,dword ptr ds:
004EB682 8901 mov dword ptr ds:,eax ;//注意堆栈窗口的eax寄存器
004EB684 8D4D F4 lea ecx,dword ptr ss: ;//执行上一步后,数据窗口中发现指针已经加密了,看汇编也可以猜出上步用eax取代变量实现了加密
004EB687 51 push ecx
004EB688 8B55 F0 mov edx,dword ptr ss:
004EB68B 52 push edx
004EB68C 6A 04 push 0x4
004EB68E 8B45 08 mov eax,dword ptr ss:
004EB691 50 push eax
004EB692 FF15 40784F00 call dword ptr ds: ; kernel32.VirtualProtect
所有经过上面的分析我们有两种方法跳过加密
1.直接nop掉(004EB682 8901 mov dword ptr ds:,eax)
2.magic jump 将je改为jmp 这样就直接跳过了加密代码(004EB658 /74 45 je short 多记忆桌.004EB69F)
我用第一种方法吧,在(004EB682 8901 mov dword ptr ds:,eax)处下硬件执行断点,重载od
004E3BD3 >E8 00000000 call 多记忆桌.004E3BD8 ;//加载OD程序停在此处,删除之前为了查看指针的跟随断点
004E3BD8 60 pushad
004E3BD9 E8 4F000000 call 多记忆桌.004E3C2D ;//此处可以用ESP定理法(hr 12ffa0)
F9 1次来到加密处,nop掉,删除掉硬件执行断点
004EB682 8901 mov dword ptr ds:,eax ; 多记忆桌.004F16C8 ;//nop掉
F9后来到OEP的特征入口
F9004E37B1 58 pop eax ; 多记忆桌.004E3BD8
004E37B2 58 pop eax
004E37B3 FFD0 call eax ;//F7跟进就到OEP了
修复是已经不缺少指针了。
但现在程序修复后运行时跑不起,说丢失了SkinH_EL.dll文件,我这里在网上下载了SkinH_EL.dll,程序就跑起来了。这里可能有一部分人疑惑,这个比较难,涉及到了该壳捆绑文件的问题,以后分析透彻了另开一贴专门说。
先介绍一种更快一些脱此壳的方法。
分析了加密过程后,发现加密是在两段VirtualProtect间实现的,VirtualProtect顾名思义是虚拟保护,应该起到内存保护作用吧。这能是该壳关键代码在此处的原因
004E3BD3 >E8 00000000 call 多记忆桌.004E3BD8 ;//加载OD程序停在此处
004E3BD8 60 pushad
004E3BD9 E8 4F000000 call 多记忆桌.004E3C2D ;//此处可以用ESP定理法(hr 12ffa0)先不急运行 下bp VirtualProtect
F9运行后6次后堆栈窗口
0012FAE0 004EB66C/CALL 到 VirtualProtect 来自 多记忆桌.004EB666;//从此句看出ALT+F9返回4EB66C,返回后离我们的nop处非常近,ALT+F9返回用户代码
0012FAE4 77DA1034|Address = <&KERNEL32.CloseHandle>
0012FAE8 00000004|Size = 4
0012FAEC 00000004|NewProtect = PAGE_READWRITE
0012FAF0 0012FAF4\pOldProtect = 0012FAF4
0012FAF4 0012FB0C
0012FAF8 004F1B80返回到 多记忆桌.004F1B80 来自 多记忆桌.004F1B84
0012FAFC 004F7320多记忆桌.004F7320
0012FB00 00000000
0012FB04/0012FB7C
0012FB08|004EB5B7返回到 多记忆桌.004EB5B7 来自 多记忆桌.004EB620
0012FB0C|77DA1034<&KERNEL32.CloseHandle>
0012FB10|76B2EBA0ASCII "ADVAPI32.dll"
0012FB14|77E12AE4ASCII "KERNEL32.dll"
0012FB18|003C2104
0012FB1C|004E3C1E多记忆桌.004E3C1E
0012FB20|7FFDF000
0012FB24|7C92EB79返回到 ntdll.7C92EB79 来自 ntdll.RtlMultiByteToUnicodeN
0012FB28|7FFDEC00UNICODE "ntdll.dll"
0012FB2C|77E12AE4ASCII "KERNEL32.dll"
0012FB30|7C800000kernel32.7C800000
0012FB34|77DA1034<&KERNEL32.CloseHandle>
004EB66C 85C0 test eax,eax
004EB66E 75 0A jnz short 多记忆桌.004EB67A
004EB670 B9 0B0000EF mov ecx,0xEF00000B
004EB675 E8 9D2F0000 call 多记忆桌.004EE617
004EB67A 8B4D 08 mov ecx,dword ptr ss:
004EB67D 8B55 F8 mov edx,dword ptr ss:
004EB680 8B02 mov eax,dword ptr ds:
004EB682 8901 mov dword ptr ds:,eax ;//nop掉此处,ALT+b删除刚刚的断点,返回窗口F9运行
F9后来到OEP的特征入口,又可以脱壳了。
004E37B1 58 pop eax ; 多记忆桌.004E3BD8
004E37B2 58 pop eax
004E37B3 FFD0 call eax ;//F7跟进就到OEP了
https://www.52pojie.cn/forum.php?mod=image&aid=1355679&size=300x300&key=ac0646a1c619a41e&nocache=yes&type=贴图错误,请阅读“贴图帮助”。lz好,我这个程序esp定律,硬件断点f9之后到了这里,没有一串pop的特征,怎么办 谢谢留住分享 以前遇到过,没拿下,挺麻烦的,好好学习一下,感谢大神! 好好学习一下 来看看这个好厉害 {:1_930:}多谢分享学习。 很不错,受教了。 支持下!谢谢分享!!!