从狂风汉化百宝箱XP的破解看VB注册(二)(算法分析及注册机)
——手把手系列之五
一些诸如“简介”的废话就不重申了,上次我们做了这个程序的内存注册机,也简单地看了一下爆破地址,有的坛友说这有点简单,况且这也决不应是我们的目的。解决OverNimble LocPlus这个难题后(该分析见系列之四),就回头又把狂风汉化百宝箱看了一遍,追出了其注册算法,现分享给各位。
【破解作者】jackily
【作者主页】http://estudy.ys168.com
【破解声明】 本破解纯属以学习为目的,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
通过上次的分析,我们知道本程序是典型的常用串(string) 明码比较,用到的函数是_vbastrcomp,内存地址是00462C3D。下断后,发现在mov eax,dword ptr ds:[esi+54]中,[esi+54]是真码的地址,我们只要追出其从何而来即可找到算法。但经研究,发现一个很有意思的现象,即此程序在启动时就算出了真码,然后放到[esi+54]。因此想追算法过程得在启动时下断。该程序的注册方式也是个重启验证型,和OverNimble LocPlus 1.04以前版本有些相像,这也难怪,因为两个程序的开发者都来自同一工作室。废话少说,于是有人问了,“你怎知该程序是重启验证型?”我想这是大多数人所关心的。还记得上次我们是如何下断的吗?对了,当时断在函数_vbastrcomp上,而且当时提到了程序有四处调用了该函数,我们全部下断,而上次只是在其中之一的地方停了下来。这次重启程序后,并没有新增断点,却在00464472处停了下来。于是沿着代码向上分析,发现00464419中push eax里的eax值是486cca,也就是"4746442"的HEX值。那么“4746442”又是什么呢?忘了吧,它不是我的机器码吗?该语句下一行0046441b这个call有问题,跟进后是jmp 00467120,再跟发现正是算法调用。
代码分析如下:
00464220 > \55 push ebp
00464221 . 8BEC mov ebp,esp
00464223 . 83EC 0C sub esp,0C
00464226 . 68 F613400>push <jmp.&MSVBVM60.__vbaExceptHandler>; SE handler installation
0046422B . 64:A1 0000>mov eax,dword ptr fs:[0]
00464231 . 50 push eax
00464232 . 64:8925 00>mov dword ptr fs:[0],esp
00464239 . 81EC B0000>sub esp,0B0
...........此处代码省略
00464405 . 53 push ebx
00464406 . 50 push eax
00464407 . FF15 64104>call dword ptr ds:[<&MSVBVM60.__vbaHre>; MSVBVM60.__vbaHresultCheckObj
0046440D > 8B55 D8 mov edx,dword ptr ss:[ebp-28]
00464410 . 8B1E mov ebx,dword ptr ds:[esi]
00464412 . 52 push edx
00464413 . FF15 8C114>call dword ptr ds:[<&MSVBVM60.__vbaI4S>; MSVBVM60.__vbaI4Str
00464419 . 50 push eax ;eax=486cca,“4746442”的HEX值
0046441A . 56 push esi
0046441B . FF93 00070>call dword ptr ds:[ebx+700] ;[ebx+700]=00458c30,跟进,算法调用
00464421 . 85C0 test eax,eax
00464423 . 7D 12 jge short _狂风汉?00464437
00464425 . 68 0007000>push 700
0046442A . 68 9457450>push _狂风汉?00455794
0046442F . 56 push esi
00464430 . 50 push eax
00464431 . FF15 64104>call dword ptr ds:[<&MSVBVM60.__vbaHre>; MSVBVM60.__vbaHresultCheckObj
00464437 > 8D4D D8 lea ecx,dword ptr ss:[ebp-28]
0046443A . FF15 14124>call dword ptr ds:[<&MSVBVM60.__vbaFre>; MSVBVM60.__vbaFreeStr
00464440 . 8D4D C8 lea ecx,dword ptr ss:[ebp-38]
00464443 . FF15 10124>call dword ptr ds:[<&MSVBVM60.__vbaFre>; MSVBVM60.__vbaFreeObj
00464449 . 8B06 mov eax,dword ptr ds:[esi]
0046444B . 56 push esi
0046444C . FF90 08070>call dword ptr ds:[eax+708]
00464452 . 85C0 test eax,eax
00464454 . 7D 12 jge short _狂风汉?00464468
00464456 . 68 0807000>push 708
0046445B . 68 9457450>push _狂风汉?00455794
00464460 . 56 push esi
00464461 . 50 push eax
00464462 . FF15 64104>call dword ptr ds:[<&MSVBVM60.__vbaHre>; MSVBVM60.__vbaHresultCheckObj
00464468 > 8B4E 60 mov ecx,dword ptr ds:[esi+60] 假码地址
0046446B . 8B56 54 mov edx,dword ptr ds:[esi+54] 真码地址
0046446E . 51 push ecx ;unicode"123456" 我输入的假码
0046446F . 52 push edx ;unicode"MNMNKMI" 真码
00464470 . 6A 01 push 1
[color]00464472 . FF15 CC114>call dword ptr ds:[<&MSVBVM60.__vbaStrcomp>;关键比较 [/color]
00464478 . 66:85C0 test ax,ax
0046447B . 0F85 36010>jnz _狂风汉?004645B7 ;跳走就失败,此处才是爆破点,
------------------------------------------------------------------------------
由0046441B跟进,此处是关键,注册算法在此。
00467120 > \55 push ebp
00467121 . 8BEC mov ebp,esp
00467123 . 83EC 0C sub esp,0C
00467126 . 68 F613400>push <jmp.&MSVBVM60.__vbaExceptHandler> ; SE handler installation
0046712B . 64:A1 0000>mov eax,dword ptr fs:[0]
00467131 . 50 push eax
00467132 . 64:8925 00>mov dword ptr fs:[0],esp
00467139 . 81EC F4000>sub esp,0F4
0046713F . 53 push ebx
00467140 . 56 push esi
00467141 . 57 push edi
00467142 . 8965 F4 mov dword ptr ss:[ebp-C],esp
00467145 . C745 F8 B0>mov dword ptr ss:[ebp-8],_狂风汉?004013B0
0046714C . 33F6 xor esi,esi
0046714E . 8975 FC mov dword ptr ss:[ebp-4],esi
00467151 . 8B45 08 mov eax,dword ptr ss:[ebp+8]
00467154 . 50 push eax
00467155 . 8B08 mov ecx,dword ptr ds:[eax]
00467157 . FF51 04 call dword ptr ds:[ecx+4] ;call zombie_addref
0046715A . B8 0200000>mov eax,2
0046715F . 89B5 64FFF>mov dword ptr ss:[ebp-9C],esi
00467165 . 89B5 54FFF>mov dword ptr ss:[ebp-AC],esi
0046716B . 89B5 44FFF>mov dword ptr ss:[ebp-BC],esi
00467171 . 8985 64FFF>mov dword ptr ss:[ebp-9C],eax
00467177 . 8985 54FFF>mov dword ptr ss:[ebp-AC],eax
0046717D . 8985 44FFF>mov dword ptr ss:[ebp-BC],eax
00467183 . 8D95 64FFF>lea edx,dword ptr ss:[ebp-9C]
00467189 . 8D85 54FFF>lea eax,dword ptr ss:[ebp-AC]
0046718F . 52 push edx
00467190 . 8D8D 44FFF>lea ecx,dword ptr ss:[ebp-BC]
00467196 . 50 push eax
00467197 . 8D95 04FFF>lea edx,dword ptr ss:[ebp-FC]
0046719D . 51 push ecx
0046719E . 8D85 14FFF>lea eax,dword ptr ss:[ebp-EC]
004671A4 . 52 push edx
004671A5 . 8D4D DC lea ecx,dword ptr ss:[ebp-24]
004671A8 . 50 push eax
004671A9 . 51 push ecx
004671AA . 8975 DC mov dword ptr ss:[ebp-24],esi
004671AD . 8975 D8 mov dword ptr ss:[ebp-28],esi
004671B0 . 8975 D4 mov dword ptr ss:[ebp-2C],esi
004671B3 . 8975 C4 mov dword ptr ss:[ebp-3C],esi
004671B6 . 8975 B4 mov dword ptr ss:[ebp-4C],esi
004671B9 . 8975 A4 mov dword ptr ss:[ebp-5C],esi
004671BC . 8975 94 mov dword ptr ss:[ebp-6C],esi
004671BF . 8975 84 mov dword ptr ss:[ebp-7C],esi
004671C2 . 89B5 74FFF>mov dword ptr ss:[ebp-8C],esi
004671C8 . 89B5 34FFF>mov dword ptr ss:[ebp-CC],esi
004671CE . 89B5 24FFF>mov dword ptr ss:[ebp-DC],esi
004671D4 . 89B5 14FFF>mov dword ptr ss:[ebp-EC],esi
004671DA . 89B5 04FFF>mov dword ptr ss:[ebp-FC],esi
004671E0 . C785 6CFFF>mov dword ptr ss:[ebp-94],-1
004671EA . C785 5CFFF>mov dword ptr ss:[ebp-A4],1 ;步长为1
004671F4 . C785 4CFFF>mov dword ptr ss:[ebp-B4],7 ;循环7次
004671FE . FF15 78104>call dword ptr ds:[<&MSVBVM60.__vbaVarForInit>;和_vbaVarForNext联合使用,相当于for的循环语句
00467204 . 8B3D B8114>mov edi,dword ptr ds:[<&MSVBVM60.__vbaI4V>; MSVBVM60.__vbaI4Var
0046720A . 8B1D C0114>mov ebx,dword ptr ds:[<&MSVBVM60.__vbaVar>; MSVBVM60.__vbaVarAdd
00467210 > 3BC6 cmp eax,esi
00467212 . 0F84 43010>je _狂风汉?0046735B
00467218 . 8B55 08 mov edx,dword ptr ss:[ebp+8]
0046721B . 8D4D 0C lea ecx,dword ptr ss:[ebp+C] ;“4746442”的地址
0046721E . C785 24FFF>mov dword ptr ss:[ebp-DC],8
00467228 . C745 CC 01>mov dword ptr ss:[ebp-34],1
0046722F . 8B42 54 mov eax,dword ptr ds:[edx+54]
00467232 . 8D72 54 lea esi,dword ptr ds:[edx+54]
00467235 . 8985 2CFFF>mov dword ptr ss:[ebp-D4],eax
0046723B . 8D55 C4 lea edx,dword ptr ss:[ebp-3C]
0046723E . 8D45 DC lea eax,dword ptr ss:[ebp-24]
00467241 . 52 push edx
00467242 . 50 push eax
00467243 . C745 C4 02>mov dword ptr ss:[ebp-3C],2
0046724A . 898D 6CFFF>mov dword ptr ss:[ebp-94],ecx
00467250 . C785 64FFF>mov dword ptr ss:[ebp-9C],4003
0046725A . FFD7 call edi ;为MSVBVM60.__vbaI4Var
0046725C . 8D8D 64FFF>lea ecx,dword ptr ss:[ebp-9C] ;call之后,eax依次为0x7,0x6,...,0x1
00467262 . 50 push eax
00467263 . 8D55 B4 lea edx,dword ptr ss:[ebp-4C]
00467266 . 51 push ecx
00467267 . 52 push edx
00467268 . FF15 B0104>call dword ptr ds:[<&MSVBVM60.#632>] ; MSVBVM60.rtcMidCharVar,取第eax值的字符
0046726E . 8D45 B4 lea eax,dword ptr ss:[ebp-4C]
00467271 . 8D4D D8 lea ecx,dword ptr ss:[ebp-28]
00467274 . 50 push eax
00467275 . 51 push ecx
00467276 . FF15 4C114>call dword ptr ds:[<&MSVBVM60.__vbaStrVar>; MSVBVM60.__vbaStrVarVal
0046727C . 50 push eax
0046727D . FF15 4C104>call dword ptr ds:[<&MSVBVM60.#516>] ; MSVBVM60.rtcAnsiValueBstr,变ASCII值,放ax里
00467283 . 66:8985 4C>mov word ptr ss:[ebp-B4],ax ;依次是32,34,34,...,37,34
0046728A . B8 0200000>mov eax,2
0046728F . 8985 44FFF>mov dword ptr ss:[ebp-BC],eax
00467295 . 8985 34FFF>mov dword ptr ss:[ebp-CC],eax
0046729B . 8D95 44FFF>lea edx,dword ptr ss:[ebp-BC]
004672A1 . 8D45 DC lea eax,dword ptr ss:[ebp-24]
004672A4 . 52 push edx
004672A5 . 8D4D A4 lea ecx,dword ptr ss:[ebp-5C]
004672A8 . 50 push eax
004672A9 . 51 push ecx ;ecx为0046725c语句里的ecx值
004672AA . C785 3CFFF>mov dword ptr ss:[ebp-C4],14 ;一个常量,0x14
004672B4 . FFD3 call ebx ;_vbaVaradd,ax+ecx
004672B6 . 50 push eax ;
004672B7 . 8D95 34FFF>lea edx,dword ptr ss:[ebp-CC]
004672BD . 8D45 94 lea eax,dword ptr ss:[ebp-6C]
004672C0 . 52 push edx
004672C1 . 50 push eax
004672C2 . FFD3 call ebx ;_vbaVaradd,ax+ecx的值再加0x14
004672C4 . 50 push eax
004672C5 . FFD7 call edi
004672C7 . 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
004672CA . 50 push eax
004672CB . 51 push ecx
004672CC . FF15 34114>call dword ptr ds:[<&MSVBVM60.#608>] ; rtcVarBstrFromAnsi,转整形数值,eax为存放地址
004672D2 . 8D95 24FFF>lea edx,dword ptr ss:[ebp-DC]
004672D8 . 8D45 84 lea eax,dword ptr ss:[ebp-7C]
004672DB . 52 push edx
004672DC . 8D8D 74FFF>lea ecx,dword ptr ss:[ebp-8C]
004672E2 . 50 push eax
004672E3 . 51 push ecx
004672E4 . FF15 50114>call dword ptr ds:[<&MSVBVM60.__vbaVarCat>; 结果连接在一起
004672EA . 50 push eax
004672EB . FF15 20104>call dword ptr ds:[<&MSVBVM60.__vbaStrVar>; MSVBVM60.__vbaStrVarMove
004672F1 . 8BD0 mov edx,eax
004672F3 . 8D4D D4 lea ecx,dword ptr ss:[ebp-2C]
004672F6 . FF15 E0114>call dword ptr ds:[<&MSVBVM60.__vbaStrMov>; MSVBVM60.__vbaStrMove
004672FC . 8BD0 mov edx,eax
004672FE . 8BCE mov ecx,esi
00467300 . FF15 88114>call dword ptr ds:[<&MSVBVM60.__vbaStrCop>; MSVBVM60.__vbaStrCopy
00467306 . 8D55 D4 lea edx,dword ptr ss:[ebp-2C]
00467309 . 8D45 D8 lea eax,dword ptr ss:[ebp-28]
0046730C . 52 push edx
0046730D . 50 push eax
0046730E . 6A 02 push 2
00467310 . FF15 90114>call dword ptr ds:[<&MSVBVM60.__vbaFreeSt>; MSVBVM60.__vbaFreeStrList
00467316 . 8D8D 74FFF>lea ecx,dword ptr ss:[ebp-8C]
0046731C . 8D55 84 lea edx,dword ptr ss:[ebp-7C]
0046731F . 51 push ecx
00467320 . 8D45 94 lea eax,dword ptr ss:[ebp-6C]
00467323 . 52 push edx
00467324 . 8D4D A4 lea ecx,dword ptr ss:[ebp-5C]
00467327 . 50 push eax
00467328 . 51 push ecx
00467329 . 8D55 B4 lea edx,dword ptr ss:[ebp-4C]
0046732C . 8D45 C4 lea eax,dword ptr ss:[ebp-3C]
0046732F . 52 push edx
00467330 . 50 push eax
00467331 . 6A 06 push 6
00467333 . FF15 30104>call dword ptr ds:[<&MSVBVM60.__vbaFreeVa>; MSVBVM60.__vbaFreeVarList
00467339 . 83C4 28 add esp,28
0046733C . 8D8D 04FFF>lea ecx,dword ptr ss:[ebp-FC]
00467342 . 8D95 14FFF>lea edx,dword ptr ss:[ebp-EC]
00467348 . 8D45 DC lea eax,dword ptr ss:[ebp-24]
0046734B . 51 push ecx
0046734C . 52 push edx
0046734D . 50 push eax
0046734E . FF15 04124>call dword ptr ds:[<&MSVBVM60.__vbaVarForNext>;和_vbaVarForInit一并使用
00467354 . 33F6 xor esi,esi
00467356 .^ E9 B5FEFFF>jmp _狂风汉?00467210
0046735B > 68 BC73460>push _狂风汉?004673BC
00467360 . EB 37 jmp short _狂风汉?00467399
00467362 . 8D4D D4 lea ecx,dword ptr ss:[ebp-2C]
00467365 . 8D55 D8 lea edx,dword ptr ss:[ebp-28]
00467368 . 51 push ecx
00467369 . 52 push edx
0046736A . 6A 02 push 2
0046736C . FF15 90114>call dword ptr ds:[<&MSVBVM60.__vbaFreeSt>; MSVBVM60.__vbaFreeStrList
00467372 . 8D85 74FFF>lea eax,dword ptr ss:[ebp-8C]
00467378 . 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
0046737B . 50 push eax
0046737C . 8D55 94 lea edx,dword ptr ss:[ebp-6C]
0046737F . 51 push ecx
00467380 . 8D45 A4 lea eax,dword ptr ss:[ebp-5C]
00467383 . 52 push edx
00467384 . 8D4D B4 lea ecx,dword ptr ss:[ebp-4C]
00467387 . 50 push eax
00467388 . 8D55 C4 lea edx,dword ptr ss:[ebp-3C]
0046738B . 51 push ecx
0046738C . 52 push edx
0046738D . 6A 06 push 6
0046738F . FF15 30104>call dword ptr ds:[<&MSVBVM60.__vbaFreeVa>; MSVBVM60.__vbaFreeVarList
00467395 . 83C4 28 add esp,28
00467398 . C3 retn
00467399 > 8D85 04FFF>lea eax,dword ptr ss:[ebp-FC]
0046739F . 8D8D 14FFF>lea ecx,dword ptr ss:[ebp-EC]
004673A5 . 50 push eax
004673A6 . 51 push ecx
004673A7 . 6A 02 push 2
004673A9 . FF15 30104>call dword ptr ds:[<&MSVBVM60.__vbaFreeVa>; MSVBVM60.__vbaFreeVarList
004673AF . 83C4 0C add esp,0C
004673B2 . 8D4D DC lea ecx,dword ptr ss:[ebp-24]
004673B5 . FF15 18104>call dword ptr ds:[<&MSVBVM60.__vbaFreeVa>; MSVBVM60.__vbaFreeVar
004673BB . C3 retn
--------------------------------------------------------------------------------
【破解总结】
注册码一共七位。从机器码的最后一位开始倒着取ASCII值,结果分别加其位数,再加0x14,最后将所有的数相连即可,输出类型是字符。
--------------------------------------------------------------------------------
【算法注册机】
/* KuangFeng Chinese c语言注册机 */
/* 在Turboc 2.0 下调试通过 */
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
main()
{
char name[100]={0} ,s[10];
int i,j;
long unsigned code;
printf("KuangFeng Chinese KeyGen by jackily 2005-1-18\n");
printf("Email:jackily_zhang@msn.com or jackily_zhang@yahoo.com.cn\n");
printf("please input name:");
scanf("%s",name);
printf("please input computer code:");
scanf("%s",s);
printf("\nYour serial number is:");
for (i=7;i>0;i--)
{ code=s[i-1]+i;code+=0x14;
printf("%c",code);
}
}
--------------------------------------------------------------------------------
最新发现,用户名虽不参与注册的运算,但机器码是由用户名计算出来的。然而机器码已由程序给出,所以用户名不过是个摆设而已。因此结论是:VB的运算很“有趣”的哟!
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
2005-1-26