首先简单说下验证过程
用户名+硬盘序列号+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
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)