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;
}

代码写的不好,希望大家给我提出宝贵意见。

  • 标 题: 答复
  • 作 者:cnbragon
  • 时 间:2005-02-14 23:30

 
这是MD5