【文章标题】: 紫微斗数人生预测系统简易解密全程
【文章作者】: fonge
【软件名称】: 紫微斗数人生预测系统
【软件大小】: 2.5M
【下载地址】: http://www.ichingsoft.com/zhouyi/winzw.htm
【加壳方式】: Armadillo_Copy-II
【保护方式】: 序列号护方式+天数限制
【编写语言】: delphi
【使用工具】: OllyICE,PEiD,LordPE,ImportREC
【操作平台】: XP
【软件介绍】: 紫微斗数号称“天下第一神数”。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
序列号护方式+天数限制+Armadillo_Copy-II
查壳:Armadillo的,版本不准确。
脱壳前准备:通看一遍看雪精华和密解脱壳文集中关于Armadillo壳相关的,做好最坏的打算。
一.开始脱壳之旅~
用IsDebug插件去掉OllyICE的调试器标志。
0060F243 >/$ 55 push ebp //停在这里
0060F244 |. 8BEC mov ebp, esp
0060F246 |. 6A FF push -1
0060F248 |. 68 408F6300 push 00638F40
0060F24D |. 68 80EF6000 push 0060EF80 ; SE 处理程序安装
0060F252 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0060F258 |. 50 push eax
0060F259 |. 64:8925 00000>mov dword ptr fs:[0], esp
0060F260 |. 83EC 58 sub esp, 58
BP WaitForDebugEvent
中断后取消断点,看堆栈:
0012DC8C 005FF386 /CALL 到 WaitForDebugEvent 来自 ZWDS.005FF380
0012DC90 0012ED7C |pDebugEvent = 0012ED7C
0012DC94 000003E8 \Timeout = 1000. ms
0012DC98 7C910738 ntdll.7C910738
在数据窗口定位到0012ED7C处,准备看OEP值
接着下断:BP WriteProcessMemory,断下
数据窗口:
0012ED7C 01 00 00 00 54 0E 00 00 ...T..
0012ED84 88 0B 00 00 01 00 00 80 ?....€
0012ED8C 00 00 00 00 00 00 00 00 ........
0012ED94 74 09 58 00 02 00 00 00 t.X....
0012ED9C 00 00 00 00 74 09 58 00 ....t.X.
0012EDA4 74 09 58 00 01 00 00 00 t.X....
可以看到OEP=00580974
现在Alt+F9返回代码窗口
Ctrl+F在当前位置下搜索命令:or eax,0FFFFFFF8
找到第一处在005FF956处
005FF953 . /79 05 jns short 005FF95A
005FF955 . |48 dec eax
005FF956 . |83C8 F8 or eax, FFFFFFF8
005FF959 . |40 inc eax
005FF95A > \33C9 xor ecx, ecx
往上翻找到cmp dword ptr ss:[ebp-A34],0处设置断点。
005FF908 >^\EB F9 jmp short 005FF903
005FF90A > 83BD CCF5FFFF>cmp dword ptr [ebp-A34], 0 //下断,Shift+F9中断下来 把[ebp-A34]清0
005FF911 . 0F8C A8020000 jl 005FFBBF
005FF917 . 8B8D CCF5FFFF mov ecx, dword ptr [ebp-A34]
005FF91D . 3B0D D4A36300 cmp ecx, dword ptr [63A3D4] //注意[63A3D4]
005FF923 . 0F8D 96020000 jge 005FFBBF //解码结束后跳转005FFBBF 在005FFBBF处下断
005FF929 . 8B95 40F6FFFF mov edx, dword ptr [ebp-9C0]
005FF92F . 81E2 FF000000 and edx, 0FF
往下找and eax,off等如下代码
005FF9D5 . E8 68210000 call 00601B42
005FF9DA . 83C4 0C add esp, 0C
005FF9DD . 25 FF000000 and eax, 0FF
005FF9E2 . 85C0 test eax, eax
005FF9E4 . 0F84 D5010000 je 005FFBBF
005FF9EA > 837D D8 00 cmp dword ptr [ebp-28], 0
修改之:
005FF9DD FF85 CCF5FFFF inc dword ptr [ebp-0A34]
005FF9E3 C705 D8A36300>mov dword ptr [63A3D8], 1 //63A3D4见清0下面的地址
005FF9ED ^ E9 18FFFFFF jmp 005FF90A //跳到我们清0的那个位置
bp 005FFBBF
继续Shift+F9,中断在005FFBBF处
此时子进程代码已经解开,运行LordPE,完全Dump出子进程
—————————————————————————————————
处理输入表
没有耐性完美修复..
再次载入主程序
IsDebug插件隐之
下断:BP DebugActiveProcess 中断后看堆栈:
0012DC90 005FF1DA /CALL 到 DebugActiveProcess 来自 ZWDS.005FF1D4
0012DC94 0000031C \ProcessId = 31C
0012DC98 7C910738 ntdll.7C910738
新开一个OllyICE,附加进程ID 31C的子进程
F9,再F12,会暂停在EP处
0060F243 > - EB FE jmp short <模块入口点>
0060F245 EC in al, dx
//子进程在EP处死循环 修改回原来EP处的代码:55 8B
干掉一个进程。
BP OpenMutexA Shift+F9,中断后看堆栈:
0012F798 005FADB8 /CALL 到 OpenMutexA 来自 ZWDS.005FADB2
0012F79C 001F0001 |Access = 1F0001
0012F7A0 00000000 |Inheritable = FALSE
0012F7A4 0012FDD8 \MutexName = "31C::DA9E430C11" //注意0012FDD8
找个空间键入分离代码,Ctrl+G:401000
00401000 60 pushad
00401001 9C pushfd
00401002 68 D8FD1200 push 12FDD8 ; ASCII "9A8::DA9E430C11"
00401007 33C0 xor eax, eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 2FD9407C call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 04DA407C jmp kernel32.OpenMutexA
609c68d8fd120033c05050e82fd9407c9d61e904da407c
push 12FDD8认识吧,堆栈里看到的那个值
在401000处新建EIP,F9运行,再次中断在OpenMutexA处
取消OpenMutexA断点。
返回401000处,“撤销选择”,清掉写入的代码
下断:HE GetModuleHandleA Shift+F9(为什么要用Shift+F9:因为随时都可能有异常出现,用它安全一点),注意看堆栈:
00129528 00F96DF3 /CALL 到 GetModuleHandleA 来自 00F96DED
0012952C 00FABC1C \pModule = "kernel32.dll"
00129530 00FACEC4 ASCII "VirtualAlloc"
00129534 00FAFA98
00129538 7C9010ED ntdll.RtlLeaveCriticalSection
00129528 00F96E10 /CALL 到 GetModuleHandleA 来自 00F96E0A
0012952C 00FABC1C \pModule = "kernel32.dll"
00129530 00FACEB8 ASCII "VirtualFree"
00129534 00FAFA98
00129538 7C9010ED ntdll.RtlLeaveCriticalSection
出这个时,快了,下一个就到了
0012928C 00F85CE1 /CALL 到 GetModuleHandleA 来自 00F85CDB
00129290 001293DC \pModule = "kernel32.dll"
00129294 00000000
00129298 EC6C0000
这时,到站了,取消GetModuleHandleA处断点,Alt+F9返回
00F85CDB FF15 B860FA00 call dword ptr [FA60B8] ; kernel32.GetModuleHandleA
00F85CE1 8B0D AC40FB00 mov ecx, dword ptr [FB40AC]
00F85CE7 89040E mov dword ptr [esi+ecx], eax //返回到这里
00F85CEA A1 AC40FB00 mov eax, dword ptr [FB40AC]
00F85CEF 391C06 cmp dword ptr [esi+eax], ebx
00F85CF2 75 16 jnz short 00F85D0A
00F85CF4 8D85 B4FEFFFF lea eax, dword ptr [ebp-14C]
00F85CFA 50 push eax
00F85CFB FF15 BC62FA00 call dword ptr [FA62BC] ; kernel32.LoadLibraryA
00F85D01 8B0D AC40FB00 mov ecx, dword ptr [FB40AC]
00F85D07 89040E mov dword ptr [esi+ecx], eax
00F85D0A A1 AC40FB00 mov eax, dword ptr [FB40AC]
00F85D0F 391C06 cmp dword ptr [esi+eax], ebx
00F85D12 0F84 2F010000 je 00F85E47 //传说中的Magic Jump! 修改为:jmp 00F85E47
00F85D18 33C9 xor ecx, ecx
00F85D1A 8B07 mov eax, dword ptr [edi]
00F85D1C 3918 cmp dword ptr [eax], ebx
00F85D1E 74 06 je short 00F85D26
有时间校验,要处理一下
下断:BP GetTickCount 中断后取消断点返回,红色区域了
00F9C003 FF15 7C62FA00 call dword ptr [FA627C] ; kernel32.GetTickCount
00F9C009 8985 A4D4FFFF mov dword ptr [ebp-2B5C], eax //返回到这里
00F9C00F 6A 01 push 1
00F9C011 58 pop eax
00F9C012 85C0 test eax, eax
00F9C014 0F84 A8030000 je 00F9C3C2
往下面翻,还有一处GetTickCount取时间,其实也是je 00F9C3C2跳向的地方
00F9C39E /73 1D jnb short 00F9C3BD
00F9C3A0 |8B85 10D9FFFF mov eax, dword ptr [ebp-26F0]
00F9C3A6 |8B8D 68CAFFFF mov ecx, dword ptr [ebp-3598]
00F9C3AC |8908 mov dword ptr [eax], ecx //函数写入。在这里下断,可以看见输入表函数开始地址005B51E0
00F9C3AE |8B85 10D9FFFF mov eax, dword ptr [ebp-26F0]
00F9C3B4 |83C0 04 add eax, 4
00F9C3B7 |8985 10D9FFFF mov dword ptr [ebp-26F0], eax
00F9C3BD ^\E9 4DFCFFFF jmp 00F9C00F
00F9C3C2 FF15 7C62FA00 call dword ptr [FA627C] ; kernel32.GetTickCount
00F9C3C8 2B85 A4D4FFFF sub eax, dword ptr [ebp-2B5C]
00F9C3CE 8B8D A8D4FFFF mov ecx, dword ptr [ebp-2B58]
00F9C3D4 6BC9 32 imul ecx, ecx, 32
00F9C3D7 81C1 D0070000 add ecx, 7D0
00F9C3DD 3BC1 cmp eax, ecx
00F9C3DF 76 07 jbe short 00F9C3E8 //修改为:JMP 00E8913C,跳过它的检测
00F9C3E1 C685 34D9FFFF 0>mov byte ptr [ebp-26CC], 1
00F9C3E8 83BD E4D7FFFF 0>cmp dword ptr [ebp-281C], 0
00F9C3EF 0F85 8A000000 jnz 00F9C47F
00F9C3F5 0FB685 94D4FFFF movzx eax, byte ptr [ebp-2B6C]
00F9C3FC 85C0 test eax, eax
00F9C3FE 74 7F je short 00F9C47F
00F9C400 6A 00 push 0
00F9C402 8B85 98D4FFFF mov eax, dword ptr [ebp-2B68]
00F9C408 C1E0 02 shl eax, 2
00F9C40B 50 push eax
00F9C40C 8B85 0CD8FFFF mov eax, dword ptr [ebp-27F4]
00F9C412 0385 90D4FFFF add eax, dword ptr [ebp-2B70]
00F9C418 50 push eax
00F9C419 E8 131E0000 call 00F9E231
00F9C41E 83C4 0C add esp, 0C
00F9C421 8B85 98D4FFFF mov eax, dword ptr [ebp-2B68]
00F9C427 C1E0 02 shl eax, 2
00F9C42A 50 push eax
00F9C42B FFB5 6CD9FFFF push dword ptr [ebp-2694]
00F9C431 8B85 0CD8FFFF mov eax, dword ptr [ebp-27F4]
00F9C437 0385 90D4FFFF add eax, dword ptr [ebp-2B70]
00F9C43D 50 push eax
00F9C43E E8 4B8B0000 call 00FA4F8E ; jmp 到 msvcrt.memcpy
00F9C443 83C4 0C add esp, 0C
00F9C446 6A 01 push 1
00F9C448 8B85 98D4FFFF mov eax, dword ptr [ebp-2B68]
00F9C44E C1E0 02 shl eax, 2
00F9C451 50 push eax
00F9C452 8B85 0CD8FFFF mov eax, dword ptr [ebp-27F4]
00F9C458 0385 90D4FFFF add eax, dword ptr [ebp-2B70]
00F9C45E 50 push eax
00F9C45F E8 CD1D0000 call 00F9E231
00F9C464 83C4 0C add esp, 0C
00F9C467 8B85 6CD9FFFF mov eax, dword ptr [ebp-2694]
00F9C46D 8985 A4ABFFFF mov dword ptr [ebp+FFFFABA4], eax
00F9C473 FFB5 A4ABFFFF push dword ptr [ebp+FFFFABA4]
00F9C479 E8 0A8B0000 call 00FA4F88 ; jmp 到 msvcrt.operator delete
00F9C47E 59 pop ecx
00F9C47F ^ E9 30F7FFFF jmp 00F9BBB4
00F9C484 8B85 F0D7FFFF mov eax, dword ptr [ebp-2810] //这个地方下断,输入表解码走出循环的地方
中断后输入表处理完毕
运行ImportREC,选择这个进程。填入RVA=001B51E0、Size=00001000,Get Import剪切掉无效函数,修改OEP RVA=00180974,FixDump,正常运行!
查壳之,delphi6-7
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二.突破注册封锁线的限制
dede可用,定位
窗体FormMain ->之actRegExecute(事件)->地址0057FDC0
为什么定位为个事件而不是注册按钮的事件呢!
一方面,不懂算法,不打算写注册机
二方面,短时间内还没找到在哪
思路:一般在弹出注册框之时会验证一次存储的注册码,注册,将会显示已注册相关的东东,不会再让输入注册码之类的等等
所以呢,果然,关键call就在里面,
下断bp 0057FDC0
0057FDC0 55 push ebp //断在这里
0057FDC1 8BEC mov ebp, esp
0057FDC3 33C9 xor ecx, ecx
0057FDC5 51 push ecx
0057FDC6 51 push ecx
0057FDC7 51 push ecx
0057FDC8 51 push ecx
0057FDC9 51 push ecx
0057FDCA 51 push ecx
0057FDCB 53 push ebx
0057FDCC 8BD8 mov ebx, eax
0057FDCE 33C0 xor eax, eax
0057FDD0 55 push ebp
0057FDD1 68 24FF5700 push 0057FF24
0057FDD6 64:FF30 push dword ptr fs:[eax]
0057FDD9 64:8920 mov dword ptr fs:[eax], esp
0057FDDC 8B83 D4050000 mov eax, dword ptr [ebx+5D4]
0057FDE2 E8 5DDFFEFF call 0056DD44 //直觉他是关键call,一般他放最前面,确实,他就是关键call
0057FDE7 84C0 test al, al
0057FDE9 0F85 F0000000 jnz 0057FEDF //我们试试爆破,果然,有好现像出现,所以我们要跟进上面的那个call
0057FDEF 8B0D E8135B00 mov ecx, dword ptr [5B13E8] ; dumped_.005B2C38
0057FDF5 8B09 mov ecx, dword ptr [ecx]
0057FDE2 E8 5DDFFEFF call 0056DD44 //F2 下断
断下, F7进入
0056DD44 E8 E3010000 call 0056DF2C //再进,果然之
0056DD49 C3 retn
F7进入,一片光明啊
0056DF2C 55 push ebp
0056DF2D 8BEC mov ebp, esp
0056DF2F 6A 00 push 0
0056DF31 6A 00 push 0
0056DF33 6A 00 push 0
0056DF35 53 push ebx
0056DF36 56 push esi
0056DF37 8BF0 mov esi, eax
0056DF39 33C0 xor eax, eax
0056DF3B 55 push ebp
0056DF3C 68 C5DF5600 push 0056DFC5
0056DF41 64:FF30 push dword ptr fs:[eax]
0056DF44 64:8920 mov dword ptr fs:[eax], esp
0056DF47 837E 68 00 cmp dword ptr [esi+68], 0 //猜想是比较用户名,未考证..呵呵,爆之
0056DF4B 74 5B je short 0056DFA8
0056DF4D 8D55 FC lea edx, dword ptr [ebp-4]
0056DF50 8BC6 mov eax, esi
0056DF52 E8 F5FCFFFF call 0056DC4C
0056DF57 837D FC 00 cmp dword ptr [ebp-4], 0 //猜想是比较序列号,未考证..呵呵,爆之
0056DF5B 74 4B je short 0056DFA8
0056DF5D 8D45 F8 lea eax, dword ptr [ebp-8]
0056DF60 50 push eax
0056DF61 8D55 F4 lea edx, dword ptr [ebp-C]
0056DF64 8BC6 mov eax, esi
0056DF66 E8 E1FCFFFF call 0056DC4C
0056DF6B 8B55 F4 mov edx, dword ptr [ebp-C]
0056DF6E 8B4E 68 mov ecx, dword ptr [esi+68]
0056DF71 8BC6 mov eax, esi
0056DF73 E8 38F6FFFF call 0056D5B0
0056DF78 8B45 F8 mov eax, dword ptr [ebp-8]
0056DF7B BA DCDF5600 mov edx, 0056DFDC ; 645364631365423154824
0056DF80 E8 7BB1E9FF call 00409100 //最终码比较call,爆之
0056DF85 85C0 test eax, eax
0056DF87 75 14 jnz short 0056DF9D
0056DF89 B1 01 mov cl, 1
0056DF8B 8B56 68 mov edx, dword ptr [esi+68]
0056DF8E 8BC6 mov eax, esi
0056DF90 E8 77FEFFFF call 0056DE0C
0056DF95 84C0 test al, al
0056DF97 75 04 jnz short 0056DF9D
0056DF99 B3 01 mov bl, 1
0056DF9B EB 0D jmp short 0056DFAA
0056DF9D 33DB xor ebx, ebx
0056DF9F 8BC6 mov eax, esi
0056DFA1 E8 620B0000 call 0056EB08
0056DFA6 EB 02 jmp short 0056DFAA
0056DFA8 33DB xor ebx, ebx
0056DFAA 33C0 xor eax, eax
0056DFAC 5A pop edx
0056DFAD 59 pop ecx
0056DFAE 59 pop ecx
0056DFAF 64:8910 mov dword ptr fs:[eax], edx
0056DFB2 68 CCDF5600 push 0056DFCC
0056DFB7 8D45 F4 lea eax, dword ptr [ebp-C]
0056DFBA BA 03000000 mov edx, 3
0056DFBF E8 B867E9FF call 0040477C
0056DFC4 C3 retn
最最关键call找到,启动里调用了好几次,可知,一爆全身破,
收工
不再有其他危险动作,固定码比较,不....
--------------------------------------------------------------------------------
2007年07月21日 14:07:00
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课