首页
社区
课程
招聘
[原创]关于注册机
发表于: 2007-2-11 15:22 10043

[原创]关于注册机

2007-2-11 15:22
10043

关于注册机,我看到风飘在《手册》一月刊上有一篇文章关于写注册机,我学习crack的时间只有他的零头,但是那篇文章似乎夸大了写注册机的简单性,或许对那么厉害的风飘来讲写注册机太简单了。但我想要说的是,可以像那篇文章中的说的可以利用程序本身的源码的只是一类软件,而且现在数量正越来越少。改变多少要有一些。有些我们不可能直接利用原来的代码,否则不是所有的程序都可以轻而易举的破解了吗?那么还要DSA,ECC等算法干吗?
还有如果你一定要用高级语言来写汇编,那么你最好学Delphi或者c这种可以使用内联汇编的语言,但是好像在Delphi加入了.net计划之后就不支持内联汇编,我想vc.net也一样。虽然说有时用VB也可以写注册机,但是有些时候实现起来很麻烦。
举个例子来说吧!让我们看看另一类不可以直接利用源码的软件,应该怎么破解。《照片桌面》我曾在06年的11月刊上发表了对它的爆破,但是要找出注册码,这个还需要一点编程知识,和一点汇编基础。
我们开始,OD载入。关键的地方很容易找到如下:

/*403163*/  MOVZX EDX,BYTE PTR DS:[EAX];EAX是伪码的地址
/*403166*/  MOV ECX,ESI;ESI的址为FFFFFFFF
/*403168*/  AND ECX,0FF
/*40316E*/  XOR ECX,EDX
/*403170*/  MOV EBP,DWORD PTR DS:[EDI+ECX*4];看到这里我们就知道EDI寄存器的址对这个软件的注册有很重要的作用。
/*403173*/  SHR ESI,8
/*403176*/  XOR ESI,EBP
/*403178*/  INC EAX;指针指向下一个
/*403179*/  DEC EBX;EBX是注册码长度
/*40317A*/  JNZ SHORT 照片桌面.00403163
……没用的代码省略了
/*40317D*/  MOV EAX,ESI
……同上一样
/*403181*/  NOT EAX;根据下面一句,也就是说明这里的EAX需要=15A7393A
/*403DBF*/  CMP EAX,EA58C6C5;比较后要true

上面是一个循环,就是代码最关键的地方。所以我们此刻需要一件武器帮助我们,就是OD插件:内存数据格式转换或者data ripper也可以。
看着上面的东西我们不禁感觉到这个东西有点hash的色彩。我们唯一写注册机的方法就是穷举,另外至少我是没有办法了,如果你有幸是一个密码学高手或许可以找出这种算法的漏洞。EDI的值是不定的,但是edi和edi+ecx*4指向的数据块是确定的。所以我们要找出这个表的范围,ECX*4 ,AND ECX,0FF从这句话我们可以知道ECX的值最大不过FF。用工具计算一下ECX*4 =3FC,我们把目光盯住数据窗口。在命令框中输入d edi。我们先选择0012EFB8到12F3B4的区域(这只是我这边),然后用“内存数据格式转换”插件把这些数据提取出来,因为它本身取值就是DWORD,所以我们也要选择以DWORD的形式来复制。如图1



图1
然后保存。接下来我们就要实行穷举了。
下面是c++的实现方法。我对c++尤其是vc++不怎么精通,所以我写得差那么就很不好意思了。
其实这么一个东西写注册机要小鸟来写真的难了一点。我一共花了一天写了上文《内联汇编》,又用了一天写了这个东西的注册机。使用过c语言的人都知道它本身就具有位运算,所以假如你够本事的话,基本上可以直接使用位运算和指针达到内联汇编的效果。下面给出我在vc++6.0中调试通过的c++源代码。大家注意我的c++代码和软件本身的汇编代码的区别。

#include <iostream.h>
const int sj[]={我们从数据窗口中拷贝来的数据};
void main()
{
        int n;
        int b;
for (n=0x 01000000;n<=0xFFFFFFFF;n++)
        {
          __asm
        {
                mov ebx,4
                lea EAX,n
        MOV ESI,0xFFFFFFFF
line1:
                MOVZX EDX,byte ptr[EAX+ebx-1]
        MOV ECX,ESI
                and ECX,0xFF
                XOR ECX,EDX
                shl ecx,2;相当于ecx*4
                MOV edi,sj[ECX]
                SHR ESI,8
                XOR ESI,edi
                dec EBX;EBX是注册码长度
                JNZ line1
                CMP ESI,0x15A7393A
                JZ line2
                push 0
                pop b
                jmp line3
line2:
                push 1
                pop b
line3:
    }
           if (b==1)
           {
                   zh=n;
                   for (n1=0;zh>0;n1++)
                        {
                                sz[n1]=zh % 256;
                                zh=zh / 256;
                        };
                                n1--;
                for (;n1>=0;n1--)
                        {
                                cout<<char(sz[n1]);
                        };
           }
        }

}
需要解释的是这句:for (n=0x10000000;n<=0xFFFFFFFF;n++),大家肯定感到很奇怪。我这是为了方便处理数据,因为无论是字符串或者数字,在内存中都是用数字来表示的。所以这句话我是模拟了在从4字节即00 00 00 01――FF FF FF FF下所有在内存中出现的情况,因为假如数据再大一点,我们穷举的时间会很大。我也就不能投机使用这种外循环采用for语句。稍高一点的鸟知道,从有符号的角度来讲n的值从0x01000000一直到最大,最后到-1。虽然这有点类似整数溢出,但是这个溢出效果就是我要的。
还有这句:MOVZX EDX,byte ptr[EAX+ebx-1];EAX是伪码的地址,因为软件处理我们的注册码的时候就是从我们输入的第一位开始的,而我们模拟的值在内存中储存着的是反向的。打个比方说:我输入的伪码是1234,那么软件经过处理之后,把它们安排在内存区域里的格式是31 32 33 34,而我们在模拟的n=0x31 32 33 34在内存中是这样存储着的34 33 32 31。所以我们要从最后一位开始。这里大家最好分别用OD调试软件和用vc本身调试这段源代码,就可以明白了。
其它的如mov ebx,4就不难理解了,我这是手动设置byte数。运气很好的是在上述范围内,我追到一组注册码+*05。我想假如把数据扩大到0x0100000000――0x9999999999这样的话肯定可以搜索到更多的注册码,但是在设置4字节下我的赛扬2.66GHZ就跑了好几分钟,所以在5byte数据下要完全搜过的话,不但外围的循环不能投机取巧这样模拟,要改写,而且内部要多不少的指针操作,所以我懒惰一下,不写了。反正我已经找到了一组。有兴趣且够实力的读者不妨自己试试,但千万不要和自己过不去,因为有时候注册机真的很难写。
再说一点废话,上面的循环有一半是做无用功,因为ASCII码值估计它只用了基本的0-128。我把扩展ASCII码表也模拟进去了。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 623
活跃值: (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
2
支持 汇编可以更高效
2007-2-11 15:22
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3
学习你的第二个帖子
2007-2-11 16:10
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
算法是标准crc32。 表都是标准的。。
2007-2-12 14:48
0
雪    币: 277
活跃值: (312)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
5
那找个库调用下就行了
2007-2-12 22:02
0
雪    币: 314
活跃值: (10)
能力值: ( LV12,RANK:570 )
在线值:
发帖
回帖
粉丝
6
后来我知道这是CRC32,很不好意思.可是也说明一点,就是CRC32不仅可以用来校验.还可以用来验证注册码.
2007-2-18 14:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢了,让我学不少的知识
2007-2-20 16:14
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习 ,VC内联汇编真是强大
2007-2-21 14:15
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
正想这事儿呢!谢谢谢谢
2007-2-22 12:42
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
请问用int sj[]存32位数不是会溢出吗(vc++ int 16位)为什么还能得到正确数据?……
2007-2-22 12:51
0
雪    币: 707
活跃值: (1301)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
11
不错.......
2007-5-10 22:32
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
本人资历不是很好。。 看不太懂
2007-5-10 22:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
呵呵,学习
2007-5-11 21:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14

我那个缺点东西
2007-5-12 17:16
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习当中...
2007-5-12 19:36
0
游客
登录 | 注册 方可回帖
返回
//