首页
社区
课程
招聘
[讨论]第三题,抛砖引玉
发表于: 2010-10-24 12:06 7709

[讨论]第三题,抛砖引玉

2010-10-24 12:06
7709

验证过程:
1.计算注册码的格式:xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx以及字符集合法性,见如下letter数组
2.一些移位操作计算出一个20字节的HASH值
3.对输入的用户名,后面追加C盘逻辑卷的序列号以及一个字符串"Tencent",用变形的类SHA1算法计算一个HASH值
4.比较前后两个,相同则ok

能看到注册码的格式把注册码分为四部分,其中每一组8Byte计算出5个BYTE,对应于用户名的HASH值。

计算部分如下,用户名那部分的代码就不贴了,抠出来就是。

DWORD USER_HASH[5]; //这里记录的是用户名+VolumeSerialNumber+Tencent最终生成的hash

char letter[] = "ABCDEFGHJKMNPQRSTVWXYZ1234567890";
char reg_code[4][9] = {0};

void CalcReg()
{
    bool succ = false;
    BYTE* byte_USER_HASH = (BYTE*)USER_HASH;
    for(int i=0; i<4; i++)
    {
        int pos = i*5;
        succ = false;
        for(int a0=0; a0<32 && !succ; a0++)
        {
            for(int a1=0; a1<32 && !succ; a1++)
            {
                if ((((a0<<3)|(a1>>2))&0xFF) != byte_USER_HASH[pos])
                    continue;
                for(int a2=0; a2<32 && !succ; a2++)
                {
                    for(int a3=0; a3<32 && !succ; a3++)
                    {
                        if ((((a1<<6)|(a2<<1)|(a3>>4))&0xFF) != byte_USER_HASH[pos+1])
                            continue;
                        for(int a4=0; a4<32 && !succ; a4++)
                        {
                            if ((((a3<<4)|(a4>>1))&0xFF)!= byte_USER_HASH[pos+2])
                                continue;
                            for(int a5=0; a5<32 && !succ; a5++)
                            {
                                for(int a6=0; a6<32 && !succ; a6++)
                                {
                                    if ((((a4<<7)|(a5<<2)|(a6>>3))&0xFF) != byte_USER_HASH[pos+3])
                                        continue;
                                    for(int a7=0; a7<32; a7++)
                                    {
                                        if((((a6<<5)|a7)&0xFF) == byte_USER_HASH[pos+4])
                                        {
                                            reg_code[i][0] = letter[a0];
                                            reg_code[i][1] = letter[a1];
                                            reg_code[i][2] = letter[a2];
                                            reg_code[i][3] = letter[a3];
                                            reg_code[i][4] = letter[a4];
                                            reg_code[i][5] = letter[a5];
                                            reg_code[i][6] = letter[a6];
                                            reg_code[i][7] = letter[a7];
                                            succ = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 29214
活跃值: (7719)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
2
BOOL GenCodeFromDigest(char* pszCode,const BYTE* pDigest)
{
	char szCodeMap[33] ={
		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
		'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 
		'T', 'V', 'W', 'X', 'Y', 'Z', '1', '2', 
		'3', '4', '5', '6', '7', '8', '9', '0',
		'='
	};

	BYTE bufCode[EXPECTED_CODE_SIZE] = {0};

	int i=0;
	int j=0;

	if (!pszCode || !pDigest) return FALSE;

	//make sure bufCode[i]<=0x20
	for (i=0,j=0; i<32; i+=8,j+=5) {
		
		//以下并没有考虑所有可能的解
		//原则上不让bufCode有0x20出现,结果就很明朗了
		//bufCode[0]的第3位由bufCode[0]确定,bufCode[1]可以不用管这个位,以下都基于此思想

		bufCode[0+i] |= pDigest[0+j] >> 3; 
		
		bufCode[1+i] |= (pDigest[0+j] & 7) << 2;
		bufCode[1+i] |= pDigest[1+j] >> 6;
		
		bufCode[2+i] |= pDigest[1+j] >> 1;
		bufCode[2+i] &= 0x1F;

		bufCode[3+i] |= (pDigest[1+j] & 1) << 4;
		bufCode[3+i] |= pDigest[2+j] >> 4;

		bufCode[4+i] |= (pDigest[2+j] & 0x0F) << 1;
		bufCode[4+i] |= pDigest[3+j] >> 7;

		bufCode[5+i] |= pDigest[3+j] >> 2;
		bufCode[5+i] &= 0x1F;

		bufCode[6+i] |= (pDigest[3+j] & 3) << 3;
		bufCode[6+i] |= pDigest[4+j] >> 5;

		bufCode[7+i] |= pDigest[4+j] & 0x1F;
	}

	//map code string
	for (i=0,j=0; i < EXPECTED_CODE_SIZE; i++) {
		
		if ((i!=0) && ((i%8)==0)) {
			pszCode[j++] = '-';
		}

		pszCode[j++] = szCodeMap[ bufCode[i] ];
	}

	pszCode[j] = 0;

	return TRUE;
}
2010-10-24 12:09
0
雪    币: 105
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
我也来一段计算的代码
void GetCode(unsigned char p[20], char code[32])
{
	int ebp = 0;
	int ebx = 0;
	int esi = 0;
	char str[33] = "ABCDEFGHJKMNPQRSTVWXYZ1234567890";

	int flag[][2] =
	{

		{0xF8, -3},

		{0x07,  2}, //+
		{0xC0, -6},

		{0x3E, -1},

		{0x01,  4}, //+
		{0xF0, -4},

		{0x0F,  1}, //+
		{0x80, -7},

		{0x7C, -2},

		{0x03,  3}, //+
		{0xE0, -5},

		{0x1F,  0}, //+

		{0xF8, -3},

		{0x07,  2}, //+
		{0xC0, -6},

		{0x3E, -1},

		{0x01,  4}, //+
		{0xF0, -4},

		{0x0F,  1}, //+
		{0x80, -7},

		{0x7C, -2},

		{0x03,  3}, //+
		{0xE0, -5},

		{0x1F,  0}, //+

		{0xF8, -3},

		{0x07,  2}, //+
		{0xC0, -6},

		{0x3E, -1},

		{0x01,  4}, //+
		{0xF0, -4},

		{0x0F,  1}, //+
		{0x80, -7},

		{0x7C, -2},

		{0x03,  3}, //+
		{0xE0, -5},

		{0x1F,  0}, //+

		{0xF8, -3},

		{0x07,  2}, //+
		{0xC0, -6},

		{0x3E, -1},

		{0x01,  4}, //+
		{0xF0, -4},

		{0x0F,  1}, //+
		{0x80, -7},

		{0x7C, -2},

		{0x03,  3}, //+
		{0xE0, -5},

		{0x1F,  0}, //+
	};

	int t20 = 0;
	int t32 = 0;
	int da = 0;
	while (esi<20)
	{
		t20 |= flag[ebx][0];
		t32 |= flag[ebx][1]>0?(flag[ebx][0]<<flag[ebx][1]):(flag[ebx][0]>>-flag[ebx][1]);
		int t = (flag[ebx][0]&p[esi]);
		da |= flag[ebx][1]>0?(t<<flag[ebx][1]):(t>>-flag[ebx][1]);

		if (t20==0xff)
		{
			t20 = 0;
			esi++;
		}
		if (t32==0x1f)
		{
			code[ebp] = str[da];
			ebp++;
			da = 0;
			t32 = 0;
		}

		ebx++;
	}

}
2010-10-24 12:13
0
雪    币: 347
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
两位代码都不错啊,学习!
2010-10-24 12:57
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
5

谁抠个name计算的code来,太多了

膜拜>ls
2010-10-24 13:04
0
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
完全扣出来的代码,虽然不知道它在干什么
char * SHA(char *UserName, char *Key ,int len)
{

	char wap[0x13C]={0};
	char *pwap=wap;
    //预处理 补齐数据
    *(BYTE*)(UserName+len)=0x80;
	if(len<0x20)
	{
		*(BYTE*)(UserName+0x3F)=8*len;
	}
	else
	{
		*(BYTE*)(UserName+0x3F)=8*len%0x20;
		*(BYTE*)(UserName+0x3E)=len/0x20;
	}

	//改变字符串的字节序
	_asm
	{
		xor    ecx, ecx;
		mov    esi, UserName;
		mov    edi, pwap;
lab1:
		mov    eax,dword ptr [esi+ecx*4];
        bswap  eax;
		mov    dword ptr [edi+ecx*4], eax;
		add    ecx, 1;
		cmp    ecx, 0x10;
		jl     short lab1;
	}

	//生成表

	_asm
	{
		 mov     edx,0x40;
		 mov     eax,pwap;
		 add     eax,8;
lab2:
		 mov    ecx,dword ptr [eax+0x2C];
		 xor    ecx,dword ptr [eax+0x18];
		 add    eax,4;
		 xor    ecx,dword ptr [eax-0xC];
		 xor    ecx,dword ptr [eax-4];
		 rol    ecx,1;
		 sub    edx,1;
		 mov    dword ptr [eax+0x34],ecx;
		 jnz    short lab2;
	}

	//SHA

	_asm
	{
		push    ebp;
		mov     eax,Key;
		mov     edx,dword ptr [eax+4];
		mov     ebx,dword ptr [eax+0xC];
		mov     esi,dword ptr [eax+8];
		mov     edi,dword ptr [eax];
		mov     eax,dword ptr [eax+0x10];
		push    eax;
		push    edi;
		xor     eax,eax;

lab4:
		rol     edi,5;
		mov     ebp,esi;
		and     ebp,edx;
		mov     ecx,edx;
		not     ecx;
		and     ecx,ebx;
		xor     ecx,ebp;
		add     edi,ecx;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     edi,dword ptr [wap+eax*4];
		pop     ebp;

		mov     ecx,dword ptr [esp+4];
		lea     ecx,dword ptr [edi+ecx+0x5A827999];
		mov     edi,dword ptr [esp];
		mov     dword ptr [esp+4],ebx;
		ror     edx,2;
		mov     dword ptr [esp],ecx;
		rol     ecx,5;
		mov     ebx,edi;
		not     ebx;
		and     ebx,esi;
		mov     ebp,edx;
		and     ebp,edi;
		xor     ebx,ebp;
		add     ecx,ebx;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     ecx,dword ptr [wap+eax*4+4];
		pop     ebp;

		mov     ebx,dword ptr [esp+4];
		lea     ecx,dword ptr [ecx+ebx+0x5A827999];
		ror     edi,2;
		mov     dword ptr [esp+4],esi;
		mov     ebx,edx;
		mov     edx,dword ptr [esp];
		mov     dword ptr [esp],ecx;
		rol     ecx,5;
		mov     ebp,edi;
		and     ebp,edx;
		mov     esi,edx;
		not     esi;
		and     esi,ebx;
		xor     esi,ebp;
		add     ecx,esi;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     ecx,dword ptr [wap+eax*4+8];
		pop     ebp;
		mov     esi,dword ptr [esp+4];
		lea     ecx,dword ptr [ecx+esi+0x5A827999];
		mov     esi,dword ptr [esp];
		ror     edx,2;
		mov     dword ptr [esp+4],ebx;
		mov     dword ptr [esp],ecx;
		rol     ecx,5;
		mov     ebx,esi;
		not     ebx;
		and     ebx,edi;
		mov     ebp,edx;
		and     ebp,esi;
		xor     ebx,ebp;
		add     ecx,ebx;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     ecx,dword ptr [wap+eax*4+0xC];
		pop     ebp;

		mov     ebx,dword ptr [esp+4];
		lea     ecx,dword ptr [ecx+ebx+0x5A827999];
		ror     esi,2;
		mov     dword ptr [esp+4],edi;
		mov     ebx,esi;
		mov     esi,dword ptr [esp];
		mov     edi,esi;
		not     edi;
		and     edi,edx;
		mov     dword ptr [esp],ecx;
		rol     ecx,5;
		mov     ebp,ebx;
		and     ebp,esi;
		xor     edi,ebp;
		add     ecx,edi;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     ecx,dword ptr [wap+eax*4+0x10];
		pop     ebp;

		mov     edi,dword ptr [esp+4];
		lea     ecx,dword ptr [ecx+edi+0x5A827999];
		mov     ebp,edx;
		mov     edx,dword ptr [esp];
		mov     edi,ecx;
		add     eax,5;
		ror     esi,2;
		mov     dword ptr [esp+4],ebp;
		mov     dword ptr [esp],edi;
		cmp     eax,0x14;
		jl      lab4;

		cmp     eax,0x28;
		jge     short lab5;
lab6:
		mov      ebp,ebx;
		xor      ebp,esi;
		xor      ebp,edx;
		rol      ecx,5;
		add      ecx,ebp;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     ecx,dword ptr [wap+eax*4];
		pop     ebp;

		mov     ebp,dword ptr [esp+4];
		lea     ecx,dword ptr [ecx+ebp+0x6ED9EBA1];
		ror     edx,2;
		mov     ebp,ebx;
		mov     ebx,esi;
		add     eax,1;
		cmp     eax,0x28;
		mov     esi,edx;
		mov     edx,edi;
		mov     dword ptr [esp+4],ebp;
		mov     edi,ecx;
		jl      short lab6;
		mov     dword ptr [esp],ecx;
lab5:
		cmp     eax,0x3C;
		jge     short lab7;
lab8:
		mov     edi,esi;
		xor     edi,edx;
		and     edi,ebx;
		mov     ebp,esi;
		and     ebp,edx;
		rol     ecx,5;
		add     ecx,dword ptr [esp+4];
		xor     edi,ebp;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     edi,dword ptr [wap+eax*4];
		pop     ebp;

		ror     edx,2;
		mov     ebp,ebx;
		mov     ebx,esi;
		add     eax,1;
		cmp     eax,0x3C;
		lea     ecx,dword ptr [edi+ecx+0x8F1BBCDC];
		mov     esi,edx;
		mov     edx,dword ptr [esp];
		mov     dword ptr [esp+4],ebp;
		mov     dword ptr [esp],ecx;
		jl      short lab8;
lab7:
		cmp     eax,0x50;
		jge     short lab9;
lab10:
		mov     edi,ebx;
		xor     edi,esi;
		rol     ecx,5;
		xor     edi,edx;

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		add     edi,dword ptr [wap+eax*4];
		pop     ebp;

		add     ecx,ebp;
		ror     edx,2;
		mov     ebp,ebx;
		mov     ebx,esi;
		add     eax,1;
		cmp     eax,0x50;
		lea     ecx,dword ptr [edi+ecx+0xCA62C1D6];
		mov     esi,edx;
		mov     edx,dword ptr [esp];
		mov     dword ptr [esp],ecx;
		jl      short lab10;
lab9:

		push    ebp;
		mov     ebp,dword ptr [esp+0xC];
		mov     eax,Key;
		pop     ebp;

		mov     edi,dword ptr [eax];
		add     edi,ecx;
		mov     ecx,dword ptr [eax+4];
		add     ecx,edx;
		mov     dword ptr [eax+4],ecx;
		mov     ecx,dword ptr [eax+8];
		add     ecx,esi;
		mov     dword ptr [eax+8],ecx;
		mov     ecx,dword ptr [eax+0xC];
		add     ecx,ebx;
		mov     dword ptr [eax],edi;
		mov     dword ptr [eax+0xC],ecx;
		mov     ecx,dword ptr [eax+0x10];
		add     ecx,ebp;
		mov     dword ptr [eax+0x10],ecx;

		pop     edi;
		pop     eax;
		pop     ebp;
	}

	//翻转字节序

	_asm
	{
		xor    ecx, ecx;
		mov    esi, Key;
lab11:
		mov    eax,dword ptr [esi+ecx*4];
        bswap  eax;
		mov    dword ptr [esi+ecx*4], eax;
		add    ecx, 1;
		cmp    ecx, 5;
		jl     short lab11;
	}
	return Key;

}
2010-10-24 13:19
0
雪    币: 105
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
我也一段Name的计算代码
int sub_4078E0(char* a0)
{
	char *p = a0;
	while (*p)
	{
		p++; 
		p++;
		if (*(p-1) == '\0')
		{
			return p-a0-1;
		}

		p++;
		if (*(p-1) == '\0')
		{
			return p-a0-1;
		}

		p++;
		if (*(p-1) == '\0')
		{
			return p-a0-1;
		}
	}

	return p+1-a0-1;
}

char *memcpy_r(char* a0, char* a4, int a8)
{
	char *p = a0;
	while (a8>0)
	{
		*p = *(a4-a0+p);
		p++;
		a8--;
	}
	
	return a0;
}

int bswap(int n)
{
	_asm {
		mov eax, n
		bswap eax
		mov n, eax
	}
	return n;
}


void my_sha1_compile(sha1_ctx ctx[1])
{
	sha1_compile(ctx);
	return;

}

void my_sha1_hash(sha1_ctx ecx[1], char* a0, int a4)
{
	int eax = ((ecx->count[0]>>3) & 0x3f);
	ecx->count[0] += a4*8;
	if (ecx->count[0] < (sha1_32t)a4*8)
	{
		ecx->count[1]++;
	}
	ecx->count[1] += (a4>>29);
	if (a4 < (0x40 - eax))
	{
		memcpy_r((char*)ecx->wbuf+eax, a0, a4);
		return;
	}

	memcpy_r((char*)ecx->wbuf+eax, a0, (0x40 - eax));
	my_sha1_compile(ecx);
	int va4 = (0x40 - eax);
	int ebp = va4+0x3f;
	char* ebx = (char*)ecx->wbuf+0x100;

	if (ebp < a4)
	{
		do {
			my_sha1_compile(ecx);
			va4 += 0x40;
			ebp += 0x40;
			ebx += 0x100;
		} while(ebp < a4);
	}

	memcpy_r((char*)ecx->wbuf, a0+va4, a4-va4);
	return;

}

void my_sha1_end(sha1_ctx ecx[1], char* a0)
{
	char v1c[8] = {0};
	*(int*)(v1c+4) = ecx->count[0];
	*(int*)(v1c) = ecx->count[1];

	int ecx1;
	for (ecx1=0; ecx1<2; ecx1++)
	{
		*(int*)(v1c+ecx1*4) = bswap(*(int*)(v1c+ecx1*4));
	}

	sha1_32t    i = (sha1_32t)((ecx->count[0]>>3) & 0x3f);
	static char s_byte_40CD50[64] = {'\x80'};
	my_sha1_hash(ecx, s_byte_40CD50, (i<56?56-i:120-56));
	my_sha1_hash(ecx, v1c, 8);
	char v14[20];
	for (ecx1=0; ecx1<5; ecx1++)
	{
		*(int*)(v14+ecx1*4) = bswap(ecx->hash[ecx1]);
	}
	memcpy_r(a0, v14, 20);
	memset(ecx->hash, 0, 20);
	return;
}

bool sub_401000(int ecx, char *edi, char *a0)
{
	char v30[32+12] = {0};

	if (edi == NULL || a0 == NULL)
	{
		return false;
	}

	DWORD dwVolumeSerialNumber;
	GetVolumeInformationA("C:\\", NULL, 0, &dwVolumeSerialNumber, NULL,NULL, NULL, 0);
	memcpy_r(v30, a0, ecx);
	*(DWORD*)(v30+ecx) = dwVolumeSerialNumber;
	memcpy_r(v30+ecx+4, "Tencent", sub_4078E0("Tencent"));
	sha1_ctx v8c;
	sha1_begin(&v8c);
	v8c.hash[0] = 0xB1CAB1CA;
	v8c.hash[1] = 0xCCBFCCBF;
	v8c.hash[2] = 0xBFB2D6BE;
	v8c.hash[3] = 0xF8C7D8B5;
	v8c.hash[4] = 0xEEC7BCCD;
	my_sha1_hash(&v8c, v30, ecx+11);
	my_sha1_end(&v8c, edi);
	return true;
}



sha1系列函数的代码,到网上搜吧
2010-10-24 13:33
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
8
if(len<0x20)
  {
    *(BYTE*)(UserName+0x3F)=8*len;
  }
  else
  {
    *(BYTE*)(UserName+0x3F)=8*len%0x20;
    *(BYTE*)(UserName+0x3E)=len/0x20;
  }

应该为"]*(BYTE*)(UserName+0x3F)=(8*len)%(8*0x20);
2010-10-24 22:13
0
游客
登录 | 注册 方可回帖
返回
//