首页
社区
课程
招聘
[原创][原创]腾讯第一阶段第三题keygenme
发表于: 2010-10-24 11:26 5206

[原创][原创]腾讯第一阶段第三题keygenme

2010-10-24 11:26
5206
首先简单说下验证过程
用户名+硬盘序列号+Tencent 经过变形sha1,得到20位校验值

注册码必须是这里面的数字ABCDEFGHJKMNPQRSTVWXYZ1234567890,因为后面要查这个表。

注册码必须是35位,排除中间的3个“-”,实际参与是32位

校验的过程比较复杂,没完全搞懂
void genuserhash(char *RegCode)
{
  int result;
  int i = 0;
  int n = 0;
  int a3 = 0;
  memset(comparebuf,0,32);
  do
  {
    if(a3 %8 == 0) printf("\n\n");
    result = find_value(RegCode[a3]);
    if ( (unsigned int)n > 3 )
    {
      n = (n - 3) & 7;
      comparebuf[i] += result >> n;
      printf("buf[%d][a%d]=right(%d)",i,a3,n);
      if(a3%2) printf("\n");
      ++i;
    }
    else
    {
      n = (n - 3) & 7;
      if ( !n )
      {
        comparebuf[i++] += result;
        printf("buf[%d][a%d]=noshift(%d)",i,a3,n);
        goto LABEL_6;
      }
    }
    result <<= 8 - n;
    comparebuf[i] += result;
    printf("buf[%d][a%d]=left(8-%d)",i,a3,n);
LABEL_6:
    ++a3;
  }
  while ( a3 < 0x20 );
}
通过研究这个过程找出一个规律,他的32位注册码移位的过程中,每8位移动的位数和方向是一定的,只是重复了4次。
设每段注码为a0,a1,a2,a3,a4,a5,a6,a7,a8
设hash值为v1,v2,v3,v4
可列方程组
                                           v0 = (a0<<3) + (a1>>2);
             v1 = (a1<<6)+(a2<<1)+(a3 >>4);
             v2 = (a3<<4) + (a4 >>1);
             v3 = (a4<<7) +(a5<<2) + (a6>>3);
             v4 = (a6<<5) +a7;
如何解方程?
a0~a8,范围为0~0x1f,现在已知v1,v2,v3,v4,求这8个未知数,我只会穷举。如果穷举6个一是2^30,太长了,我拆成两部分分别穷举,时间不算长。

贴出穷举第一段的代码

void reverse1(char* RegCode,char* table)
{
  int a0,a1,a2,a3,a4,a5,a6,a7;
  unsigned char v0,v1,v2,v3,v4;
  //穷举前4位
  for(a0 = 0; a0< 0x20;a0++)
  {
     for(a1 = 0;a1< 0x20 ; a1++)
     {
       for(a2 = 0;a2< 0x20 ; a2++)
       {
         for(a3 = 0;a3< 0x20 ; a3++)
         {
           for(a4 = 0;a4< 0x20 ; a4++)
           {
             v0 = (a0<<3) + (a1>>2);
             v1 = (a1<<6)+(a2<<1)+(a3 >>4);
             v2 = (a3<<4) + (a4 >>1);
             if(v0 ==sha1_hashvalue[0] && v1 == sha1_hashvalue[1] && v2 == sha1_hashvalue[2])
             {
               //printf("\n%c%c%c%c\n", rfind_value(a0),rfind_value(a1),rfind_value(a2),rfind_value(a3));
               RegCode[0] = rfind_value(table,a0);
               RegCode[1] = rfind_value(table,a1);
               RegCode[2] = rfind_value(table,a2);
               RegCode[3] = rfind_value(table,a3);
               goto  next;
             }
           }
         }
       }
     }
  }
  //继续枚举后两位
next:
  for(; a0< 0x20;a0++)
  {
    for(;a1< 0x20 ; a1++)
    {
      for(;a2< 0x20 ; a2++)
      {
        for(;a3< 0x20 ; a3++)
        {
          for(a4 = 0;a4< 0x20 ; a4++)
          {
            for(a5 = 0;a5< 0x20 ; a5++)
            {
              for(a6 = 0;a6< 0x20 ; a6++)
              {
                for(a7 = 0;a7< 0x20 ; a7++)
                {
                  v2 = (a3<<4) + (a4>>1);
                  v3 = (a4<<7) +(a5<<2) + (a6>>3);
                  v4 = (a6<<5) +a7;
                  if(v2 ==sha1_hashvalue[2] && v3 == sha1_hashvalue[3] && v4 == sha1_hashvalue[4])
                  {
                    //printf("\n%c%c%c%c\n", rfind_value(a4),rfind_value(a5),rfind_value(a6),rfind_value(a7));
                    
                    RegCode[4] = rfind_value(table,a4);
                    RegCode[5] = rfind_value(table,a5);
                    RegCode[6] = rfind_value(table,a6);
                    RegCode[7] = rfind_value(table,a7);
                    
                    //goto ok;
                  }
                }
              }
            }

          }
        }
      }
     }
  }
//ok:
      RegCode[8] = '-';
}
具体代码见注册机源码。

组后给出两组序列号
Tencent
12345678
5X065N0K-2H28Y02Q-SRCGEHZ1-BQFGJ7EG

Tencent
87654321
JECSDT5X-D2ARQ0VN-83Q7AK0F-Q6CJ92GZ

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 3686
活跃值: (1036)
能力值: (RANK:760 )
在线值:
发帖
回帖
粉丝
2
经过评委会审定,你本题的得分是:100分
2010-10-27 11:00
0
游客
登录 | 注册 方可回帖
返回
//