DVDRecode 1.14 注册码破解 续之 注册机
工具:OllyDbg v1.10、VC++ 6.0
环境:WIN XP
作者:ratarice
注册码的破解过程我就不多说了,大家可以看我上次发的帖子。
http://bbs.pediy.com/showthread.php?threadid=11032
不知道自己能不能说清楚,大家凑合着看吧,我把注册机写出来了,我可以把源代码打包发给大家,有需要的
人请给我发邮件:ratarice@sina.com。
言归正传,开始咱们的编写注册机之旅吧!
想写注册机,当然要先弄明白它的算法了,咱们来看看。根据上一篇帖子的分析,知道了算法的关键CALL在这
里:
0040B4E0 /LEA ECX,DWORD PTR SS:[ESP+18]---------
0040B4E4 |PUSH ECX |
0040B4E5 |MOV EDX,ECX |
0040B4E7 |PUSH 20 |
0040B4E9 |PUSH EDX |
0040B4EA |CALL DVDRecod.0042A0B0------------ |---》循环0xB次处理email
0040B4EF |ADD ESP,0C | 处理后的数据放在[ESP+18]
0040B4F2 |DEC ESI |
0040B4F3 \JNZ SHORT DVDRecod.0040B4E0----------
是个循环处理过程,跟进去看看它是怎么处理的。这个函数比较大,不过重复的东西多,我就不把反汇编的代
码列出来了。写写它的处理过程吧。
首先,程序中预先有几个数组,一个是默认的email数组(32个CHAR,unsigned char g_table_base[32]);相
加数的数组(64个long word,unsigned int g_compute_num[64]);给定的email处理顺序数组(unsigned
int g_compute_seq[64]);位移数组(unsigned int g_displacement[4][8]);注册码生成的索引数组
(char g_index[16])。
然后,它建立了一个4个long word的数组,分别保存处理的上上上上次结果,上上上次结果,上上次结果和上
次结果。初始值是0x67452301,0x10325476,0x98BADCFE,0xEFCDAB89(unsigned int g_compute_base[4])。把
输入的email生成64个CHAR数组(前32个CHAR是email+默认email值,后32个CHAR是固定的,unsigned char
g_email_table[64])。
然后,使用下面的算法进行64次循环处理,([1]中表示使用第1步计算的结果,依此类推;使用的运算符用C语
言表示)
0-15次循环使用的算法:
1.上次结果取反
2.[1]&上上上次结果
3.上上次结果&上次结果
4.[2]|[3]
5.[4]+g_email_table[]
6.[5]+上上上上次结果+g_comput_num[]
7.移位
8.[7]+上次结果
9.修改g_compute_base表
16-31次循环使用的算法:
1.上上上次结果取反
2.[1]&上上次结果
3.上上上次结果&上次结果
4.[2]|[3]
5.[4]+g_email_table[]
6.[5]+上上上上次结果+g_comput_num[]
7.移位
8.[7]+上次结果
9.修改g_compute_base表
32-45次循环使用的算法:
1.上上上次结果^上上次结果
2.[1]^上次结果
3.[2]+g_email_table[]
4.[3]+上上上上次结果+g_comput_num[]
5.移位
6.[7]+上次结果
7.修改g_compute_base表
第46次循环使用的算法:
1.上次结果^上上上次结果
2.[1]^上上次结果
3.[2]+g_email_table[]
4.[3]+上上上上次结果+g_comput_num[]
5.移位
6.[7]+上次结果
7.修改g_compute_base表
第47次循环使用的算法:
1.上上次结果^上次结果
2.[1]^上上上次结果
3.[2]+g_email_table[]
4.[3]+上上上上次结果+g_comput_num[]
5.移位
6.[7]+上次结果
7.修改g_compute_base表
48-63次循环使用的算法:
1.上上上次结果取反
2.[1]|上次结果
3.[2]^上上次结果
4.[4]+g_email_table[]
5.[4]+上上上上次结果+g_comput_num[]
6.移位
7.[6]+上次结果
8.修改g_compute_base表
然后,产生计算后的结果,结果为16个CHAR数组,保存在g_email_table[]的0-15位:
1.上上上上次结果+上上上上次结果(初)
2.上上上次结果+上上上次结果(初)
3.上上次结果+上上次结果(初)
4.上次结果+上次结果(初)
5.[1]倒序形成g_email_table[]的0-3
6.[3]倒序形成g_email_table[]的4-7
7.[2]倒序形成g_email_table[]的8-11
8.[1]倒序形成g_email_table[]的12-15
然后这64次循环要执行执行11次,
最后,根据g_email_table[]的0-15位,查g_index[]表生成最后的注册码。
1.以第g_email_table[0]的前4位查表,生成注册码的第0个数
2.以第g_email_table[0]的后4位查表,生成注册码的第1个数
3.以第g_email_table[1]的前4位查表,生成注册码的第2个数
4.以第g_email_table[1]的后4位查表,生成注册码的第3个数
...
依此类推
...
31.以第g_email_table[15]的前4位查表,生成注册码的第30个数
32.以第g_email_table[15]的后4位查表,生成注册码的第31个数
呵呵,可算说完了,希望大家能看懂,下面看核心代码:
unsigned char g_table_base[32] =
{0x3E,0x2E,0x4E,0x00,0xB6,0xD0,0x68,0x80,0xFF,0xFA,0x08,0x01,0x64,0x00,0x4E,0x56,
0x4E,0x5E,0x4E,0x8A,0x28,0xBF,0x75,0x41,0x69,0x2F,0x0C,0xA9,0xFE,0x64,0x53,0x7A};
unsigned int g_compute_num[64] =
{0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,
0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,0x6B901122,0xFD987193,0xA679438E,0x49B40821,
0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,0xD62F105D,0x02441453,0xD8A1E681,0xE7D3FBC8,
0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,
0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,
0x289B7EC6,0xEAA127FA,0xD4EF3085,0x04881D05,0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,
0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,
0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391};
/*0:上上上上次结果,1:上上上次结果,2:上上次结果,3:上次结果*/
unsigned int g_compute_base[4] = {0x67452301,0x10325476,0x98BADCFE,0xEFCDAB89};
/*for now*/
unsigned char g_email_table[64] =
{0x72,0x61,0x74,0x61,0x72,0x69,0x63,0x65,0x40,0x73,0x69,0x6E,0x61,0x2E,0x63,0x6F,
0x6D,0x3E,0x2E,0x4E,0x00,0xB6,0xD0,0x68,0x80,0xFF,0xFA,0x08,0x01,0x64,0x00,0x4E,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
/*位移表*/
unsigned int g_displacement[4][8] = {0x07,0x19,0x0C,0x14,0x11,0x0F,0x16,0x0A,
0x05,0x1B,0x09,0x17,0x0E,0x12,0x14,0x0C,
0x04,0x1C,0x0B,0x15,0x10,0x10,0x17,0x09,
0x06,0x1A,0x0A,0x16,0x0F,0x11,0x15,0x0B};
unsigned int g_compute_seq[64] =
{0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,
0x1,0x6,0xb,0x0,0x5,0xa,0xf,0x4,0x9,0xe,0x3,0x8,0xd,0x2,0x7,0xc,
0x5,0x8,0xb,0xe,0x1,0x4,0x7,0xa,0xd,0x0,0x3,0x6,0x9,0xc,0xf,0x2,
0x0,0x7,0xe,0x5,0xc,0x3,0xa,0x1,0x8,0xf,0x6,0xd,0x4,0xb,0x2,0x9};
int main(int argc, char* argv[])
{
/*define variables*/
unsigned int temp1;
unsigned int temp2;
unsigned int *temp_ptr;
int seq;
int left, right;
seq = 0;
unsigned int compute_backup[4];
int loop;
/*scanf email input*/
for (loop=0; loop<11; loop++)
{
g_compute_base[0] = 0x67452301;
g_compute_base[1] = 0x10325476;
g_compute_base[2] = 0x98BADCFE;
g_compute_base[3] = 0xEFCDAB89;
compute_backup[0] = 0x67452301;
compute_backup[1] = 0x10325476;
compute_backup[2] = 0x98BADCFE;
compute_backup[3] = 0xEFCDAB89;
/*begin compute*/
for (seq=0; seq<16; seq++)
{
/*1.上次结果取反*/
temp1 = ~g_compute_base[3];
/*2.[1]&上上上次结果*/
temp1 = temp1 & g_compute_base[1];
/*3.上上次结果&上次结果*/
temp2 = g_compute_base[2] & g_compute_base[3];
/*4.[2]|[3]*/
temp1 = temp1 | temp2;
/*5.[4]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*6.[5]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*7.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*8.[7]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
}
for (seq=16; seq<32; seq++)
{
/*1.上上上次结果取反*/
temp1 = ~g_compute_base[1];
/*2.[1]&上上次结果*/
temp1 = temp1 & g_compute_base[2];
/*3.上上上次结果&上次结果*/
temp2 = g_compute_base[1] & g_compute_base[3];
/*4.[2]|[3]*/
temp1 = temp1 | temp2;
/*5.[4]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*6.[5]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*7.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*8.[7]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
}
for (seq=32; seq<46; seq++)
{
/*1.上上上次结果^上上次结果*/
temp1 = g_compute_base[1] ^ g_compute_base[2];
/*2.[1]^上次结果*/
temp1 = temp1 ^ g_compute_base[3];
/*3.[2]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*4.[3]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*5.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*6.[7]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
}
/*seq = 46*/
/*1.上次结果^上上上次结果*/
temp1 = g_compute_base[3] ^ g_compute_base[1];
/*2.[1]^上上次结果*/
temp1 = temp1 ^ g_compute_base[2];
/*3.[2]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*4.[3]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*5.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*6.[7]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
seq++;
/*seq = 47*/
/*1.上上次结果^上次结果*/
temp1 = g_compute_base[2] ^ g_compute_base[3];
/*2.[1]^上上上次结果*/
temp1 = temp1 ^ g_compute_base[1];
/*3.[2]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*4.[3]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*5.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*6.[7]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
seq++;
for (seq=48; seq<64; seq++)
{
/*1.上上上次结果取反*/
temp1 = ~g_compute_base[1];
/*2.[1]|上次结果*/
temp1 = temp1 | g_compute_base[3];
/*3.[2]^上上次结果*/
temp1 = temp1 ^ g_compute_base[2];
/*4.[4]+g_email_table[]*/
temp_ptr = (unsigned int *)(g_email_table + (g_compute_seq[seq] * 4));
temp1 = temp1 + *temp_ptr;
/*5.[4]+上上上上次结果+g_comput_num[]*/
temp1 = temp1 + g_compute_base[0] + g_compute_num[seq];
/*6.移位*/
left = g_displacement[seq / 16][(seq % 4) * 2];
right = g_displacement[seq / 16][(seq % 4) * 2 + 1];
temp2 = temp1;
temp1 = temp1 << left;
temp2 = temp2 >> right;
temp1 = temp1 | temp2;
/*7.[6]+上次结果*/
temp1 = temp1 + g_compute_base[3];
/*9.修改g_compute_base表*/
g_compute_base[0] = g_compute_base[1];
g_compute_base[1] = g_compute_base[2];
g_compute_base[2] = g_compute_base[3];
g_compute_base[3] = temp1;
}
/*上上上上次结果+上上上上次结果(初)*/
compute_backup[0] = g_compute_base[0] + compute_backup[0];
/*上上上次结果+上上上次结果(初)*/
compute_backup[1] = g_compute_base[1] + compute_backup[1];
/*上上次结果+上上次结果(初)*/
compute_backup[2] = g_compute_base[2] + compute_backup[2];
/*上次结果+上次结果(初)*/
compute_backup[3] = g_compute_base[3] + compute_backup[3];
/*产生计算后的结果*/
g_email_table[0] = (unsigned char)(compute_backup[0] & 0xff);
compute_backup[0] >>= 8;
g_email_table[1] = (unsigned char)(compute_backup[0] & 0xff);
compute_backup[0] >>= 8;
g_email_table[2] = (unsigned char)(compute_backup[0] & 0xff);
compute_backup[0] >>= 8;
g_email_table[3] = (unsigned char)(compute_backup[0] & 0xff);
compute_backup[0] >>= 8;
g_email_table[4] = (unsigned char)(compute_backup[3] & 0xff);
compute_backup[3] >>= 8;
g_email_table[5] = (unsigned char)(compute_backup[3] & 0xff);
compute_backup[3] >>= 8;
g_email_table[6] = (unsigned char)(compute_backup[3] & 0xff);
compute_backup[3] >>= 8;
g_email_table[7] = (unsigned char)(compute_backup[3] & 0xff);
compute_backup[3] >>= 8;
g_email_table[8] = (unsigned char)(compute_backup[2] & 0xff);
compute_backup[2] >>= 8;
g_email_table[9] = (unsigned char)(compute_backup[2] & 0xff);
compute_backup[2] >>= 8;
g_email_table[10] = (unsigned char)(compute_backup[2] & 0xff);
compute_backup[2] >>= 8;
g_email_table[11] = (unsigned char)(compute_backup[2] & 0xff);
compute_backup[2] >>= 8;
g_email_table[12] = (unsigned char)(compute_backup[1] & 0xff);
compute_backup[1] >>= 8;
g_email_table[13] = (unsigned char)(compute_backup[1] & 0xff);
compute_backup[1] >>= 8;
g_email_table[14] = (unsigned char)(compute_backup[1] & 0xff);
compute_backup[1] >>= 8;
g_email_table[15] = (unsigned char)(compute_backup[1] & 0xff);
compute_backup[1] >>= 8;
}
/*打印出计算结果,注意这个不是最后的注册码,还需要根据结果查g_index表*/
for (seq=0; seq<16; seq++)
{
printf("%x ", (unsigned char)g_email_table[seq]);
}
printf("\n");
return 0;
}
代码写的不好,希望大家给我提出宝贵意见。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课