jackily 发表于 2005-2-15 15:13:43

【原创】OverNimble LocPlus 1.05注册算法全程详解(写给学VB算法者)

————手把手系列之四
我自认为最成功的一个算法分析!
【破解作者】 jackily
【作者主页】 http://estudy.ys168.com
【使用工具】 ollydbg、 untelock和偶的一双手(手动脱壳)
【破解平台】 Win9x/NT/2000/XP
【软件名称】 OverNimble LocPlus 1.05
【软件简介】 OverNimble LocPlus主要用于非资源格式的本地化,支持的种类包括非资源格式的 C 编译的程序中的 ASCII 字符串和 UniCode 字符串、非资源格式的 Delphi(C++ Builder)编译的程序的字符串、VB 编译的程序的字符串、文本格式的字符串等的提取及替换。未注册版本有一些功能(“VA英文和符号”、“VA非控制符”、“VA中文(GBK)”、“VA中文(BIG5)”、“VA完全中文”、“VA非保留区”、“VA非限制查找”方式的 ASCII 及 uniCode 查找)不能使用。
【加壳方式】tElock 0.98b1、PEBundle 2.0b5 - 3.0x 双层壳
【破解声明】 本破解纯以学习和交流为目的,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------

提起OverNimble LocPlus,大家可能很陌生,至少在真正接触它以前,我一直以为它是国外产品,但提到点睛字符串替换器,汉化界的朋友就非常熟悉了。其实二者是一回事。和狂风汉化百宝箱相类似,它最大的长处就是用于非资源格式字符串的本地化,而LocPlus做得更胜一筹,提供了更多的功能。在看雪精华4、5中侦探柯南、八鸟@和leeyam分别对其1.02版和1.04版做了分析,但采取的都是爆破方法,并没有深入到注册算法,而且他们对于关键代码的分析也存在着一些小BUG,因此本文一并指正出来,以免给初学者带来误导。
1.05版不仅增加了新功能,还在验证注册上稍做了改动,具体见分析过程。因此建议,在读本文前,先读一下侦探柯南、八鸟@和leeyam对1.02版和1.04版做的分析(参见看雪五周年收藏版),以便更好地理解本文。
和以往不同,这次倒过来写,先文字详述分析思路、过程和总结,代码分析放到最后的附录中,大家以交流心得为主,谁都不愿意,也没时间一句句地去读汇编代码,而且能读懂的也真不多,有兴趣的自己慢慢读吧。
读懂本文所必备的知识:
   1. 汇编基础知识;
   2. 听说过VB的浮点运算;
   3. 听说过VB的数据在内存中的存放方式;
   4. 了解如下VB内部函数的功能和参数调用(程序中将用到,先自行预习一下,代码分析中有讲解);
   4.1 _vbavaradd
   4.2 _vbavarsub
   4.3 _vbaVarForInit、_vbaVarForNext
   4.4 _vbaLenBstr
   4.5 _vbaVarTstLe
   4.6 rtcR8ValFromBstr
   4.7 rtcVarBstrFromAnsi
   4.8 rtcIsNumeric

这些天伏案成疾,背疼,找了个郎中,也偷学了一些疗法,这回随我出趟诊吧,医不好,不收费的。:)

第一步:出诊(查壳)
首先,当然是用PEID查壳了,发现tElock 0.98b1,用untelock很轻松地去掉第一层外衣。本想再用PEID查一下是什么程序编写的(本人习惯:脱完壳后,再查一次),嗯?!怎么出来个PEBundle 2.0b5 - 3.0x呢?!嘿,我的爆脾气又来了,第一次听说啊?用google一搜索,明白了,与其说PEBundle是一个壳,不如说是EXE压缩器。于是乎找遍了大江南北,楞没找到相应的脱壳机(本人一般很懒,要是有脱壳机,决不自己动手)。这家伙,象大姑娘上花轿似的,扭扭捏捏地,还穿了里三层外三层的?!没办法,用我的手来脱吧。只说一下要点,脱壳部分码见附录一。
这壳特简单。用ollydbg载入,忽略警告,进入后发现入口处的两个命令pushfd(9c)、pushad(60)非常典型,那我们就寻找popad和popfd,连在一起是619d。Ctrl+B搜索619d...,找到后,在紧接着的RETN 处下断。F9运行,被拦,F8单步跟过,又是60(pushad),此时地址是004473D0,顺着代码,一行行地快速下查,在0044753B处找到一个61(popad),紧接着是jmp 004027fc,下断。再来个F8跟过,此时看到了什么?典型的VB程序入口。用插件中的ollydump脱壳,轻松搞掂。

第二步:诊脉(查看注册校验方式)
打开脱壳后的locplus,点注册,弹出对话框,要求输入用户名和注册码?分别输入jackily和123456点确定,要求重启验证。这是1.05与以往版本不同之处。1.04以前版本有出错信息, 在ollydbg中可以查找到其地址,可以下断,因此其在输入注册码时,会直接检验一次,此时会有机会跟踪注册码。当然,每次重启时,它也都会重新校验注册码。而1.05不直接检验注册码,只在重启时检验,这给跟踪增加了一定的难度,是1.05的一大改进。

第三步:B超检查(动态调试)
既然是重启校验的方式,仔细想一下,无碍乎就是读key文件和读注册表。重新载入程序,点右键—“搜索”—“字符参考”。咦,只有稀稀啦啦的几个注册表项目树,并没有发现1.02和1.04版中出现的\Software\OverNimble\LocPlusRegUserName和RegCode项(注:在以前的版本中直接可查到具体的注册个子项),看来作者在反破解上下了点功夫。不过这点已经够了,说明注册码保存在注册表中了。那么如何下断呢?就断在HKEY_CURRENT_USER的地址上。为什么?我试出来的呗!以下过程请对照附录二的代码分析阅读。在00431a43下断,一步一步向下,发现经过计算,\Software\OverNimble\LocPlusRegUserName和RegCode项被解码出来,原来作者对这两个注册表项加密了。再经过N步跟踪,发现了一个重要信息,在00431a43和00431a71处的两个语句mov edx,eax中,eax存放着用户名和注册码的地址(个人认为,长时间的跟踪能力是大部分cracker所欠缺的,这是crack成功与否的关键)。再向下跟,就和1.04版以前的注册验证部分代码相似了。00431a81的call是关键算法,其中对输入的假码同“ONLocPlus"进行了循环计算(注意大小写),并得出新值,子调用中的算法详见附录二,在此不再述赘;00431a91是检验新值的长度,而非侦探柯南和leeyam所说的注册码长度,实际的注册码长度是26位,而这里是0xc,即12位,也就是说,通过重新计算,26位的注册码被转成12位新值;00431aad是检验新值是否为浮点数值,是就通过,否就失败;00431ac8是检验浮点数值的HEX值,也就是要求这个数值是大于0的,也非侦探柯南和leeyam所说的比较注册码;00431ad9是浮点数比较,中是程序既定值“9900000000.00000000”,因此,新算出的浮点值是“99.后接18个0”。这个写注册机时要用到。以上两点更正是需向读者说明的,以免造成学习过程中的误解。

第四步:开药方(编写注册机)
【破解总结】
一、用户名不参加注册计算,校验注册条件有三:
1、注册码运算后为12位数,即0xC;换句话说,注册码应该为26位。
2、注册码运算后应为数字,分析中会指出判断函数。
3、运算后的数字的HEX值应大于1 。
二、算法思路:
算法属于较特殊的变量比较一种,注册码第1、2位需取00,第3位开始,取12轮,每次取两个位(不用转换,已经认为是HEX值),和“ONLocPlus”的第一位开始(循环取值),每次取1个字母,进行异或。异或值是否小于前一对注册码值,如果是,用0xff减去异或值,再加上前一对注册码值,反之,用异或值减去前一对注册码值。如果前10轮结果值都等于0x30,并且11、12轮结果等于0x39,那么12轮结果转十进制并相连便是00000000099,此时注册码成功。(解释的我都有点糊涂了,能看懂吗?)
算法的数学表达式:
设x为注册码,y为符合条件值,a和b为变量,a=f1(x),b=f2(y),如果f3(a)=b,x为正确的。也就是说如果等式f3(f1(x))=f2(y)成立,x合法有效。
【算法注册机】
/* OverNimble LocPlus c语言注册机 */
/* 本注册机对以前版本也适用 */
/* 在Turboc 2.0 下调试通过*/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
main()
{
char name={0} ,s[]="ONLocPlus";
int i,j;
long unsigned c,code,k=0,m,t=0;
printf("OverNimble LocPlusB KeyGen by jackily 2005-1-18\n");
printf("Email:[email protected] or [email protected]\n");
printf("please input name:");
scanf("%s",name);
printf("\nYour serial number is:00");
    for (i=0;i<0xc;i++)
{ j=i;
for (k=0;k<0xff;k++)
{
code=k;
if (j>0x8) j-=0x9;
m=k^s;
if (t<=m) c=m-t;
else {c=0xff-t;c+=m;}
if (i<=0xa&&c==0x30) break;
if (i>0xa&&c==0x39) break;
}
t=code;                        
if (code<=0xf) printf("0%x",code);
else printf("%x",code);
}
}
--------------------------------------------------------------------------------
【内存注册机】
非明码比较,无法实现

【爆破地址】
小孩爬窗户的行为,都有钥匙了,还用吗?

【用户名、密码】
用户名:jackily
SN    :007FE15EE171F14E0B4837292E

jackily 发表于 2005-2-15 15:14:31

--------------------------------------------------------------------------------

附录一:脱壳分析(结合第一步阅读)

步骤一:
0044E000 L>9C         pushfd               ; 程序进入点
0044E001   60         pushad
0044E002   E8 02000000call LocPlus-.0044E009
0044E007   33C0         xor eax,eax
0044E009   8BC4         mov eax,esp
0044E00B   83C0 04      add eax,4
0044E00E   93         xchg eax,ebx

.........中间省略

0044E195   8D9D 0923400>lea ebx,dword ptr ss:
0044E19B   53         push ebx
0044E19C   6A 00      push 0
0044E19E   FFD0         call eax
0044E1A0   FFA5 D628400>jmp dword ptr ss:
0044E1A6   61         popad                     ; 搜索到这里
0044E1A7   9D         popfd
0044E1A8   68 D0734400push LocPlus-.004473D0
0044E1AD   C3         retn                      ; 下断

步骤二:
004473D0   60         pushad                     ;由44E1AD的retn而来
004473D1   BE 15604300mov esi,LocPlus-.00436015
004473D6   8DBE EBAFFCF>lea edi,dword ptr ds:
004473DC   57         push edi
004473DD   83CD FF      or ebp,FFFFFFFF
004473E0   EB 10      jmp short LocPlus-.004473F2
004473E2   90         nop

...........中间省略

0044752E   8903         mov dword ptr ds:,eax
00447530   83C3 04      add ebx,4
00447533   ^ EB D8      jmp short LocPlus-.0044750D
00447535   FF96 447D040>call dword ptr ds:
0044753B   61         popad
0044753C   - E9 BBB2FBFFjmp LocPlus-.004027FC   ;下第二个断点

真正的程序入口:

004027FC   68 FC594000push LocPlus-.004059FC      ;oep,在此dump...
00402801   E8 EEFFFFFFcall LocPlus-.004027F4      ;jmp to MSVBVM50.ThunRTMain
00402806   0000         add byte ptr ds:,al
00402808   0000         add byte ptr ds:,al
0040280A   0000         add byte ptr ds:,al
0040280C   3000         xor byte ptr ds:,al
0040280E   0000         add byte ptr ds:,al
00402810   48         dec eax
00402811   0000         add byte ptr ds:,al
00402813   0000         add byte ptr ds:,al
00402815   0000         add byte ptr ds:,al
00402817   0053 4A      add byte ptr ds:,dl
0040281A   - E9 0B725CCEjmp CE9C9A2A
........以下代码省略
-------------------------------------------------------------------------------
附录二:代码分析(结合第三步阅读)
004319E0   55         push ebp
004319E1   8BEC         mov ebp,esp
004319E3   83EC 14      sub esp,14
004319E6   68 C6224000push <jmp.&MSVBVM50.__vbaExceptHandler>
004319EB   64:A1 000000>mov eax,dword ptr fs:
004319F1   50         push eax
004319F2   64:8925 0000>mov dword ptr fs:,esp
004319F9   83EC 40      sub esp,40
004319FC   53         push ebx
004319FD   56         push esi
004319FE   57         push edi
004319FF   8965 EC      mov dword ptr ss:,esp
00431A02   C745 F0 7820>mov dword ptr ss:,locplus-.004020>
00431A09   33F6         xor esi,esi
00431A0B   8975 F4      mov dword ptr ss:,esi
00431A0E   8975 F8      mov dword ptr ss:,esi
00431A11   8975 DC      mov dword ptr ss:,esi
00431A14   8975 CC      mov dword ptr ss:,esi
00431A17   8975 BC      mov dword ptr ss:,esi
00431A1A   6A 01      push 1
00431A1C   FF15 F8C4430>call dword ptr ds:[<&MSVBVM50.__vbaOnErro>; MSVBVM50.__vbaOnError
00431A22   66:8935 2C91>mov word ptr ds:,si
00431A29   68 38914300push locplus-.00439138
00431A2E   8D45 CC      lea eax,dword ptr ss:
00431A31   50         push eax
00431A32   E8 F90E0000call locplus-.00432930
00431A37   8D4D CC      lea ecx,dword ptr ss:
00431A3A   51         push ecx
00431A3B   8B3D 38C4430>mov edi,dword ptr ds:[<&MSVBVM50.__vbaStr>; MSVBVM50.__vbaStrVarMove
00431A41   FFD7         call edi
00431A43   8BD0         mov edx,eax                     ;eax存放着用户名地址
00431A45   B9 28914300mov ecx,locplus-.00439128
00431A4A   8B35 18C7430>mov esi,dword ptr ds:[<&MSVBVM50.__vbaStr>; MSVBVM50.__vbaStrMove
00431A50   FFD6         call esi
00431A52   8D4D CC      lea ecx,dword ptr ss:
00431A55   8B1D 2CC4430>mov ebx,dword ptr ds:[<&MSVBVM50.__vbaFre>; MSVBVM50.__vbaFreeVar
00431A5B   FFD3         call ebx
00431A5D   68 3C914300push locplus-.0043913C
00431A62   8D55 CC      lea edx,dword ptr ss:
00431A65   52         push edx
00431A66   E8 C50E0000call locplus-.00432930
00431A6B   8D45 CC      lea eax,dword ptr ss:
00431A6E   50         push eax
00431A6F   FFD7         call edi
00431A71   8BD0         mov edx,eax                      ;eax存放着注册码地址
00431A73   8D4D DC      lea ecx,dword ptr ss:
00431A76   FFD6         call esi
00431A78   8D4D CC      lea ecx,dword ptr ss:
00431A7B   FFD3         call ebx
00431A7D   8D4D DC      lea ecx,dword ptr ss:
00431A80   51         push ecx
00431A81   E8 0AFBFFFFcall locplus-.00431590         ;关键算法call,必须跟进
00431A86   8BD0         mov edx,eax                      ;eax为新数值的地址
00431A88   8D4D DC      lea ecx,dword ptr ss:
00431A8B   FFD6         call esi
00431A8D   8B55 DC      mov edx,dword ptr ss:
00431A90   52         push edx
00431A91   FF15 30C4430>call dword ptr ds:[<&MSVBVM50.__vbaLenBstr> ; 取新值的长度
00431A97   83F8 0C      cmp eax,0C                           ;检验新值的长度是否为12位
00431A9A   75 6A      jnz short locplus-.00431B06            ;跳走即失败
00431A9C   8D45 DC      lea eax,dword ptr ss:
00431A9F   8945 C4      mov dword ptr ss:,eax
00431AA2   C745 BC 0840>mov dword ptr ss:,4008
00431AA9   8D4D BC      lea ecx,dword ptr ss:
00431AAC   51         push ecx
00431AAD   FF15 8CC5430>call dword ptr ds:[<&MSVBVM50.rtcIsNumeric> ; 检验新值是否为浮点数值
00431AB3   66:85C0      test ax,ax                                  ;是就通过
00431AB6   74 4E      je short locplus-.00431B06                  ;跳走即失败
00431AB8   8B55 DC      mov edx,dword ptr ss:
00431ABB   52         push edx
00431ABC   FF15 58C7430>call dword ptr ds:[<&MSVBVM50.rtcR8ValFromBstr>];
00431AC2   FF15 00C7430>call dword ptr ds:[<&MSVBVM50.__vbaFpI4>] ; MSVBVM50.__vbaFpI4
00431AC8   8945 E0      mov dword ptr ss:,eax
00431ACB   83F8 01      cmp eax,1                              ; 检验浮点数值的HEX值
00431ACE   7C 36      jl short locplus-.00431B06               ;跳走即失败
00431AD0   DB45 E0      fild dword ptr ss:
00431AD3   DD5D A4      fstp qword ptr ss:
00431AD6   DD45 A4      fld qword ptr ss:
00431AD9   DC1D 5020400>fcomp qword ptr ds:   ; 浮点数比较
00431ADF   DFE0         fstsw ax                      ; 既定值“9900000000.00000000”
00431AE1   F6C4 41      test ah,41
00431AE4   74 20      je short locplus-.00431B06
00431AE6   66:C705 2C91>mov word ptr ds:,0FFFF
00431AEF   FF15 DCC4430>call dword ptr ds:[<&MSVBVM50.__vbaExitPr>; MSVBVM50.__vbaExitProc
00431AF5   9B         wait
00431AF6   68 281B4300push locplus-.00431B28
00431AFB   EB 21      jmp short locplus-.00431B1E
00431AFD   66:C705 2C91>mov word ptr ds:,0
00431B06   FF15 DCC4430>call dword ptr ds:[<&MSVBVM50.__vbaExitPr>; MSVBVM50.__vbaExitProc
00431B0C   9B         wait
00431B0D   68 281B4300push locplus-.00431B28
00431B12   EB 0A      jmp short locplus-.00431B1E
00431B14   8D4D CC      lea ecx,dword ptr ss:
00431B17   FF15 2CC4430>call dword ptr ds:[<&MSVBVM50.__vbaFreeVa>; MSVBVM50.__vbaFreeVar
00431B1D   C3         retn
00431B1E   8D4D DC      lea ecx,dword ptr ss:
00431B21   - FF25 54C7430>jmp dword ptr ds:[<&MSVBVM50.__vbaFreeStr>; MSVBVM50.__vbaFreeStr
00431B27   C3         retn
00431B28   8B4D E4      mov ecx,dword ptr ss:
00431B2B   64:890D 0000>mov dword ptr fs:,ecx
00431B32   5F         pop edi
00431B33   5E         pop esi
00431B34   5B         pop ebx
00431B35   8BE5         mov esp,ebp
00431B37   5D         pop ebp
00431B38   C3         retn

--------------------------------------------------------

[ Last edited by jackily on 2005-2-15 at 03:16 PM ]

jackily 发表于 2005-2-15 15:17:55

关键算法,由00431a81跟进。
00431590   55   push ebp
00431591   8BEC   mov ebp,esp
00431593   83EC 0>sub esp,0C
00431596   68 C62>push <jmp.&MSVBVM50.__vbaExceptHandler>
0043159B   64:A1 >mov eax,dword ptr fs:
004315A1   50   push eax
004315A2   64:892>mov dword ptr fs:,esp
004315A9   81EC E>sub esp,0E0
004315AF   A1 589>mov eax,dword ptr ds:
004315B4   53   push ebx
004315B5   56   push esi
004315B6   57   push edi
004315B7   8965 F>mov dword ptr ss:,esp
004315BA   33FF   xor edi,edi
004315BC   50   push eax                        ; eax=001a7514,unicode "ONLocPlus"
004315BD   C745 F>mov dword ptr ss:,locplus-.00402068
004315C4   897D D>mov dword ptr ss:,edi
004315C7   897D D>mov dword ptr ss:,edi
004315CA   897D C>mov dword ptr ss:,edi
004315CD   897D C>mov dword ptr ss:,edi
004315D0   897D B>mov dword ptr ss:,edi
004315D3   897D A>mov dword ptr ss:,edi
004315D6   897D A>mov dword ptr ss:,edi
004315D9   897D 9>mov dword ptr ss:,edi
004315DC   897D 8>mov dword ptr ss:,edi
004315DF   89BD 7>mov dword ptr ss:,edi
004315E5   89BD 6>mov dword ptr ss:,edi
004315EB   89BD 5>mov dword ptr ss:,edi
004315F1   89BD 4>mov dword ptr ss:,edi
004315F7   89BD 3>mov dword ptr ss:,edi
004315FD   89BD 2>mov dword ptr ss:,edi               
00431603   89BD 1>mov dword ptr ss:,edi
00431609   FF15 3>call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>] ; 取"ONLocPlus"的长度放eax,为9
0043160F   8BC8   mov ecx,eax
00431611   FF15 9>call dword ptr ds:[<&MSVBVM50.__vbaI2I4>]   ; MSVBVM50.__vbaI2I4
00431617   8B4D 0>mov ecx,dword ptr ss:
0043161A   BE 020>mov esi,2
0043161F   68 00D>push locplus-.0040D900                  ; UNICODE "&H"
00431624   56   push esi
00431625   8B11   mov edx,dword ptr ds:
00431627   8945 B>mov dword ptr ss:,eax      ; 把长度值9放入ebp-4c,在00431786会用到
0043162A   52   push edx                           ; 注册码地址
0043162B   FF15 F>call dword ptr ds:[<&MSVBVM50.rtcLeftCharBstr>; 取左边两个字符,
00431631   8B1D 1>mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrMove>; MSVBVM50.__vbaStrMove
00431637   8BD0   mov edx,eax
00431639   8D4D A>lea ecx,dword ptr ss:
0043163C   FFD3   call ebx                           ; 把宽型第1、2字符的地址放入ebp-54中       0043163E   50   push eax
0043163F   FF15 8>call dword ptr ds:[<&MSVBVM50.__vbaStrCat>] ; &H和第1、2字符连在一起
00431645   8BD0   mov edx,eax
00431647   8D4D A>lea ecx,dword ptr ss:
0043164A   FFD3   call ebx                           ; 把1a76ac,&H和第1、2字符地址放入ebp-58
0043164C   50   push eax
0043164D   FF15 5>call dword ptr ds:[<&MSVBVM50.rtcR8ValFromBstr> ; &&H和第1、2字符换成浮点数00431653   FF15 F>call dword ptr ds:[<&MSVBVM50.__vbaFpI2>]   ; MSVBVM50.__vbaFpI2
00431659   8BD8   mov ebx,eax
0043165B   8D45 A>lea eax,dword ptr ss:
0043165E   8D4D A>lea ecx,dword ptr ss:
00431661   50   push eax
00431662   51   push ecx
00431663   56   push esi
00431664   FF15 A>call dword ptr ds:[<&MSVBVM50.__vbaFreeStrLis>; MSVBVM50.__vbaFreeStrList
0043166A   8B55 0>mov edx,dword ptr ss:                            ; 注册码存放地址
0043166D   83C4 0>add esp,0C
00431670   89B5 6>mov dword ptr ss:,esi                        ; ESI=0x2
00431676   89B5 5>mov dword ptr ss:,esi
0043167C   8B02   mov eax,dword ptr ds:
0043167E   50   push eax                                        ; 注册码存放地址给EAX
0043167F   FF15 3>call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]; 算注册码长度
00431685   8985 5>mov dword ptr ss:,eax               ; 长度应为0x1a,放入ebp-b0
0043168B   B8 030>mov eax,3
00431690   8D8D 5>lea ecx,dword ptr ss:
00431696   8985 4>mov dword ptr ss:,eax               ; eax=0x3
0043169C   8985 4>mov dword ptr ss:,eax
004316A2   8D95 4>lea edx,dword ptr ss:
004316A8   51   push ecx
004316A9   8D85 3>lea eax,dword ptr ss:
004316AF   52   push edx
004316B0   8D8D 1>lea ecx,dword ptr ss:
004316B6   50   push eax
004316B7   8D95 2>lea edx,dword ptr ss:
004316BD   51   push ecx
004316BE   8D45 D>lea eax,dword ptr ss:
004316C1   52   push edx
004316C2   50   push eax
004316C3   89B5 3>mov dword ptr ss:,esi                              
004316C9   FF15 E>call dword ptr ds:[<&MSVBVM50.__vbaVarForInit>; 和00431925中的call联合使用,相当于for循环语句
004316CF   3BC7   cmp eax,edi                         ;条件符合的话,eax=0,否=1
004316D1   0F84 5>je locplus-.00431932
004316D7   8D4D 9>lea ecx,dword ptr ss:                        
004316DA   8D55 D>lea edx,dword ptr ss:                                 
004316DD   BF 080>mov edi,8
004316E2   51   push ecx
004316E3   52   push edx
004316E4   C785 5>mov dword ptr ss:,locplus-.0040D900   ; UNICODE "&H"
004316EE   89BD 4>mov dword ptr ss:,edi                  ; edi=0x8
004316F4   8975 A>mov dword ptr ss:,esi               ; esi=0x2
004316F7   8975 9>mov dword ptr ss:,esi
004316FA   FF15 C>call dword ptr ds:[<&MSVBVM50.__vbaI4Var>]    ; 转长整型
00431700   50   push eax                                    ; 此处通过计算,每一循环取两个字符,下次是5,7,以此类推
00431701   8B45 0>mov eax,dword ptr ss:
00431704   8B08   mov ecx,dword ptr ds:
00431706   51   push ecx                         ; 注册码地址
00431707   FF15 4>call dword ptr ds:[<&MSVBVM50.rtcMidCharBstr>>; 从EDX值处(=3、5、7等)取两个字符。
0043170D   8945 9>mov dword ptr ss:,eax                ; 地址放入ebp-70
00431710   8D55 8>lea edx,dword ptr ss:                ; 内容值为0,下同
00431713   8D85 7>lea eax,dword ptr ss:
00431719   52   push edx
0043171A   50   push eax
0043171B   897D 8>mov dword ptr ss:,edi                ; edi=0x8
0043171E   FF15 2>call dword ptr ds:[<&MSVBVM50.rtcTrimVar>]    ; MSVBVM50.rtcTrimVar
00431724   8D8D 4>lea ecx,dword ptr ss:                  
0043172A   8D95 7>lea edx,dword ptr ss:
00431730   51   push ecx                        ; ebp-b8 =8
00431731   8D85 6>lea eax,dword ptr ss:
00431737   52   push edx
00431738   50   push eax
00431739   FF15 D>call dword ptr ds:[<&MSVBVM50.__vbaVarAdd>]   ; MSVBVM50.__vbaVarAdd
0043173F   8D4D A>lea ecx,dword ptr ss:
00431742   50   push eax
00431743   51   push ecx
00431744   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaStrVarVal>>; 把&H和注册码连在一起
0043174A   50   push eax      
0043174B   FF15 5>call dword ptr ds:[<&MSVBVM50.rtcR8ValFromBstr>; 转浮点数
00431751   FF15 F>call dword ptr ds:[<&MSVBVM50.__vbaFpI2>]   ; MSVBVM50.__vbaFpI2
00431757   8D4D A>lea ecx,dword ptr ss:            ; call 后ax随注册码在变
0043175A   8BF8   mov edi,eax                              ;VB够笨的,以上实际就是把假码从第3位开始,每次取2个字符,循环取完
0043175C   FF15 5>call dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]; MSVBVM50.__vbaFreeStr
00431762   8D95 6>lea edx,dword ptr ss:
00431768   8D85 7>lea eax,dword ptr ss:
0043176E   52   push edx
0043176F   8D4D 8>lea ecx,dword ptr ss:
00431772   50   push eax
00431773   8D55 9>lea edx,dword ptr ss:
00431776   51   push ecx
00431777   52   push edx
00431778   6A 04push 4
0043177A   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaFreeVarLis>; 清空变量

jackily 发表于 2005-2-15 15:19:37

00431780   8B45 C>mov eax,dword ptr ss:
00431783   83C4 1>add esp,14
00431786   66:3B4>cmp ax,word ptr ss:       ; 最早"ONLocPlus"的长度
0043178A   7D 0Djge short locplus-.00431799
0043178C   66:40inc ax                              ; 计数器
0043178E   0F80 3>jo locplus-.004319D3
00431794   8945 C>mov dword ptr ss:,eax
00431797   EB 07jmp short locplus-.004317A0
00431799   C745 C>mov dword ptr ss:,1
004317A0   0FBF4D>movsx ecx,word ptr ss:
004317A4   8B15 5>mov edx,dword ptr ds:          ; 地址01a7514,unicode "ONLocPlus"
004317AA   8D45 9>lea eax,dword ptr ss:
004317AD   50   push eax
004317AE   51   push ecx                     ; ecx=1,2,3等,类推,
004317AF   52   push edx
004317B0   C745 A>mov dword ptr ss:,1
004317B7   8975 9>mov dword ptr ss:,esi   ; esi=2
004317BA   FF15 4>call dword ptr ds:[<&MSVBVM50.rtcMidCharBstr>>; 取"ONLocPlus”取ecx位值,循环
004317C0   8BD0   mov edx,eax
004317C2   8D4D A>lea ecx,dword ptr ss:
004317C5   FF15 1>call dword ptr ds:[<&MSVBVM50.__vbaStrMove>]; 地址放入ebp-54,0012f8dc
004317CB   50   push eax
004317CC   FF15 6>call dword ptr ds:[<&MSVBVM50.rtcAnsiValueBst>; 分别转ascii,如"O"转换成HEX值,eax=0x4F
004317D2   33C7   xor eax,edi                              ;假码与取的值异或         
004317D4   8D95 4>lea edx,dword ptr ss:
004317DA   8D4D C>lea ecx,dword ptr ss:            ; 地址12f8f4
004317DD   66:898>mov word ptr ss:,ax            ; ax=异或后的值, 放入
004317E4   89B5 4>mov dword ptr ss:,esi
004317EA   FF15 1>call dword ptr ds:[<&MSVBVM50.__vbaVarMove>]; MSVBVM50.__vbaVarMove
004317F0   8D4D A>lea ecx,dword ptr ss:
004317F3   FF15 5>call dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]; MSVBVM50.__vbaFreeStr
004317F9   8D4D 9>lea ecx,dword ptr ss:
004317FC   FF15 2>call dword ptr ds:[<&MSVBVM50.__vbaFreeVar>]; MSVBVM50.__vbaFreeVar
00431802   8D45 C>lea eax,dword ptr ss:
00431805   8D8D 5>lea ecx,dword ptr ss:
0043180B   50   push eax
0043180C   51   push ecx
0043180D   66:899>mov word ptr ss:,bx          ; bx=假码的第1位开始取值,每次2个
00431814   C785 5>mov dword ptr ss:,8002
0043181E   FF15 B>call dword ptr ds:[<&MSVBVM50.__vbaVarTstLe>] ; 比较是否ax<=bx
00431824   66:85C>test ax,ax                                 ; 小于eax=0,否=FFFF
00431827   74 5Aje short locplus-.00431883               ;小于跳,不小于不跳
00431829   8D95 5>lea edx,dword ptr ss:
0043182F   8D45 C>lea eax,dword ptr ss:
00431832   52   push edx
00431833   8D4D 9>lea ecx,dword ptr ss:
00431836   50   push eax
00431837   51   push ecx
00431838   C785 6>mov dword ptr ss:,0FF                     ; 赋值,0x0ff
00431842   89B5 5>mov dword ptr ss:,esi
00431848   66:899>mov word ptr ss:,bx
0043184F   89B5 4>mov dword ptr ss:,esi
00431855   FF15 D>call dword ptr ds:[<&MSVBVM50.__vbaVarAdd>]   ; MSVBVM50.__vbaVarAdd
0043185B   50   push eax
0043185C   8D95 4>lea edx,dword ptr ss:
00431862   8D45 8>lea eax,dword ptr ss:
00431865   52   push edx
00431866   50   push eax
00431867   FF15 0>call dword ptr ds:[<&MSVBVM50.__vbaVarSub>]   ; MSVBVM50.__vbaVarSub
0043186D   8BD0   mov edx,eax                                                            
0043186F   8D4D C>lea ecx,dword ptr ss:
00431872   FF15 1>call dword ptr ds:[<&MSVBVM50.__vbaVarMove>]; MSVBVM50.__vbaVarMove
00431878   8D4D 9>lea ecx,dword ptr ss:
0043187B   FF15 2>call dword ptr ds:[<&MSVBVM50.__vbaFreeVar>]; MSVBVM50.__vbaFreeVar
00431881   EB 2Djmp short locplus-.004318B0            ; 以上为不小于的话,ax+0xff-bx
00431883   8D4D C>lea ecx,dword ptr ss:            ; 由431827跳来,
00431886   8D95 5>lea edx,dword ptr ss:
0043188C   51   push ecx
0043188D   8D45 9>lea eax,dword ptr ss:
00431890   52   push edx
00431891   50   push eax
00431892   66:899>mov word ptr ss:,bx      
00431899   89B5 5>mov dword ptr ss:,esi   ; esi=0x2
0043189F   FF15 0>call dword ptr ds:[<&MSVBVM50.__vbaVarSub>]   ; MSVBVM50.__vbaVarSub
004318A5   8BD0   mov edx,eax                                    ;小于则 bx-ax
004318A7   8D4D C>lea ecx,dword ptr ss:
004318AA   FF15 1>call dword ptr ds:[<&MSVBVM50.__vbaVarMove>]; MSVBVM50.__vbaVarMove
004318B0   8B4D B>mov ecx,dword ptr ss:
004318B3   8D55 C>lea edx,dword ptr ss:
004318B6   52   push edx
004318B7   898D 6>mov dword ptr ss:,ecx
004318BD   C785 5>mov dword ptr ss:,8
004318C7   FF15 C>call dword ptr ds:[<&MSVBVM50.__vbaI4Var>]    ; MSVBVM50.__vbaI4Var
004318CD   50   push eax
004318CE   8D45 9>lea eax,dword ptr ss:
004318D1   50   push eax
004318D2   FF15 2>call dword ptr ds:[<&MSVBVM50.rtcVarBstrFromA>; MSVBVM50.rtcVarBstrFromAnsi
004318D8   8D8D 5>lea ecx,dword ptr ss:
004318DE   8D55 9>lea edx,dword ptr ss:
004318E1   51   push ecx
004318E2   8D45 8>lea eax,dword ptr ss:
004318E5   52   push edx
004318E6   50   push eax
004318E7   FF15 D>call dword ptr ds:[<&MSVBVM50.__vbaVarAdd>]   ; 此处需仔细研究
004318ED   50   push eax
004318EE   FF15 3>call dword ptr ds:[<&MSVBVM50.__vbaStrVarMove>; MSVBVM50.__vbaStrVarMove
004318F4   8BD0   mov edx,eax                  
004318F6   8D4D B>lea ecx,dword ptr ss:          ; 得出数值放入ebp-48,最后连在一起需得000000000099,才正确
004318F9   FF15 1>call dword ptr ds:[<&MSVBVM50.__vbaStrMove>]
004318FF   8D4D 8>lea ecx,dword ptr ss:
00431902   8D55 9>lea edx,dword ptr ss:
00431905   51   push ecx
00431906   52   push edx
00431907   56   push esi
00431908   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaFreeVarLis>; MSVBVM50.__vbaFreeVarList
0043190E   83C4 0>add esp,0C
00431911   8D85 1>lea eax,dword ptr ss:
00431917   8D8D 2>lea ecx,dword ptr ss:
0043191D   8D55 D>lea edx,dword ptr ss:
00431920   50   push eax
00431921   51   push ecx
00431922   52   push edx
00431923   8BDF   mov ebx,edi
00431925   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaVarForNext>; 为下一循环作准备
0043192B   33FF   xor edi,edi
0043192D   ^ E9 9DF>jmp locplus-.004316CF
00431932   8B55 B>mov edx,dword ptr ss:
00431935   8D4D D>lea ecx,dword ptr ss:
00431938   FF15 9>call dword ptr ds:[<&MSVBVM50.__vbaStrCopy>]; MSVBVM50.__vbaStrCopy
0043193E   9B   wait
0043193F   68 BD1>push locplus-.004319BD
00431944   EB 44jmp short locplus-.0043198A
00431946   F645 F>test byte ptr ss:,4
0043194A   74 09je short locplus-.00431955
0043194C   8D4D D>lea ecx,dword ptr ss:
0043194F   FF15 5>call dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]; MSVBVM50.__vbaFreeStr
00431955   8D45 A>lea eax,dword ptr ss:
00431958   8D4D A>lea ecx,dword ptr ss:
0043195B   50   push eax
0043195C   51   push ecx
0043195D   6A 02push 2
0043195F   FF15 A>call dword ptr ds:[<&MSVBVM50.__vbaFreeStrLis>; MSVBVM50.__vbaFreeStrList
00431965   83C4 0>add esp,0C
00431968   8D95 6>lea edx,dword ptr ss:
0043196E   8D85 7>lea eax,dword ptr ss:
00431974   8D4D 8>lea ecx,dword ptr ss:
00431977   52   push edx
00431978   50   push eax
00431979   8D55 9>lea edx,dword ptr ss:
0043197C   51   push ecx
0043197D   52   push edx
0043197E   6A 04push 4
00431980   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaFreeVarLis>; MSVBVM50.__vbaFreeVarList
00431986   83C4 1>add esp,14
00431989   C3   retn
0043198A   8D85 1>lea eax,dword ptr ss:
00431990   8D8D 2>lea ecx,dword ptr ss:
00431996   50   push eax
00431997   51   push ecx
00431998   6A 02push 2
0043199A   FF15 4>call dword ptr ds:[<&MSVBVM50.__vbaFreeVarLis>; MSVBVM50.__vbaFreeVarList
004319A0   8B35 2>mov esi,dword ptr ds:[<&MSVBVM50.__vbaFreeVar>; MSVBVM50.__vbaFreeVar
004319A6   83C4 0>add esp,0C
004319A9   8D4D D>lea ecx,dword ptr ss:
004319AC   FFD6   call esi
004319AE   8D4D C>lea ecx,dword ptr ss:
004319B1   FFD6   call esi
004319B3   8D4D B>lea ecx,dword ptr ss:
004319B6   - FF25 5>jmp dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]   ; MSVBVM50.__vbaFreeStr
004319BC   C3   retn
004319BD   8B4D E>mov ecx,dword ptr ss:
004319C0   8B45 D>mov eax,dword ptr ss:
004319C3   5F   pop edi
004319C4   5E   pop esi
004319C5   64:890>mov dword ptr fs:,ecx
004319CC   5B   pop ebx
004319CD   8BE5   mov esp,ebp
004319CF   5D   pop ebp
004319D0   C2 040>retn 4                                    ; 跳回 00431a86
   
--------------------------------------------------------------------------------
后记:
1.05于2003年3月推出,增加了专用的对照文件编辑器、工具“偏移量转换器”、“文本编码查询”和“剪贴板繁简转换”,给用户提供了很大的便利条件。但至今本人未见该软件的注册机面世,不知是各位高手不屑一破,还是说其在算法上有一定的难度。因为要试用其全部功能,于是便尝试着分析了一下,本注册机向下兼容,也适合以前版本。
                                  二零零五年元月二十三日
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

crack123 发表于 2005-2-16 09:23:53

哇!好长哦!
支持下

ytsnow 发表于 2005-2-16 09:41:21

hao !pf

noTme 发表于 2005-2-16 15:39:28

支持原创的说

546m 发表于 2005-3-14 00:03:54

非常好!支持,不过我还是喜欢注册机!

hjyzzz8888 发表于 2005-3-14 20:24:26

看不懂!!!!!!!

lhl8730 发表于 2006-3-20 23:39:38

详细,支持一下。
页: [1]
查看完整版本: 【原创】OverNimble LocPlus 1.05注册算法全程详解(写给学VB算法者)