手脱RLPack伪装upx
【文章标题】: 手脱RLPack伪装upx【文章作者】: 小生我怕怕
【作者邮箱】: 4586631@qq.com
【作者主页】: http://www.52pojie.cn
【作者QQ号】: 4586631
【软件名称】: 决策天机080105
【软件大小】: 1.05M
【下载地址】: 自己搜索下载
【加壳方式】: 加密壳
【保护方式】: RLPack伪装upx
【编写语言】: delphi
【使用工具】: OD lordPE importRCE
【操作平台】: XP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
007DB68A >60 pushad //OD载入
007DB68B BE 00908B00 mov esi,8B9000 //我们很熟悉的UPX入口映射我们的眼前
007DB690 8DBE 0080B4FF lea edi,dword ptr ds://自然联想到我们的ESP定律啦,在上面一句执行ESP定律
007DB696 57 push edi //或者直接hr esp
007DB697 83CD FF or ebp,FFFFFFFF
007DB69A EB 3A jmp short WishGJ.007DB6D6
007DB69C 90 nop
--------------------------------------------------------------------------------
007DB6D8 90 nop //执行ESP定律后停在这里
007DB6D9 60 pushad //这里就是RLPack壳的入口啦
007DB6DA E8 00000000 call WishGJ.007DB6DF //同样我们在这里执行ESP定律,或者直接he esp
007DB6DF 8B2C24 mov ebp,dword ptr ss: //记住先取消第一次的硬件断点
007DB6E2 83C4 04 add esp,4
007DB6E5 E8 500D0000 call WishGJ.007DC43A
007DB6EA E8 740D0000 call WishGJ.007DC463
007DB6EF E8 960C0000 call WishGJ.007DC38A
007DB6F4 8DB5 73260000 lea esi,dword ptr ss:
--------------------------------------------------------------------------------
007DB91D- E9 F6E4DFFF jmp WishGJ.005D9E18 //超级大跳转,直接跳去我们的OEP啦
007DB922 83BD 231B0000 0>cmp dword ptr ss:,0 //我们单步一步走
007DB929 74 16 je short WishGJ.007DB941
007DB92B 2B85 1B1B0000 sub eax,dword ptr ss:
007DB931 034424 4C add eax,dword ptr ss:
007DB935 50 push eax
--------------------------------------------------------------------------------
005D9E18 55 push ebp //呵呵标准的OEP入口
005D9E19 8BEC mov ebp,esp //我们运行importRCE看看我们的IAT指针
005D9E1B 83C4 F0 add esp,-10
005D9E1E 53 push ebx
005D9E1F B8 18955D00 mov eax,WishGJ.005D9518
005D9E24 E8 FFD4E2FF call WishGJ.00407328
005D9E29 8B1D 40EC5D00 mov ebx,dword ptr ds: ; WishGJ.005DFC38
005D9E2F E8 9899E9FF call WishGJ.004737CC
005D9E34 E8 8793E9FF call WishGJ.004731C0
--------------------------------------------------------------------------------
分析进程...
模块已载入: c:\windows\system32\ntdll.dll
模块已载入: c:\windows\system32\kernel32.dll
模块已载入: c:\windows\system32\user32.dll
模块已载入: c:\windows\system32\gdi32.dll
模块已载入: c:\windows\system32\imm32.dll
模块已载入: c:\windows\system32\advapi32.dll
模块已载入: c:\windows\system32\rpcrt4.dll
模块已载入: c:\windows\system32\secur32.dll
模块已载入: c:\windows\system32\lpk.dll
模块已载入: c:\windows\system32\usp10.dll
模块已载入: c:\windows\system32\msvcrt.dll
模块已载入: c:\windows\system32\oleaut32.dll
模块已载入: c:\windows\system32\ole32.dll
模块已载入: c:\windows\system32\version.dll
模块已载入: c:\windows\system32\comctl32.dll
模块已载入: c:\windows\system32\shell32.dll
模块已载入: c:\windows\system32\shlwapi.dll
模块已载入: c:\windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\comctl32.dll
模块已载入: c:\windows\system32\comdlg32.dll
模块已载入: c:\windows\system32\winmm.dll
获取关联模块完成.
镜像基址:00400000 大小:003E21D4
原始 IAT RVA 发现于: 001E32B8 位于块 RVA: 00001000 大小:002D1000
IAT 读取成功.
---------------------------------------------------------------------------------------------------------------------------
当前输入表:
10 (十进制:16) 个有效模块 (已添加: +10 (十进制:+16))
228 (十进制:552) 个输入函数. (已添加: +228 (十进制:+552)) //还有163个无效指针
(A3 (十进制:163) 个未解决的指针) (已添加: +A3 (十进制:+163)) //我们选中我们的第一个无效指针
---------------------------------------------------------------------------------------------------------------------------
FThunk: 001E31B8 NbFunc: 0000002F //由于指针过多,这里我只复制少数部分
0 001E31B8 ? 0000 00DC0000 //这里就是我们的IAT加密的开始,我们复制地址001E31B8
0 001E31BC ? 0000 00DC0017
0 001E31C0 ? 0000 00DC002E
0 001E31C4 ? 0000 00DC0045
0 001E31C8 ? 0000 00DC005C
0 001E31CC ? 0000 00DC0073
0 001E31D0 ? 0000 00DC008A
0 001E31D4 ? 0000 00DC00A1
0 001E31D8 ? 0000 00DC00B8
--------------------------------------------------------------------------------
看一下我们程序的基址是多少
内存映射,项目 21
地址=00400000
大小=00001000 (4096.)
物主=WishGJ 00400000 (自身)
区段=
包含=PE header
类型=Imag 01001040
访问=RWE
初始访问=RWE
那么我们IAT加米的地址就应该是
00400000+001E31B8=005E31B8
--------------------------------------------------------------------------------
007DB68A >60 pushad //从新载入程序
007DB68B BE 00908B00 mov esi,8B9000 //在命令行输入D 005E31B8
007DB690 8DBE 0080B4FF lea edi,dword ptr ds:
007DB696 57 push edi
007DB697 83CD FF or ebp,FFFFFFFF
--------------------------------------------------------------------------------
005E31B800000000 //直接在这里右键--断点--硬件访问断点--Dword
005E31BC00000000 //下好硬件断点,我们shift+f9运行程序
005E31C000000000
005E31C400000000
005E31C800000000
005E31CC00000000
--------------------------------------------------------------------------------
007DB899 83C7 04 add edi,4 //程序停在了这里
007DB89C 8B85 6B260000 mov eax,dword ptr ss: //而此时我们的第一个指针已经被加密啦
007DB8A2 EB 01 jmp short WishGJ.007DB8A5 //好我们不管啦,开始单步跟
007DB8A4 40 inc eax
007DB8A5 8038 00 cmp byte ptr ds:,0
--------------------------------------------------------------------------------
005E31B800DC0000 //这里就是我们的第一句加密
005E31BC00000000 //开始跟吧,在跟的时候注意寄存器窗口变化
005E31C000000000
005E31C400000000
--------------------------------------------------------------------------------
007DB89C 8B85 6B260000 mov eax,dword ptr ss: ; 把IAT放入我们的加密地址
007DB8A2 EB 01 jmp short WishGJ.007DB8A5
007DB8A4 40 inc eax ; 逐一读取EAX的字母
007DB8A5 8038 00 cmp byte ptr ds:,0 ; 计算读取了多少位
007DB8A8^ 75 FA jnz short WishGJ.007DB8A4 ; 当读完IAT指针位数就不跳
007DB8AA 40 inc eax ; 在次为IAT加1
007DB8AB E8 A8150000 call WishGJ.007DCE58 ; 加密CALL,我们跟进吧
-------------------------加密CALL------------------------------------------
007DCE58 60 pushad
007DCE59 8B85 80200000 mov eax,dword ptr ss: ; 取我们的下一句IAT,放入EAX
007DCE5F 8B9D 67260000 mov ebx,dword ptr ss: ; 取我们的下一句IAT的地址,放入EBX
007DCE65 0BC0 or eax,eax ; “或”EAX相加
007DCE67 75 07 jnz short WishGJ.007DCE70
007DCE69 C747 FC 0000000>mov dword ptr ds:,0
007DCE70 3B9D 3B1B0000 cmp ebx,dword ptr ss: ; 比较我们的IAT指针地址是否存在EBX
007DCE76 75 0C jnz short WishGJ.007DCE84 ; 如果IAT地址存在EBX则不跳
007DCE78 3947 FC cmp dword ptr ds:,eax ; 比较EAX是否为下一句加密的地址
007DCE7B 76 07 jbe short WishGJ.007DCE84 ; EAX是下一句IAT加密地址则跳
007DCE7D C747 FC 0000000>mov dword ptr ds:,0
007DCE84 61 popad
007DCE85 C3 retn ; 返回加密的结果
--------------------------------------------------------------------------------
007DB8B0 8985 6B260000 mov dword ptr ss:,eax ; 放入第二句真实的IAT
007DB8B6 66:8178 02 0080cmp word ptr ds:,8000
007DB8BC^ 74 87 je short WishGJ.007DB845 ; 比较是否需要在次加密下一句指针,不需要则跳
007DB8BE 8038 00 cmp byte ptr ds:,0 ; 比较是否需要加密下一句指针,需要则跳
007DB8C1^ 75 82 jnz short WishGJ.007DB845 ; 向上跳继续循环加密
--------------------------------------------------------------------------------
007DB845 8B85 6B260000 mov eax,dword ptr ss:
007DB84B 8B00 mov eax,dword ptr ds:
007DB84D A9 00000080 test eax,80000000
007DB852 74 1A je short WishGJ.007DB86E
007DB854 35 00000080 xor eax,80000000
007DB859 50 push eax
007DB85A 8985 2F1B0000 mov dword ptr ss:,eax
007DB860 8B85 6B260000 mov eax,dword ptr ss:
007DB866 C700 20202000 mov dword ptr ds:,202020
007DB86C EB 06 jmp short WishGJ.007DB874
007DB86E FFB5 6B260000 push dword ptr ss: ; 把IAT指针压栈
007DB874 FFB5 67260000 push dword ptr ss: ; 把IAT地址压栈
007DB87A FF95 FF0A0000 call dword ptr ss: ; 取我们的特殊函数
007DB880 85C0 test eax,eax ; 把构造出的IAT指针在EAX比较
007DB882 0F84 F7090000 je WishGJ.007DC27F ; 比较是否需要加密,加密则不跳
007DB888 E8 F9150000 call WishGJ.007DCE86 ; 加密CALL我们跟进吧
-------------------------加密CALL------------------------------------------
007DCE86 60 pushad
007DCE87 83BD 80200000 00 cmp dword ptr ss:,0 ; 比较上面的我们的IAT的地址
007DCE8E 75 24 jnz short WishGJ.007DCEB4 ; 这里跳则跳向下面执行加密
007DCE90 60 pushad ; 把上面的JNZ改NOP
007DCE91 6A 40 push 40
007DCE93 68 00100000 push 1000
007DCE98 8B85 371B0000 mov eax,dword ptr ss:
007DCE9E 6BC0 16 imul eax,eax,16
007DCEA1 83C0 64 add eax,64
007DCEA4 50 push eax
007DCEA5 6A 00 push 0
007DCEA7 FF95 030B0000 call dword ptr ss:
007DCEAD 8985 80200000 mov dword ptr ss:,eax
007DCEB3 61 popad
007DCEB4 8BBD 67260000 mov edi,dword ptr ss:
007DCEBA 3BBD 3B1B0000 cmp edi,dword ptr ss: ; 比较EDI是否为我们IAT地址
007DCEC0 0F85 82000000 jnz WishGJ.007DCF48 ; 是则跳,不是则取反
007DCEC6 8BF8 mov edi,eax ; 这里不跳我们指针加密,所以要把这个JNZ改JMP
--------------------------------------------------------------------------------
007DB89C 8B85 6B260000 mov eax,dword ptr ss: ; 把IAT放入我们的加密地址
007DB8A2 EB 01 jmp short WishGJ.007DB8A5
007DB8A4 40 inc eax ; 逐一读取EAX的字母
007DB8A5 8038 00 cmp byte ptr ds:,0 ; 计算读取了多少位
007DB8A8^ 75 FA jnz short WishGJ.007DB8A4 ; 当读完IAT指针位数就不跳
007DB8AA 40 inc eax ; 在次为IAT加1
007DB8AB E8 A8150000 call WishGJ.007DCE58 ; 加密CALL,我们跟进吧
007DB8B0 8985 6B260000 mov dword ptr ss:,eax ; 放入第二句真实的IAT
-------------------------加密CALL------------------------------------------
007DCE59 8B85 80200000 mov eax,dword ptr ss: ; 取我们的下一句IAT,放入EAX
007DCE5F 8B9D 67260000 mov ebx,dword ptr ss: ; 取我们的下一句IAT的地址,放入EBX
007DCE65 0BC0 or eax,eax ; “或”EAX相加
007DCE67 75 07 jnz short WishGJ.007DCE70
007DCE69 C747 FC 00000000 mov dword ptr ds:,0
007DCE70 3B9D 3B1B0000 cmp ebx,dword ptr ss: ; 比较我们的IAT指针地址是否存在EBX
007DCE76 75 0C jnz short WishGJ.007DCE84 ; 如果假IAT地址存在EBX则不跳
007DCE78 3947 FC cmp dword ptr ds:,eax ; 比较EAX是否为下一句加密的地址
007DCE7B 76 07 jbe short WishGJ.007DCE84 ; EAX是下一句IAT加密地址则跳
007DCE7D C747 FC 00000000 mov dword ptr ds:,0 ; 上面的JBE跳则执行加密,所以我们需要把他NOP掉
--------------------------------------------------------------------------------
007DB8C3 /EB 01 jmp short WishGJ.007DB8C6 //F4运行到这里看一下,我们的其他IAT全部出来啦
007DB8C5 |46 inc esi //而我们的第一句还是加密的怎么办
007DB8C6 \803E 00 cmp byte ptr ds:,0 //我们把我们需要修改的地址记下
007DB8C9^ 75 FA jnz short WishGJ.007DB8C5
007DB8CB 46 inc esi
007DB8CC 40 inc eax
007DB8CD 8B38 mov edi,dword ptr ds:
--------------------------------------------------------------------------------
007DCE8E-----------这句改NOP
007DCEC0-----------这句改JMP
007DCE7B-----------这句改JMP
从新载入程序,开始脱壳吧
--------------------------------------------------------------------------------
007DB68A >60 pushad //重新载入程序后
007DB68B BE 00908B00 mov esi,8B9000 //这里执行ESP定律
007DB690 8DBE 0080B4FF lea edi,dword ptr ds:
007DB696 57 push edi
007DB697 83CD FF or ebp,FFFFFFFF
007DB69A EB 3A jmp short WishGJ.007DB6D6
--------------------------------------------------------------------------------
007DB6D8 90 nop //取消第一个硬件断点
007DB6D9 60 pushad //单步F8走
007DB6DA E8 00000000 call WishGJ.007DB6DF //在这里执行ESP定律
007DB6DF 8B2C24 mov ebp,dword ptr ss: //CTRL+G把我们需要修改的地址全部改好
007DB6E2 83C4 04 add esp,4 //改好后我们F9运行程序
007DB6E5 E8 500D0000 call WishGJ.007DC43A
007DB6EA E8 740D0000 call WishGJ.007DC463
--------------------------------------------------------------------------------
007DB91D- E9 F6E4DFFF jmp WishGJ.005D9E18 //单步一步就到OEP啦
007DB922 83BD 231B0000 00 cmp dword ptr ss:,0
007DB929 74 16 je short WishGJ.007DB941
007DB92B 2B85 1B1B0000 sub eax,dword ptr ss:
007DB931 034424 4C add eax,dword ptr ss:
007DB935 50 push eax
007DB936 8B4424 50 mov eax,dword ptr ss:
--------------------------------------------------------------------------------
005D9E18 55 push ebp //运行lordPE把程序dump,在运行importRCE修复下就可以啦
005D9E19 8BEC mov ebp,esp //修复时会发现没有无效指针啦,证明我们的magic jump是对的
005D9E1B 83C4 F0 add esp,-10
005D9E1E 53 push ebx
005D9E1F B8 18955D00 mov eax,WishGJ.005D9518
005D9E24 E8 FFD4E2FF call WishGJ.00407328
005D9E29 8B1D 40EC5D00 mov ebx,dword ptr ds: ; WishGJ.005DFC38
005D9E2F E8 9899E9FF call WishGJ.004737CC
005D9E34 E8 8793E9FF call WishGJ.004731C0
--------------------------------------------------------------------------------
【经验总结】
第一次写这样的脱文,两个字太累,说实在的分析这个壳不累,但是写脱文太累
所以决定以后在不象这样写啦,太累啦,写得不好请大家不要见笑
--------------------------------------------------------------------------------
【版权声明】: 本文原创于小生我怕怕, 转载请注明作者并保持文章的完整, 谢谢!
2008年11月28日 0:28:04
[ 本帖最后由 小生我怕怕 于 2008-11-30 14:02 编辑 ] 师傅太厉害了膜拜.! 此篇文章太棒了分係超詳盡
連我這新手都看得懂
樓主真厲害,感謝學習了寶貴的一課 主要是处理IAT加密的吧,我先学习了。处理这些我不会 又上了一课,谢谢了! 支持小生,写教程很辛苦的。 收藏一个 学习先 十分佩服小生,手脱最劳神,还记录得这么详细,收藏学习。 很牛X很强大,支持一下,现在手生了好多,但是小生的教程是真的很好很牛X。看的很明白。 非常好的脱文!!!支持一下小生!