对幻影1.5b3加壳的程序中各种注册相关代码的一点分析 ---这是一篇写了很旧的东东了,一直没发,这次充数吧 (10千字)
对幻影1.5b3加壳的程序中各种注册相关代码的一点分析【声明】
我写文章以交流为主,希望大家在转载时能保持文章的完整性。
【前言】
跟踪分析幻影加密的程序实在很痛苦,在我的爱机被他超度了N次之后,终于让我下定决心去详细分析一下他的加密方法。
经过数天艰苦卓绝的战斗,终于让我有了一点收获,现在我可以很快获取Serial No和脱壳。这可能是我最下功夫去了解的一个加壳程序了。
写作
这里说一说幻影中各种注册相关代码的内容。首先我们来看看幻影加密中的用到的几种方法:
1、Start Message 你可以由此加入一些程序启动时的欢迎之类的信息
2、Restrictive Date 你可以由此设置程序的过期日期
3、Restrictive Time 你可以由此设置程序的未注册限制使用次数
4、Pass Word 你可以由此设置程序启动时的口令
5、Register Key 你可以由此设置程序加密用的 Key (此 Key 用于代码还原,所以这里就不分析他了)
6、Register Cue 你可以由此设置程序
以上有五类注册相关的设置(第 5 项除外),实际上还有一处,就是如果你用未注册版的幻影去加密程序,那么程序在使用时会随机显示该程序是被未注册版幻影加密的信息。所以共有六类,现在我们来看一下相关的代码。
第一段:判断程序是否被注册版幻影加密
00412574: 53 push ebx
00412575: 6A64 push 00000064
00412577: 6A63 push 00000063
00412579: 6A00 push 00000000
0041257B: FF9508BC4000 call dword ptr [ebp+0040BC08] <--SetTimer()
00412581: 61 popad
00412582: 6A00 push 00000000
00412584: FF95C3BB4000 call dword ptr [ebp+0040BBC3] <--GetModuleHandle()
0041258A: 89855FBD4000 mov dword ptr [ebp+0040BD5F],eax
00412590: 80BDC8B2400001 cmp byte ptr [ebp+0040B2C8],01 <--标志,可能是用来标识是否被注册版幻影加密的
00412597: 7435 jz 004125CE <--注册版加密的,就会跳转。否则将随机显示信息
00412599: BEE1B94000 mov esi,0040B9E1
0041259E: 03F5 add esi,ebp
004125A0: 56 push esi
004125A1: FF959FBB4000 call dword ptr [ebp+0040BB9F] <--GetSystemTime()
004125A7: 668B85EFB94000 mov ax,word ptr [ebp+0040B9EF] <--取其中的毫秒时间
004125AE: 240F and al,0F
004125B0: 3C02 cmp al,02
004125B2: 731A jnb 004125CE <--判断结果随机,用来随机显示未注册版加密。
004125B4: B8BEB94000 mov eax,0040B9BE <--如果没有跳走,将会显示该程序被未注册版的幻影加密
EAX指向的其缺省显示内容如下:
****************************************************************
本软件由 幻影v1.5 未注册版本加密
This program protected by DBPE v1.5 Unregistered version
Homepage: http://fsdb.yeah.net E-mail: D.Boy@126.com
*****************************************************************
004125B9: 03C5 add eax,ebp
004125BB: BB11B24000 mov ebx,0040B211
004125C0: 03DD add ebx,ebp
004125C2: 6A30 push 00000030
004125C4: 50 push eax
004125C5: 53 push ebx
004125C6: 6A00 push 00000000
004125C8: FF9500BC4000 call dword ptr [ebp+0040BC00] <--MessageBoxA
第二段:判断程序是否被注册。
.......(前面的省略)
004125EF: E87C030000 call 00412970 <--获取硬件信息并计算比较注册表信息来检测软件是否已经注册
004125F4: 6689857DB44000 mov word ptr [ebp+0040B47D],ax <--保存软件是否已经注册的信息。将来程序还会以此来作点脱壳的小障碍。
004125FB: 663D0100 cmp ax,0001
004125FF: 0F84BF000000 jz 004126C4 <--已注册,就跳转到代码还原的地方,否则进入下一段
第三段:判断是否显示 StartMessage 信息
00412605: 83BD5DB7400000 cmp dword ptr [ebp+0040B75D],00000000 <--标志
0041260C: 7426 jz 00412634 <--为0,则跳走。去显示 StartMessage 信息。
0041260E: 83BD61B7400001 cmp dword ptr [ebp+0040B761],00000001 <--标志
00412615: 751D jnz 00412634 <--不等于1,则跳走,去显示 StartMessage 信息。
00412617: E80A060000 call 00412C26 <--显示 Try 对话框,其中有 Try 和 Register 按钮选择。
0041261C: 6689857FB44000 mov word ptr [ebp+0040B47F],ax
00412623: BBC9B24000 mov ebx,0040B2C9
00412628: 03DD add ebx,ebp <--EBX指向要显示的内容,如果为"||"则表示不显示。
0041262A: 663D0200 cmp ax,0002 <--2,表示选择了Register按钮
0041262E: 0F8444010000 jz 00412778 <--相等,则跳转到注册输入处。
00412634: 6681BDF1B440007C7C cmp word ptr [ebp+0040B4F1],7C7C <--判断是否为"||"
0041263D: 741A jz 00412659 <--相等则表示不显示任何信息,跳走到口令输入处
0041263F: B8BEB94000 mov eax,0040B9BE
00412644: 03C5 add eax,ebp
00412646: BBF1B44000 mov ebx,0040B4F1
0041264B: 03DD add ebx,ebp
0041264D: 6A30 push 00000030
0041264F: 50 push eax
00412650: 53 push ebx
00412651: 6A00 push 00000000
00412653: FF9500BC4000 call dword ptr [ebp+0040BC00] <--MessageBoxA(),此处为显示 StartMessage 信息
第四段:判断口令
00412659: E8A0020000 call 004128FE <--弹出口令输入框接受输入的口令并返回判断结果。
0041265E: BB91B84000 mov ebx,0040B891
00412663: 03DD add ebx,ebp <--EBX指向 Invalid PassWord 信息
00412665: 663D0000 cmp ax,0000 <--判断口令是否输入正确
00412669: 0F8409010000 jz 00412778 <--口令错,跳走到注册输入处。
第五段:判断是否过期
0041266F: E882010000 call 004127F6 <--检查使用是否过期,并返回判断结果
00412674: BB1DB64000 mov ebx,0040B61D
00412679: 03DD add ebx,ebp <--EBX指向"试用期已过"等信息
0041267B: 663D0000 cmp ax,0000 <--判断是否过期
0041267F: 0F84F3000000 jz 00412778 <--过期,则跳走到注册输入处
00412685: E8C3010000 call 0041284D <--没有过期,则在注册表中查找注册信息,第一次使用则在注册表创建相关信息。
0041268A: BB1DB64000 mov ebx,0040B61D
0041268F: 03DD add ebx,ebp <--EBX指向"试用期已过"等信息
00412691: 663D0000 cmp ax,0000
00412695: 0F84DD000000 jz 00412778 <--过期,则跳转去显示信息,否则继续下面的判断
0041269B: 6683BD7DB4400000 cmp word ptr [ebp+0040B47D],0000 <--此标志前面已有说明,判断是否已经成为正版用户
004126A3: 751F jnz 004126C4 <--已注册,则跳转到代码还原处
004126A5: 83BD5DB7400000 cmp dword ptr [ebp+0040B75D],00000000 <--此标志前面已有说明
004126AC: 7416 jz 004126C4 <--为0,则跳走到代码还原处
004126AE: 6683BD7FB4400001 cmp word ptr [ebp+0040B47F],0001 <--此标志前面已有说明,表示你在 Try 框中按下的按钮
004126B6: 740C jz 004126C4 <--按的是Try按钮而不是Register按钮,则跳到代码还原处
004126B8: BBC9B24000 mov ebx,0040B2C9
004126BD: 03DD add ebx,ebp <--EBX指向要显示的信息,如果为"||"则不显示
004126BF: E9B4000000 jmp 00412778 <--跳到显示信息处
004126C4: ................... (此处开始是代码还原部分。省略此段代码)
................... (同上,省略)
00412773: E90F120000 jmp 00413987 <--跳转到最后的一段Anti-Debug代码处,那里将不久就到了程序真正的入口了。不过那里还有最后一关要过。这里就不多说了。
00412778: 66813B7C7C cmp word ptr [ebx],7C7C <--判断是否为""||"
0041277D: 7413 jz 00412792 <--是,则不显示信息,跳走
0041277F: B8C0B94000 mov eax,0040B9C0
00412784: 03C5 add eax,ebp
00412786: 6A30 push 00000030
00412788: 50 push eax
00412789: 53 push ebx
0041278A: 6A00 push 00000000
0041278C: FF9500BC4000 call dword ptr [ebp+0040BC00] <--MessageBoxA(),显示信息
第六段:弹出注册输入框,并判断注册是否成功
00412792: 83BD5DB7400000 cmp dword ptr [ebp+0040B75D],00000000 <--此标志前面已有说明
00412799: 7446 jz 004127E1 <--为0,则跳走
0041279B: E810010000 call 004128B0 <--这里将弹出注册输入框(要求你输入正确的Serial No)并返回判断结果
004127A0: 6689857DB44000 mov word ptr [ebp+0040B47D],ax <--保存判断结果,标志
004127A7: 50 push eax
004127A8: 663D0100 cmp ax,0001 <--判断是否注册成功
004127AC: 7507 jnz 004127B5 <--不等于1,注册失败,跳转到显示信息处
004127AE: BBF5B84000 mov ebx,0040B8F5 <--注册成功了,EBX指向"Register Successfully"信息处
004127B3: EB05 jmp 004127BA <--去显示信息
004127B5: BB59B94000 mov ebx,0040B959
004127BA: 03DD add ebx,ebp <--EBX指向"Invalid Serial NO"信息处
004127BC: 66813B7C7C cmp word ptr [ebx],7C7C <--判断是否为"||"
004127C1: 7413 jz 004127D6 <--是,则表示不显示信息,跳转
004127C3: B8C0B94000 mov eax,0040B9C0
004127C8: 03C5 add eax,ebp
004127CA: 6A30 push 00000030
004127CC: 50 push eax
004127CD: 53 push ebx
004127CE: 6A00 push 00000000
004127D0: FF9500BC4000 call dword ptr [ebp+0040BC00] <--MessageBoxA,显示注册成功或者注册失败
004127D6: 58 pop eax
004127D7: 663D0100 cmp ax,0001 <--判断是否注册成功
004127DB: 0F84E3FEFFFF jz 004126C4 <--注册成功,则重新回到代码还原处继续正常工作
004127E1: C6855DBD400000 mov byte ptr [ebp+0040BD5D],00
004127E8: 8BC5 mov eax,ebp
004127EA: 5B pop ebx
004127EB: 59 pop ecx
004127EC: 5A pop edx
004127ED: 5E pop esi
004127EE: 5F pop edi
004127EF: 5D pop ebp
004127F0: 9D popfd
004127F1: E991110000 jmp 00413987 <--从这里跳走到最后的Anti-Debug处,怕是凶多吉少,因为代码没有还原,而最后的那段代码中还有一段Anti-Debug代码,虽然那里就快到了程序真正的入口处,老天!死在那里,可真悲哀。西天取经的最后一关,死在如来佛祖面前..........$#%^#。
【后记】
幻影在动态反跟踪上设计得十分优秀,不过由于其没有对动态反跟踪代码进行更多的保护,以及在静态反跟踪上有些不足,才让我能够有此收获。不过这些我已经给D.Boy提些建议,所以在新版幻影中我相信他的表现一定更加优秀。到那时不知道我的爱机还要被 k 多少次.....555555.......我的爱机啊..。------------- 怎么我现在就想着被 k ,难道幻影中加了玛啡?
