霸王卸甲――秦赢甲胄反盗版加密软件V1.01主程序脱壳
下载页面: http://www2.skycn.com/soft/16995.html
软件大小: 1961 KB
软件语言: 简体中文
软件类别: 国产软件 / 共享版 / 编程其它
应用平台: Win9x/NT/2000/XP
加入时间: 2005-01-04 15:59:27
下载次数: 908
推荐等级: ***
开 发 商: http://www.vterminal.cn/
软件介绍: 系统优点1.用户注册A.用户注册方便,终端用户不需要手动输入序列号认证码等等,一切由注册端软件自动完成;B.用户机器的硬件信息作为注册码/加密密钥;C.一个拷贝只能在同一台机器上注册;D.只要是同一台机器,可以在这台机器上注册多次;E.只能在注册的那台机器上运行2.使用理论上安全的密码学协议和算法,保证不可脱机破解A.不能通过注册机破解;B.不能通过散发序列号破解3.更改检测(可以检测病毒和破解者更改)4.反跟踪功能(Anti-Debug)5.运行时代码完整性校验A.可防止Cracker跟踪时设置断点;B.可防止通过补丁程序破解6.反 Dump 功能(Anti-Dump)7.反反汇编功能(Anit-Disassembler)8.可以有效的管理经销商和序列号的发放;9.可以统计软件的销售数量;10.可以有效的管理用户注册。
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【调试环境】:Win2003、Ollydbg、PEiD、LordPE、ImportREC
―――――――――――――――――――――――――――――――――
【脱壳过程】:
LicenseManager V1.0算是比较新的国产壳了,看作者主页介绍的比较好,所以下载看看。
壳在下载后就脱了,却直至今天才抽出时间来整理教程。
另外篇名的“霸王卸甲”只是和WiNrOOt开玩笑偶然提起的,没有戏谑的意思。
放个PEiD的Sign,选择PEiD的External Scan扫描方式即可侦测出。
[Vterminal V1.0X -> Lei Peng]
signature = E8 00 00 00 00 58 05 ?? ?? ?? ?? 9C 50 C2 04 00
ep_only = true
―――――――――――――――――――――――――――――――――
一、Magic Jump:避开输入表加密
老规矩:用IsDebug V1.4插件去掉Ollydbg的调试器标志。
00471000 E8 00000000 call lm.00471005
//进入Ollydbg后暂停在这
00471005 58 pop eax
00471006 05 3B060000 add eax,63B
0047100B 9C pushfd
0047100C 50 push eax
0047100D C2 0400 retn 4
下断:HE GetVersion F9运行,中断后取消断点。Alt+F9返回
00471870 E8 AE780000 call lm.00479123
00471875 3D 00000080 cmp eax,80000000
//返回这里
0047187A 0F82 D3010000 jb lm.00471A53
Ctrl+F搜索命令:test byte ptr ds:[eax+38],60
找到在00475297处,F4过去。这里就是处理输入表的地方了。
当然,也可以通过HE LoadLibraryA来到这个地方。
00475297 F640 38 60 test byte ptr ds:[eax+38],60
//F4到这里!
0047529B 74 0E je short lm.004752AB
0047529D 8B5424 2C mov edx,dword ptr ss:[esp+2C]
004752A1 8B8B 1C020000 mov ecx,dword ptr ds:[ebx+21C]
004752A7 890A mov dword ptr ds:[edx],ecx
004752A9 EB 0A jmp short lm.004752B5
004752AB 8B4424 2C mov eax,dword ptr ss:[esp+2C]
004752AF C700 00000000 mov dword ptr ds:[eax],0
004752B5 E8 34F7FFFF call lm.004749EE
//自校验,这部分下面再处理
004752BA 8B8B 00020000 mov ecx,dword ptr ds:[ebx+200]
004752C0 8BB3 08020000 mov esi,dword ptr ds:[ebx+208]
004752C6 8B69 10 mov ebp,dword ptr ds:[ecx+10]
//[ecx+10]=[00471110]=000547D0 这是原来输入表的RVA
…… ……省略一段恢复DLL名、函数名的处理…… ……
004753A8 E8 78FAFFFF call lm.00474E25
//GetProcAddress
004753AD 8B08 mov ecx,dword ptr ds:[eax]
//[eax]保存的是取得的函数系统地址
004753AF 57 push edi
004753B0 890F mov dword ptr ds:[edi],ecx
//API函数的系统地址填充到IAT中 ★
004753B2 8BCB mov ecx,ebx
004753B4 E8 4EFCFFFF call lm.00475007
//判断是否要加密 进入修改!
004753B9 8B93 00020000 mov edx,dword ptr ds:[ebx+200]
004753BF F642 38 08 test byte ptr ds:[edx+38],8
004753C3 74 11 je short lm.004753D6
004753C5 3BF7 cmp esi,edi
004753C7 74 0D je short lm.004753D6
004753C9 6A 04 push 4
004753CB 68 CC000000 push 0CC
004753D0 56 push esi
004753D1 E8 77F1FFFF call lm.0047454D
004753D6 8B4424 14 mov eax,dword ptr ss:[esp+14]
004753DA 83C6 04 add esi,4
004753DD 83C7 04 add edi,4
004753E0 48 dec eax
004753E1 897C24 30 mov dword ptr ss:[esp+30],edi
004753E5 894424 14 mov dword ptr ss:[esp+14],eax
004753E9 0F85 2FFFFFFF jnz lm.0047531E
004753EF 8B6C24 18 mov ebp,dword ptr ss:[esp+18]
004753F3 E8 F6F5FFFF call lm.004749EE
//同样的自校验
004753F8 8B83 00020000 mov eax,dword ptr ds:[ebx+200]
004753FE F640 38 08 test byte ptr ds:[eax+38],8
00475402 74 28 je short lm.0047542C
00475404 8B45 0C mov eax,dword ptr ss:[ebp+C]
00475407 8B93 08020000 mov edx,dword ptr ds:[ebx+208]
0047540D 03C2 add eax,edx
0047540F 8038 00 cmp byte ptr ds:[eax],0
00475412 74 0B je short lm.0047541F
00475414 C600 CC mov byte ptr ds:[eax],0CC
//用CC填充处理的DLL名
00475417 8A48 01 mov cl,byte ptr ds:[eax+1]
0047541A 40 inc eax
0047541B 84C9 test cl,cl
0047541D 75 F5 jnz short lm.00475414
0047541F 6A 14 push 14
00475421 68 CC000000 push 0CC
00475426 55 push ebp
00475427 E8 21F1FFFF call lm.0047454D
0047542C 8B4424 1C mov eax,dword ptr ss:[esp+1C]
00475430 83C5 14 add ebp,14
00475433 48 dec eax
00475434 896C24 18 mov dword ptr ss:[esp+18],ebp
00475438 894424 1C mov dword ptr ss:[esp+1C],eax
0047543C 0F85 A2FEFFFF jnz lm.004752E4
//循环处理
00475442 5F pop edi
00475443 5E pop esi
00475444 5D pop ebp
00475445 5B pop ebx
00475446 83C4 1C add esp,1C
00475449 C2 0400 retn 4
//修改好第二步的自校验后就可以F4到到这里,输入表处理就结束了
――――――――――――――――――――――――
进入call 00475007,修改Magic Jump
00475007 53 push ebx
00475008 56 push esi
00475009 57 push edi
0047500A 8B7C24 10 mov edi,dword ptr ss:[esp+10]
0047500E 8BF1 mov esi,ecx
00475010 833F 00 cmp dword ptr ds:[edi],0
00475013 75 2B jnz short lm.00475040
00475040 8B86 A0020000 mov eax,dword ptr ds:[esi+2A0]
//[esi+2A0]处保存的就是是否加密的标志 ★ 为0则不加密
00475046 85C0 test eax,eax
00475048 0F84 D5000000 je lm.00475123
//修改为:jmp 00475123 ★ Magic Jump!下面则是加密部分,很弱
0047504E 8B86 00020000 mov eax,dword ptr ds:[esi+200]
00475054 F640 38 20 test byte ptr ds:[eax+38],20
00475058 0F84 C5000000 je lm.00475123
0047505E 81BE 14020000 07180>cmp dword ptr ds:[esi+214],1807
00475068 0F83 B5000000 jnb lm.00475123
0047506E 33C9 xor ecx,ecx
00475070 8B86 18020000 mov eax,dword ptr ds:[esi+218]
00475076 8BD0 mov edx,eax
00475078 8BD8 mov ebx,eax
0047507A C1EA 13 shr edx,13
0047507D C1E3 0D shl ebx,0D
00475080 0BD3 or edx,ebx
00475082 8BD8 mov ebx,eax
00475084 C1EB 1D shr ebx,1D
00475087 C1E0 03 shl eax,3
0047508A 0BD8 or ebx,eax
0047508C 8D4413 61 lea eax,dword ptr ds:[ebx+edx+61]
00475090 33D2 xor edx,edx
00475092 BB 07180000 mov ebx,1807
00475097 8986 18020000 mov dword ptr ds:[esi+218],eax
0047509D F7F3 div ebx
0047509F 8B86 1C020000 mov eax,dword ptr ds:[esi+21C]
004750A5 41 inc ecx
004750A6 8A5CD0 03 mov bl,byte ptr ds:[eax+edx*8+3]
004750AA 84DB test bl,bl
004750AC 74 05 je short lm.004750B3
004750AE 83F9 64 cmp ecx,64
004750B1 72 BD jb short lm.00475070
004750B3 8B8E 1C020000 mov ecx,dword ptr ds:[esi+21C]
004750B9 8D04D1 lea eax,dword ptr ds:[ecx+edx*8]
004750BC 8A4CD1 03 mov cl,byte ptr ds:[ecx+edx*8+3]
004750C0 84C9 test cl,cl
004750C2 75 5F jnz short lm.00475123
004750C4 8ACA mov cl,dl
004750C6 80C1 53 add cl,53
004750C9 8808 mov byte ptr ds:[eax],cl
004750CB 8A07 mov al,byte ptr ds:[edi]
004750CD 8B8E 1C020000 mov ecx,dword ptr ds:[esi+21C]
004750D3 04 3D add al,3D
004750D5 8844D1 01 mov byte ptr ds:[ecx+edx*8+1],al
004750D9 8B07 mov eax,dword ptr ds:[edi]
004750DB 8B8E 1C020000 mov ecx,dword ptr ds:[esi+21C]
004750E1 C1E8 08 shr eax,8
004750E4 8844D1 02 mov byte ptr ds:[ecx+edx*8+2],al
004750E8 8B86 1C020000 mov eax,dword ptr ds:[esi+21C]
004750EE 8D0CD5 08000000 lea ecx,dword ptr ds:[edx*8+8]
004750F5 C644D0 03 E9 mov byte ptr ds:[eax+edx*8+3],0E9
004750FA 8B1F mov ebx,dword ptr ds:[edi]
004750FC 8B86 1C020000 mov eax,dword ptr ds:[esi+21C]
00475102 2BD9 sub ebx,ecx
00475104 2BD8 sub ebx,eax
00475106 895CD0 04 mov dword ptr ds:[eax+edx*8+4],ebx
0047510A 8B86 1C020000 mov eax,dword ptr ds:[esi+21C]
00475110 8D4CD0 03 lea ecx,dword ptr ds:[eax+edx*8+3]
00475114 890F mov dword ptr ds:[edi],ecx
00475116 8B86 14020000 mov eax,dword ptr ds:[esi+214]
0047511C 40 inc eax
0047511D 8986 14020000 mov dword ptr ds:[esi+214],eax
00475123 5F pop edi
00475124 5E pop esi
00475125 5B pop ebx
00475126 C2 0400 retn 4
你如果跟踪的话,可以发现壳判别是否是如下几个函数,是则加密
00474BBA 61 64 76 61 70 69 33 32 2E 64 6C 6C 00 63 6F 6D advapi32.dll.com
00474BCA 64 6C 67 33 32 2E 64 6C 6C 00 67 64 69 33 32 2E dlg32.dll.gdi32.
00474BDA 64 6C 6C 00 6B 65 72 6E 65 6C 33 32 2E 64 6C 6C dll.kernel32.dll
00474BEA 00 6E 74 64 6C 6C 2E 64 6C 6C 00 6F 6C 65 33 32 .ntdll.dll.ole32
00474BFA 2E 64 6C 6C 00 73 68 65 6C 6C 33 32 2E 64 6C 6C .dll.shell32.dll
00474C0A 00 73 68 6C 77 61 70 69 2E 64 6C 6C 00 75 73 65 .shlwapi.dll.use
00474C1A 72 33 32 2E 64 6C 6C 00 77 69 6E 73 70 6F 6F 6C r32.dll.winspool
00474C2A 2E 64 72 76 00 77 69 6E 73 6F 63 6B 33 32 2E 64 .drv.winsock32.d
00474C3A 6C 6C 00 6D 73 76 63 70 36 30 2E 64 6C 6C ll.msvcp60.dll
―――――――――――――――――――――――――――――――――
二、搞定自校验
进入call 004749EE
虽然作者的话语有点“威胁”效果,殊不知仅仅根据他的对话框也就能定位检验的地方。
004749EE 83EC 10 sub esp,10
004749F1 53 push ebx
004749F2 55 push ebp
004749F3 56 push esi
004749F4 E8 77D4FFFF call lm.00471E70
004749F9 8BF0 mov esi,eax
004749FB 8D4424 0C lea eax,dword ptr ss:[esp+C]
004749FF 56 push esi
00474A00 50 push eax
00474A01 E8 20DFFFFF call lm.00472926
00474A06 83C4 08 add esp,8
00474A09 8D8E 8C000000 lea ecx,dword ptr ds:[esi+8C]
00474A0F 8D5424 0C lea edx,dword ptr ss:[esp+C]
00474A13 6A 10 push 10
00474A15 51 push ecx
00474A16 52 push edx
00474A17 E8 1CFDFFFF call lm.00474738
00474A1C E8 00000000 call lm.00474A21
00474A21 5B pop ebx
00474A22 81C3 6E350000 add ebx,356E
00474A28 E8 00000000 call lm.00474A2D
00474A2D 5D pop ebp
00474A2E 81C5 1E510000 add ebp,511E
00474A34 85C0 test eax,eax
00474A36 74 2A je short lm.00474A62
//直接修改为:JMP 00474ABE ★ 这样就轻易去除了自检验部分
00474A38 F646 42 01 test byte ptr ds:[esi+42],1
00474A3C 74 20 je short lm.00474A5E
00474A3E 57 push edi
00474A3F 68 70494000 push lm.00404970
00474A44 E8 F7D3FFFF call lm.00471E40
00474A49 6A 10 push 10
00474A4B 68 6B494000 push lm.0040496B
00474A50 8BF8 mov edi,eax
00474A52 E8 E9D3FFFF call lm.00471E40
00474A57 50 push eax
00474A58 57 push edi
00474A59 6A 00 push 0
00474A5B FFD3 call ebx
00474A5D 5F pop edi
00474A5E 6A EC push -14
00474A60 FFD5 call ebp
00474A62 F646 2C 40 test byte ptr ds:[esi+2C],40
00474A66 74 56 je short lm.00474ABE
00474A68 E8 2BFEFFFF call lm.00474898
00474A6D 85C0 test eax,eax
00474A6F 75 4D jnz short lm.00474ABE
00474A71 8A46 42 mov al,byte ptr ds:[esi+42]
00474A74 A8 01 test al,1
00474A76 74 3E je short lm.00474AB6
00474A78 68 88494000 push lm.00404988
00474A7D E8 BED3FFFF call lm.00471E40
00474A82 6A 01 push 1
00474A84 68 7B494000 push lm.0040497B
00474A89 8BF0 mov esi,eax
00474A8B E8 B0D3FFFF call lm.00471E40
00474A90 50 push eax
00474A91 56 push esi
00474A92 6A 00 push 0
00474A94 FFD3 call ebx
//检验错误,弹出作者的“忠告”
00474A96 83F8 02 cmp eax,2
00474A99 75 0B jnz short lm.00474AA6
00474A9B 6A 09 push 9
00474A9D FFD5 call ebp
00474A9F 5E pop esi
00474AA0 5D pop ebp
00474AA1 5B pop ebx
00474AA2 83C4 10 add esp,10
00474AA5 C3 retn
00474AA6 6A FF push -1
00474AA8 6A 0C push 0C
00474AAA E8 A8350000 call lm.00478057
00474AAF 5E pop esi
00474AB0 5D pop ebp
00474AB1 5B pop ebx
00474AB2 83C4 10 add esp,10
00474AB5 C3 retn
00474AB6 A8 02 test al,2
00474AB8 74 04 je short lm.00474ABE
00474ABA 6A 03 push 3
00474ABC FFD5 call ebp
00474ABE 5E pop esi
00474ABF 5D pop ebp
00474AC0 5B pop ebx
00474AC1 83C4 10 add esp,10
00474AC4 C3 retn
―――――――――――――――――――――――――――――――――
三、断点检测
这里也就是普通的INT3断点检测,所以我用了硬件断点。
004794A7 E8 00000000 call lm.004794AC
004794AC 58 pop eax
004794AD 05 F4290000 add eax,29F4
004794B2 8B00 mov eax,dword ptr ds:[eax]
004794B4 E8 00000000 call lm.004794B9
004794B9 59 pop ecx
004794BA 81C1 477CFFFF add ecx,FFFF7C47
004794C0 F741 2C 08000000 test dword ptr ds:[ecx+2C],8
004794C7 75 02 jnz short lm.004794CB
004794C9 FFE0 jmp eax
004794CB 8038 CC cmp byte ptr ds:[eax],0CC
004794CE 74 1E je short lm.004794EE
//或者把这里修改为:JMP 004794E8
004794D0 8078 01 CC cmp byte ptr ds:[eax+1],0CC
004794D4 74 18 je short lm.004794EE
004794D6 8078 02 CC cmp byte ptr ds:[eax+2],0CC
004794DA 74 12 je short lm.004794EE
004794DC 8078 03 CC cmp byte ptr ds:[eax+3],0CC
004794E0 74 0C je short lm.004794EE
004794E2 8078 04 CC cmp byte ptr ds:[eax+4],0CC
004794E6 74 06 je short lm.004794EE
//检测前5个字节是否被设置INT3断点
004794E8 50 push eax
004794E9 C3 retn
使用硬件断点或者修改004794CE处,都可以搞定这个简单的CC断点检测。
―――――――――――――――――――――――――――――――――
四、OEP+修复输入表:完成脱壳
修改完Magic Jump和自校验后,直接F4到00475449处。
下断:HE GetModuleHandleA F9运行,中断后取消断点。Alt+F9返回
00471C95 E8 00000000 call lm.00471C9A
00471C9A 59 pop ecx
00471C9B 81C1 72F4FFFF add ecx,-0B8E
00471CA1 0301 add eax,dword ptr ds:[ecx]
//EAX=00400000+00043B6E=00443B6E 这就是OEP值 ★
00471CA3 8BF8 mov edi,eax ; lm.00443B6E
00471CA5 50 push eax
00471CA6 E8 00000000 call lm.00471CAB
下面经过几个ret后就可以返回OEP了
当然,可以使用第2区段内存断点大法直接暂停在OEP处。
我们下命令:G 00443B6E 回车之后就直达OEP啦
00443B6E 55 push ebp
//在这儿用LordPE完全Dump此进程
00443B6F 8BEC mov ebp,esp
00443B71 6A FF push -1
00443B73 68 90E74400 push lm.0044E790
00443B78 68 D83C4400 push lm.00443CD8 ; jmp to msvcrt._except_handler3
00443B7D 64:A1 00000000 mov eax,dword ptr fs:[0]
00443B83 50 push eax
00443B84 64:8925 00000000 mov dword ptr fs:[0],esp
00443B8B 83EC 68 sub esp,68
00443B8E 53 push ebx
00443B8F 56 push esi
00443B90 57 push edi
00443B91 8965 E8 mov dword ptr ss:[ebp-18],esp
00443B94 33DB xor ebx,ebx
00443B96 895D FC mov dword ptr ss:[ebp-4],ebx
00443B99 6A 02 push 2
00443B9B FF15 9C9E4400 call dword ptr ds:[449E9C]; msvcrt.__set_app_type
运行ImportREC,选择这个进程。把OEP改为00043B6E,点IT AutoSearch,很明显ImportREC自动得到的数据不正确。
可以手动定位IAT RVA和大小,但是这个壳有更简单的方法。
用LordPE打开原来的lm.exe,看到IAT RVA=00049000、Size=000010F8,呵呵,壳没有加密IAT信息。直接在ImportREC里填入这个数据,点“Get Import”。我们已经避开输入表加密了,所以直接CUT掉填充在DLL名之间的垃圾数据,就可以得到完整的输入表了。
可以“新增区段”来修复,不过我选择放在原来的输入表处。New Import Infors填入RVA=000547D0,把ImportREC新建输入表的3个选项清空,FixDump!
简单优化一下。用LordPE删除最后的.Shield区段,重建PE即可。
希望作者能够继续完善这个壳,成长为新的猛壳。
―――――――――――――――――――――――――――――――――
, _/
/| _.-~/ \_ , 青春都一晌
( /~ / \~-._ |\
`\\ _/ \ ~\ ) 忍把浮名
_-~~~-.) )__/;;,. \_ //'
/'_,\ --~ \ ~~~- ,;;\___( (.-~~~-. 换了破解轻狂
`~ _( ,_..--\ ( ,;'' / ~-- /._`\
/~~//' /' `~\ ) /--.._, )_ `~
" `~" " `" /~'`\ `\\~~\
" " "~' ""
UnPacked By : fly
2005-01-18 零点
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)