老文章档案 · 2003 年

GIF Movie Gear v3.0.2 破解小谈(附注册机源码)

赢政天下 [WINZHENG.COM] · 网络学院 · 2003-08-03 · 作者:商朝子 人气: · 出处:赢政天下整理收藏)

okGIF Movie Gear v3.0.2 破解小谈(附注册机源码)

最近在老罗的坛子里好多人的签名都换成了PL的图片。嘿嘿,偶自然也不愿落后,so便想自己DIY一个英俊潇洒玉树临风貌比潘安才比伯虎的挂上去,可是以前买的Flash MX D版盘怎么也找不到了,于是便到天空那边儿去找做GIF动画的软件,再于是便找到了这个软件,据说是使用简单,方便快捷…

结果,呵呵(冷汗…搞了一个上午也没搞出张像样的图片来)。偷鸡不成,怎么也要抓一把米回来吧,反正今天除了没完成的事儿其它的事儿都做完了… ;)

首先当然是先要看一下人家有没有加壳,结果是另人满意的,过程是另人愉快的,答案是VC6.0的。^_^具然没加壳…

那还等什么呢?点Help菜单中的Register Now…。接着就呼出你埋伏已久的调试器吧,我用的是TRW2000。(随便问一句哥们儿,TRW2000呼出是按Ctrl+N这事儿你知道吧,知道啊。那上海2010年办世博会,这事儿你也知道吧,哦,都知道了,那甲A前天晚上…当!…好好好,我继续就是了)呼出TRW2000后下断点bpx hmemcpy(我用的是98嘛),然后按F5返回。接着在Name处偶输入Suunb[CCG],在Code处输入20030413(呵呵,今天的日期 ^_^) 好的,接下来就按OK吧。

结果是显而易见的,成功被我军爱国者导弹给拦截掉了。之后就一个pmodule导弹过去跳出程序的领空,之后在按F12的时候会发现只按1次就提示出错了。

好的,知道这些后,就再来一遍吧。这次在pmodule返回后就按F10来单步执行,代码如下:

0167:00431972 lea edx,[esp+c4] <--会来到这里!

0167:00431979 push byte +64

0167:0043197b push edx

0167:0043197c push dword 0450

0167:00431981 push esi

0167:00431982 call edi <--看上边儿压进去的参数,这个Call应该是调用API函数GetDlgItem来得到注册码输入框的句柄。

0167:00431984 push eax

0167:00431985 call ebx <--用先前得到的注册码输入框的句柄通过调用GetWindowTextA来得到输入的注册码

0167:00431987 lea eax,[esp+c4] <--用d指令可以知道esp+c4处装的是用户输入的注册码,将这个地址装入eax中

0167:0043198e lea ecx,[esp+60] <--同样用d指令可以知道esp+60处装的是用户输入的注册名,装其地址装入ecx中

0167:00431992 push eax <--注册码地址压栈

0167:00431993 push ecx <--注册名地址压栈

0167:00431994 call 00431590 <--嘿嘿,整个过程就由这个CALL一手操控了

0167:00431999 add esp,byte +08 <--栈顶还原

0167:0043199c test eax,eax <--测试eax中装入的值

0167:0043199e jz near 00431a51 <--为0就跳到00431a51处,跳过去就Over了

0167:004319a4 lea edx,[esp+10] <--从这里开始程序通过调用RegCreateKeyExA、RegSetvalueExA等其它一些注册表相关API来向注册表中写入用户的注册信息。也就是HKEY_CURRENT_USER\Software\gamani\GIFMovieGear\2.0主键下面的RegName3与RegCode3子键。当然这是在你输入的注册码正确的前提下,RegName3中装的是你的注册名,RegCode3中自然就是你输入的册码了…

0167:004319a8 lea eax,[esp+0c]

0167:004319ac push edx

0167:004319ad push eax

0167:004319ae push byte +00

0167:004319b0 push dword 000f003f

0167:004319b5 push byte +00

0167:004319b7 push dword 0044ed14

0167:004319bc push byte +00

0167:004319be push dword 0044b3f8 <--此处可以看一下0044b3f8,得到Software\gamani\GIFMovieGear\2.0

0167:004319c3 push dword 80000001 <--这个值就是HKEY_CURRENT_USER

0167:004319c8 call `ADVAPI32!RegCreateKeyExA` <--API函数RegCreateKeyExA

0167:004319ce lea edi,[esp+60]

0167:004319d2 or ecx,byte -01

0167:004319d5 xor eax,eax

0167:004319d7 mov edx,[esp+0c]

0167:004319db repne scasb

0167:004319dd not ecx

0167:004319df mov ebx,[00448018]

0167:004319e5 push ecx

0167:004319e6 lea ecx,[esp+64]

0167:004319ea push ecx

0167:004319eb push byte +01

0167:004319ed push eax

0167:004319ee push dword 0044d498 <--0044d498处就是字符串RegName3

0167:004319f3 push edx

0167:004319f4 call ebx <--RegSetvalueExA

0167:004319f6 lea edi,[esp+c4]

0167:004319fd or ecx,byte -01

0167:00431a00 xor eax,eax

0167:00431a02 repne scasb

0167:00431a04 not ecx

0167:00431a06 lea eax,[esp+c4]

0167:00431a0d push ecx

0167:00431a0e mov ecx,[esp+10]

0167:00431a12 push eax

0167:00431a13 push byte +01

0167:00431a15 push byte +00

0167:00431a17 push dword 0044d4a4 <--0044d4a4嘛,就是字符串RegCode3

0167:00431a1c push ecx

0167:00431a1d call ebx <--RegSetvalueExA

0167:00431a1f mov edx,[esp+0c]

0167:00431a23 push edx

0167:00431a24 call `ADVAPI32!RegCloseKey`

0167:00431a2a push dword 0044d4b0

0167:00431a2f push dword 80000002

0167:00431a34 call `ADVAPI32!RegDeleteKeyA`

0167:00431a3a push byte +01

0167:00431a3c push esi

0167:00431a3d call `USER32!EndDialog` <--用EndDialog来关掉输入注册码的这个对话框

0167:00431a43 pop edi

0167:00431a44 pop esi

0167:00431a45 xor eax,eax

0167:00431a47 pop ebx

0167:00431a48 add esp,011c

0167:00431a4e ret 10 <--返回

0167:00431a51 push byte +30 <--在前边儿0043199c处如果没通过就会跳到这里,到了这里就一切都玩儿完了 ;)

0167:00431a53 push dword 9d15

0167:00431a58 push dword 9d14

0167:00431a5d push esi

0167:00431a5e call 0040ee90

0167:00431a63 add esp,byte +10

0167:00431a66 push dword 044f

0167:00431a6b push esi

0167:00431a6c call edi

0167:00431a6e push eax

0167:00431a6f call `USER32!SetFocus`

0167:00431a75 pop edi

0167:00431a76 pop esi

0167:00431a77 xor eax,eax

0167:00431a79 pop ebx

0167:00431a7a add esp,011c

0167:00431a80 ret 10

HeHe~~很明显吧,00431994处的那个CALL就是关键的所在嘛。

也就是说如果在00431994处的那个CALL中程序确定注册码是正确的话就会将其与用户名一同输入进注册表,以后每次程序启动的时候都会进行比较。But你输入的是错误的话嘛,程序就懒得去写进注册表了。所以我们尽管可以在0043199c处的时候用r fl z指令来欺骗程序,但一点儿用都没有 (众人:那你说它干嘛)

那接着就再来一遍,这次就可以直接用断点bpx 00431994了。断到后就按F8跟进去吧:

0167:00431590 push ebx

0167:00431591 push ebp

0167:00431592 mov ebp,[esp+10] <--将注册码的地址装入ebp中

0167:00431596 push esi

0167:00431597 push edi

0167:00431598 cmp byte [ebp+00],6d <--ebp+00也就是注册码的第一位,用注册码的第一位与6d相比(6d即m的ASCII码)

0167:0043159c jnz near 00431642 <--第一位不是m就跳到00431642处,跳过去就玩儿完了。呵呵,我输入的是20030413,在这里就挂掉了,再来一遍,这次把前4位改成mg37,即mg3720030413

0167:004315a2 cmp byte [ebp+01],67 <--判断注册码的第2位是否为g

0167:004315a6 jnz near 00431642

0167:004315ac cmp byte [ebp+02],33 <--同理,判断第3位是否为3

0167:004315b0 jnz near 00431642

0167:004315b6 cmp byte [ebp+03],37 <--第4位是否为4

0167:004315ba jnz near 00431642

0167:004315c0 mov ebx,0044d4c4

0167:004315c5 mov edx,[ebx]

0167:004315c7 or ecx,byte -01

0167:004315ca mov edi,edx

0167:004315cc xor eax,eax

0167:004315ce repne scasb

0167:004315d0 not ecx

0167:004315d2 dec ecx

0167:004315d3 mov edi,edx

0167:004315d5 mov esi,ebp

0167:004315d7 xor eax,eax

0167:004315d9 repe cmpsb

0167:004315db jz 00431642

0167:004315dd add ebx,byte +04

0167:004315e0 cmp ebx,0044d4c8

0167:004315e6 jl 004315c5

0167:004315e8 cmp byte [ebp+04],73 <--比较看注册码的第5位是否为s,ebp中装的其实是注册码的地址,这点很重要,后边儿会有说明

0167:004315ec jnz 004315ef <--不是就跳到004315ef处

0167:004315ee inc ebp <--是的话ebp+1

0167:004315ef add ebp,byte +07 <--ebp加上7

0167:004315f2 push ebp <--ebp入栈

0167:004315f3 call 0043f3c8 <--!!

0167:004315f8 mov edx,[esp+18]

0167:004315fc add esp,byte +04

0167:004315ff mov edi,edx

0167:00431601 xor ecx,ecx <--ecx清0

0167:00431603 mov dl,[edx] <--装入注册名中的第一个字符

0167:00431605 mov esi,0bdf <--esi中装入0bdf,即十进制数3039

0167:0043160a test dl,dl <--看dl中是否为0

0167:0043160c jz 00431634

0167:0043160e movsx edx,dl <--霸占整个edx寄存器 ;)

0167:00431611 inc ecx <--ecx加1

0167:00431612 imul edx,ecx <--用edx中此时装入的注册名中的某一位字符乘的ASCII码乘以ecx中的值

0167:00431615 add esi,edx <--用esi中的值加上edx中的值

0167:00431617 cmp esi,17be <--用esi中的值与17be,即十进制数6078比较

0167:0043161d jng 00431625 <---不大于不跳到00431625处

0167:0043161f sub esi,17be <--大于的话就减去它

0167:00431625 cmp ecx,byte +0a <--用A(也就是10)与ecx中的值比较

0167:00431628 jng 0043162c <--不大于就跳到0043162c处

0167:0043162a xor ecx,ecx <--ecx清0

0167:0043162c mov dl,[edi+01] <--dl中装入注册名中的下一个字符

0167:0043162f inc edi <--edi加上1

0167:00431630 test dl,dl <--测试dl

0167:00431632 jnz 0043160e <--不为0就跳加0043160e处继续用下一位来进行计算

0167:00431634 cmp esi,eax <--比较esi与eax中的值,esi中装入的就是前边儿0043160e-00431632处将注册名中各位字符进行计算后的值,而eax中的值是通过004315f3处的这个CALL装进来的,相对于我输入的这个注册名及注册码,它的值是76CD,也就是十进制数30413。

0167:00431636 jnz 00431642 <--不相等就跳到00431642处

0167:00431638 pop edi

0167:00431639 pop esi

0167:0043163a pop ebp

0167:0043163b mov eax,01 <--相等的话就继续执行到这里,并将eax置1,我们已经知道出来后会比较看eax是否为0,是的话就Game Over

0167:00431640 pop ebx

0167:00431641 ret

0167:00431642 pop edi <--从前面跳过来的话就…

0167:00431643 pop esi

0167:00431644 pop ebp

0167:00431645 xor eax,eax <--可恶吧,会将eax置0

0167:00431647 pop ebx

0167:00431648 ret

我认为我有必要讲一下,其实这并不难理解。在004315e8处的时候我们可以通过d指令知道ebp中装的其实就是注册码的地址,在004315e8处的时候会比较注册码的第5位是否为s,是的话就将ebp加上1。而到了004315ef处的时候会将ebp加上7,之后就将这个地址压栈了。过了004315f3处的那个CALL后EAX中的值就会改变了,完全不必要追进去,猜也能猜出来了。呵呵,这个CALL的作用就是将之前004315f2处压入的ebp中的地址处开始的值装入eax中。而ebp中装的就是注册码的第7位的地址,明白过来了吗?注册码从第7位开始的值就是程序真正要用的 ;)可问题是第7位以后还有几位呢?嘿嘿,这个很容易就能发现,在00431617的时候程序不是会判断esi中的值是否大于6078吗?而6078,也就是6078只有4位,所以嘛,注册码的位数就是7+4即11位!不过在004315e8和我们会发现程序会判断注册码的第5位是否为s,是的话就接着将ebp加上1,所以问题就解决了。正确的注册码位数只有两种情况:一种是11位,另一种是12位,这个12位的第5位是一个固定不变的,即s。

呵呵,我们来看一下正确的注册码的格式吧,第一种11位的是mg37XXXXXXX,另一种12位的是mg37sXXXXXXX。

现在我们知道的已经够多了,那就写注册机吧 ;)

这之前再大概说一遍程序注册码的计算过过程:

首先固定不变的是程序注册码的前4位,永远是mg37,然后有一个可有可无的位,即第5位,要这一位的话,就让它为s (注意如果注册码的第5位是s,那就应该在其后再补上3位),否则就不要它而直接在mg37后边儿随便补充3位,就比如说CCG ^_^。而接下来就是最后4位了,这个也是重要的地方所在了 ;) 后4位的计算过程其实也不难,就是用你输入的注册名的首位字符的ASCII码乘以X(X每计算一位字符就加上1,如果值后来一直累加到11,就会还原为0)。再用这个乘积加上3039。并将其保存起来,这里称它为Y,之后比较Y是否大于6078,如果大于就用Y减去6078。接下来第二位字符参加运算,同样用其值乘以X,然后加上Y,再比较Y是否大于6078,再接下来第三位字符参加运算,用其乘以X,然后加上Y…直到所有字符均参加完运算…

BTW:如果字符参加完运算后得到的是一个3位有效值,比如123,就在1的前边儿补上一个0,如0123。

贴的这个是注册机源码是Delphi的,直接声明这个函数就能用了:

function KeyGen(Name: String): String;

var

i,Cnt,vai,ASC:integer;

Serial:String;

begin

Cnt:=3039;

vai:=0;

for i:=1 to Length(Name) do

begin

inc(vai);

ASC:=Ord(Name[i]);

ASC:=ASC*vai;

Cnt:=Cnt+ASC;

if Cnt>6078 then Cnt:=Cnt-6078;

if vai>10 then vai:=0;

end;

Serial:=inttostr(Cnt);

Case Length(Serial) of

3:Serial:='0'+Serial;

2:Serial:='00'+Serial;

1:Serial:='000'+Serial;

end;

Serial:='mg37CCG'+Serial;

Result:=Serial;

end;

OK,就这些。

(出处:赢政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史