前几天脱壳破解了一个加了壳的程序Easy Watermark,用PEiD查是UltraProtect 1.x -> RISCO Software Inc(下面的脱壳过程感觉可能PEiD
报错,不是这个壳).但是一直有一个疑问没有解决:界面语言变化的问题。今天终于弄明白了,是CHS文件的问题,应用程序的文件名必须和
CHS的文件名相同。
下面开始这次不一样的脱壳之旅。
这个壳有很多的花指令
006051A8 58 pop eax
006051A9 FC cld
006051AA 83C5 FF add ebp, -1
006051AD ^ 0F85 7FFFFFFF jnz 00605132 //运行到这里,不要让它往回跳
006051B3 EB 01 jmp short 006051B6 //在这里F4
006051B5 E8 6681DE15 call 163ED320
006051BA EE out dx, al
将代码往下拉,看到一个明显的解码判断跳转
006052E3 FC cld
006052E4 4D dec ebp
006052E5 ^ 0F85 3CFFFFFF jnz 00605227 //F4运行到这里试一下,没错断下来了
006052EB EB 01 jmp short 006052EE //F4
将代码往下拉,看到如下代码
006053B9 EE out dx, al
006053BA 8135 15596000 5>xor dword ptr [605915], A78DA958
006053C4 83C3 FF add ebx, -1
006053C7 ^ 0F85 82FFFFFF jnz 0060534F
006053CD E8 01000000 call 006053D3 //F4到这里,F7进去,这个call距离当前eip很近
006054B4 66:8BCF mov cx, di
006054B7 1BF0 sbb esi, eax
006054B9 83C0 FF add eax, -1
006054BC ^ 0F85 7DFFFFFF jnz 0060543F
006054C2 EB 01 jmp short 006054C5 //F4
006055B7 8BEE mov ebp, esi
006055B9 FC cld
006055BA 83E8 01 sub eax, 1
006055BD ^ 0F85 68FFFFFF jnz 0060552B
006055C3 E8 01000000 call 006055C9 //F4
006056C8 41 inc ecx
006056C9 83C2 FF add edx, -1
006056CC ^ 0F85 6CFFFFFF jnz 0060563E
006056D2 E8 01000000 call 006056D8 //F4 F7
006057E9 66:81CB 5606 or bx, 656
006057EE 83C5 FF add ebp, -1
006057F1 ^ 0F85 40FFFFFF jnz 00605737
006057F7 7C 03 jl short 006057FC //F4 F7
00605802 /E9 BB4A0100 jmp 0061A2C2 //F7
0061A43D FC cld
0061A43E 83EE 01 sub esi, 1
0061A441 ^ 0F85 6CFFFFFF jnz 0061A3B3
0061A447 50 push eax //F4
0061A528 FC cld
0061A529 4A dec edx
0061A52A ^ 0F85 81FFFFFF jnz 0061A4B1
0061A530 /EB 01 jmp short 0061A533 //F4
0061A61A 4A dec edx
0061A61B 83C5 FF add ebp, -1
0061A61E ^ 0F85 65FFFFFF jnz 0061A589
0061A624 E8 01000000 call 0061A62A //F4
0061A76C F8 clc
0061A76D 85F5 test ebp, esi
0061A76F 83C2 FF add edx, -1
0061A772 ^ 0F85 84FFFFFF jnz 0061A6FC
0061A778 50 push eax //F4
0061A779 E8 01000000 call 0061A77F
0061A869 66:81DD 2659 sbb bp, 5926
0061A86E 83C2 FF add edx, -1
0061A871 ^ 0F85 74FFFFFF jnz 0061A7EB
0061A877 EB 01 jmp short 0061A87A //F4
0061A9E3 66:C1E8 F5 shr ax, 0F5
0061A9E7 66:C1D0 EA rcl ax, 0EA
0061A9EB 4F dec edi
0061A9EC ^ 0F85 4FFFFFFF jnz 0061A941
0061A9F2 74 03 je short 0061A9F7 //F4
0061AAFB F8 clc
0061AAFC 83EF 01 sub edi, 1
0061AAFF ^ 0F85 3DFFFFFF jnz 0061AA42
0061AB05 7E 03 jle short 0061AB0A //F4
出现了下面的代码,F7跟踪
0061AB1A 5A pop edx
0061AB1B 8F05 1D586000 pop dword ptr [60581D]
0061AB21 8B35 1D586000 mov esi, dword ptr [60581D]
0061AB27 FF35 D1596000 push dword ptr [6059D1] ; EasyWate.0058D8A8
0061AB2D 8F05 1D5B6000 pop dword ptr [605B1D]
0061AB33 8B05 1D5B6000 mov eax, dword ptr [605B1D]
0061AB39 891D 3D5A6000 mov dword ptr [605A3D], ebx
0061AB3F FF35 3D5A6000 push dword ptr [605A3D]
0061AB45 C70424 D4744000 mov dword ptr [esp], 004074D4
0061AB4C 8F05 1D5A6000 pop dword ptr [605A1D]
0061AB52 FF15 1D5A6000 call dword ptr [605A1D] //来到这里
0061AB58 FF35 F45E5900 push dword ptr [595EF4] ; EasyWate.00597C1C
0061AB5E 8B1C24 mov ebx, dword ptr [esp]
0061AB61 8F05 D5586000 pop dword ptr [6058D5]
0061AB67 8B03 mov eax, dword ptr [ebx]
0061AB69 56 push esi
0061AB6A 60 pushad
对于这个壳,在网上找到的资料都没什么用,不知道是不是PEiD报错,可能不是UltraProtect。总之我是这样操作最终来到了这个地方
0061AB1A 5A pop edx
0061AB1B 8F05 1D586000 pop dword ptr [60581D]
0061AB21 8B35 1D586000 mov esi, dword ptr [60581D]
0061AB27 FF35 D1596000 push dword ptr [6059D1] ; EasyWate.0058D8A8
0061AB2D 8F05 1D5B6000 pop dword ptr [605B1D] ; EasyWate.0058D8A8
0061AB33 8B05 1D5B6000 mov eax, dword ptr [605B1D] ; EasyWate.0058D8A8
0061AB39 891D 3D5A6000 mov dword ptr [605A3D], ebx
0061AB3F FF35 3D5A6000 push dword ptr [605A3D]
0061AB45 C70424 D4744000 mov dword ptr [esp], 004074D4
0061AB4C 8F05 1D5A6000 pop dword ptr [605A1D] ; EasyWate.004074D4
0061AB52 FF15 1D5A6000 call dword ptr [605A1D] ; call OEP 这里调用OEP*********
0061AB58 FF35 F45E5900 push dword ptr [595EF4] ; EasyWate.00597C1C
0061AB5E 8B1C24 mov ebx, dword ptr [esp]
0061AB61 8F05 D5586000 pop dword ptr [6058D5]
0061AB67 8B03 mov eax, dword ptr [ebx]
0061AB69 56 push esi
0061AB6A 60 pushad
为了方便下次来到OEP下硬件断点he 0061AB52
接下来用LordPE dump保存文件名为dumped.exe,用ImportREC的时候发现有两个可疑指针,直接剪掉,修复一下。
运行,没有任何反应。
OD载入dumped_.exe
F7单步跟踪,发现途中经过这样一个分支判断
00404B0D . BF 38765900 mov edi, 00597638
00404B12 . 8B47 08 mov eax, dword ptr [edi+8]
00404B15 . 85C0 test eax, eax ///eax=0
00404B17 . 74 54 je short 00404B6D
这之后程序就调用ExitThread结束了。
下硬件写断点hw 00597640
重新开始 F9断在此处
去除硬件断点
00404B74 /$ C705 14705900>mov dword ptr [597014], <jmp.&kernel32.Rai>
00404B7E |. C705 18705900>mov dword ptr [597018], <jmp.&kernel32.Rtl>
00404B88 |. A3 40765900 mov dword ptr [597640], eax //eax由调用函数传入
00404B8D |. 33C0 xor eax, eax /////////中断在此处
00404B8F |. A3 44765900 mov dword ptr [597644], eax
00404B94 |. 8915 48765900 mov dword ptr [597648], edx
00404B9A |. 8B42 04 mov eax, dword ptr [edx+4]
00404B9D |. A3 30705900 mov dword ptr [597030], eax
00404BA2 |. E8 A5FEFFFF call 00404A4C
00404BA7 |. C605 38705900>mov byte ptr [597038], 0
00404BAE |. E8 51FFFFFF call 00404B04
00404BB3 \. C3 retn
在堆栈中找到返回地址00407513,在反汇编窗口中跟随
回到OEP不远处
004074D4 >/$ 53 push ebx //OEP
004074D5 |. 8BD8 mov ebx, eax //这里**************
004074D7 |. 33C0 xor eax, eax
004074D9 |. A3 A4F05800 mov dword ptr [58F0A4], eax
004074DE |. 6A 00 push 0 ; /pModule = NULL
004074E0 |. E8 2BFFFFFF call <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
004074E5 |. A3 68765900 mov dword ptr [597668], eax
004074EA |. A1 68765900 mov eax, dword ptr [597668]
004074EF |. A3 B0F05800 mov dword ptr [58F0B0], eax
004074F4 |. 33C0 xor eax, eax
004074F6 |. A3 B4F05800 mov dword ptr [58F0B4], eax
004074FB |. 33C0 xor eax, eax
004074FD |. A3 B8F05800 mov dword ptr [58F0B8], eax
00407502 |. E8 C1FFFFFF call 004074C8
00407507 |. BA ACF05800 mov edx, 0058F0AC
0040750C |. 8BC3 mov eax, ebx //这个ebx是关键
0040750E |. E8 61D6FFFF call 00404B74 //这个调用
00407513 |. 5B pop ebx
00407514 \. C3 retn
因此这个程序的运行依赖于壳代码传递的eax(入口处的call dword ptr [605A1D])
重新运行原加壳程序,来到OEP
各个寄存器的值如下
EAX 0058D8A8 EasyWate.0058D8A8
ECX 0012FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFDC000
ESP 0012FFA8
EBP 0012FFC0
ESI FFFFFFFF
EDI 7C930738 ntdll.7C930738
EIP 004074D4 EasyWate.004074D4
dumped_.exe:
EAX 00000000
ECX 0012FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFDA000
ESP 0012FFC4
EBP 0012FFF0
ESI FFFFFFFF
EDI 7C930738 ntdll.7C930738
EIP 004074D4 dumped_.<模块入口点>
很明显eax值需要修改
ebx esp ebp 三个寄存器的值不一样
OD载入dumped_.exe后,手动修改eax的值为0058D8A8
shift+F9运行,程序还是没有反应退出了
看来堆栈也需要修改
原加壳程序栈
0012FFA8 0061AB58 <-------------------esp 返回地址
0012FFAC 7FFD7000 //ebx
0012FFB0 FFFFFFFF
0012FFB4 7FFD7000 //ebx
0012FFB8 FFFFFFFF
0012FFBC 7C930738 //edi
0012FFC0 0012FFF0 ////从这里往上是源程序多出来的数据,这是一个ebp数据(对比dumped_.exe的ebp)
0012FFC4 7C816FD7 返回到 kernel32.7C816FD7
0012FFC8 7C930738 ntdll.7C930738
0012FFCC FFFFFFFF
0012FFD0 7FFD7000
OD载入dumped_.exe
手动修改栈中的数据,并修改ebp为0012FFC0和esp为0012FFA8,eax改为0058D8A8,F9运行,程序顺利运行
接下来为程序打补丁,在OEP之前增加一段代码往栈中压入必需的数据和返回地址,同时给eax传值
找到58E000后面的数据都是0,同时打开WinHex确认,都是空数据,可以使用。
增加如下代码:
0058E000 55 push ebp
0058E001 8BEC mov ebp, esp
0058E003 57 push edi
0058E004 6A FF push -1
0058E006 53 push ebx
0058E007 6A FF push -1
0058E009 53 push ebx
0058E00A 68 58AB6100 push 0061AB58
0058E00F 53 push ebx //恢复OEP处的前五个字节的功能
0058E010 BB A8D85800 mov ebx, 0058D8A8
0058E015 33C0 xor eax, eax
0058E017 ^ E9 BD94E7FF jmp 004074D9
上面的代码用OD无法复制到可执行文件中,只能打开WinHex,定位18E000(58E000-400000)手动添加
55 8B EC 57 6A FF 53 6A FF 53 68 58 AB 61 00 53 BB A8 D8 58 00 33 C0 E9 BD 94 E7 FF
将入口改为
004074D4 > $ /E9 276B1800 jmp 0058E000
运行修改后的程序,一切正常就是语言有点问题,只要将dumped_.exe改为EasyWatermark.exe,中文的语言界面就又出现了。
下面破解的就不说了,这个程序共有3个验证子程序,8个地方进行了注册验证,爆破还是比较容易的。因为接下来要完成毕业实习报告,没时
间跟踪算法了,就此打住。
关于这个壳,我还是有疑问,真的是UltraProtect?只知道PE文件最后一个区段是.perplex。
[课程]Linux pwn 探索篇!