首页
社区
课程
招聘
[原创]菜鸟写KEYGEN
发表于: 2008-3-30 01:19 4178

[原创]菜鸟写KEYGEN

2008-3-30 01:19
4178
一直没敢踏入写KEYGEN的门槛,原先一直停留在PATCH的层次,前几天突然想练练,于是开始找CM下手.第一个CM是不知名的某虾写的,有点简单,发了也没意思,第二个是去年金山逆向分析挑战赛的第一题,搞了总计6,7个小时吧,总算是折腾出来了,然后深感自己功力之薄弱,哎...
不过正如KANXUE说的,逆向分析,破解这事,有它的乐趣,能满足人的好奇心里...呵呵...
直接贴代码了,代码里包括了CM的验证流程和KEYGEN的计算流程,写的非常烂,从它能正常计算KEY开始我就没改过,呵呵,算号过程应该可以更优化.

#include <stdio.h>
#include <string.h>
#include <memory.h>


char pre_state[10] = {0};
char fin_state[10] = {0};
char key[0x1000] = {0};
char tmp_key[0x1000] = {0};
int key_len = 0;
int tmp_key_len = 0;


int get_name_hash(char* name)
{
	size_t name_len = strlen(name);
	int name_hash = 0x13572468;

	int tmp_1 = 0;
	int tmp_2 = 0;

	for (size_t i = 0; i < name_len; i++)
	{
		tmp_1 = (name[i] + name_hash)*0x3721273 + 0x24681357;
		tmp_2 = tmp_1;
		name_hash = (tmp_2 << 0x19) | (tmp_1 >> 7);
	}

	return name_hash;
}


void init_state(int name_hash)
{
	__asm
	{
		mov		edi, 1
		mov		ebx, 1
lable1:
		mov     eax, name_hash
		mov     ecx, edi
		shr     eax, cl
		and     al, bl
		mov     pre_state[edi], al
		inc     edi
		cmp     edi, 9
		jl      lable1
	}
	pre_state[9] = 1;
}


int get_edx(int idx, int name_hash)
{
	int the_edx = 0;

	__asm
	{
		mov     eax, idx
		push    0x1F
		cdq
		pop     ecx
		idiv    ecx
		mov     eax, name_hash
		push    0x0A
		mov     ecx, edx
		xor     edx, edx
		shr     eax, cl
		pop     ecx
		div     ecx

		mov		the_edx, edx
	}

	return the_edx;
}


int check_key(int name_hash)
{
	int the_edx;

	for (int i = 0; i < key_len; i++)
	{
		the_edx = get_edx(i, name_hash);
		the_edx = the_edx + key[i] - 0x30;
		the_edx = the_edx % 10;

		if (the_edx == 1)
		{
			pre_state[the_edx] ^= 1;
		}
		else
		{
			if (pre_state[the_edx - 1] != 1)
			{
				return 0;
			}

			if (the_edx < 3)
			{
				pre_state[the_edx] ^= 1;
			}
			else
			{
				for (int j = 1; j <= the_edx - 2; j++)
				{
					if (pre_state[j] == 1)
					{
						return 0;
					}
				}
				pre_state[the_edx] ^= 1;
			}
		}
	}

	for (int i = 1; i < 10; i++)
	{
		if (pre_state[i] == 1)
		{
			return 0;
		}
	}

	return 1;
}


void recursion_compute(char* state, int idx, int flag)
{
	if (idx == 1)
	{
		if (state[1] != flag)
		{
			state[1] ^= 1;
			tmp_key[tmp_key_len] = 1;
			tmp_key_len++;
		}
	}
	else if (idx == 2)
	{
		if (state[2] != flag)
		{
			recursion_compute(state, 1, 1);
			state[2] ^= 1;
			tmp_key[tmp_key_len] = 2;
			tmp_key_len++;
			recursion_compute(state, 1, 0);
		}
	}
	else
	{
		if (state[idx] != flag)
		{
			for (int j = idx - 2; j >= 1; j--)
			{
				recursion_compute(state, j, 0);
			}

			recursion_compute(state, idx - 1, 1);

			state[idx] ^= 1;
			tmp_key[tmp_key_len] = idx;
			tmp_key_len++;

			recursion_compute(state, idx - 1, 0);
		}
	}
}


void get_key(int name_hash)
{
	recursion_compute(fin_state, 9, 0);

	int the_edx;

	for (int i = 0; i < tmp_key_len; i++)
	{
		the_edx = get_edx(i, name_hash);

		tmp_key[i] += 10;
		tmp_key[i] -= the_edx;
		tmp_key[i] %= 10;

		key[i] = tmp_key[i] + '0';
	}

	key_len = tmp_key_len;
}


int main()
{
	int name_hash = get_name_hash("abcdeabcdeabcd");

	init_state(name_hash);

	memcpy(fin_state, pre_state, 10);

	get_key(name_hash);

	printf("%s\n", key);

	int check_result = check_key(name_hash);

	if (check_result == 1)
	{
		printf("check ok\n");
	}
	else
	{
		printf("check fail\n");
	}

	return 1;
}


代码冗长不优美,恩,各方面功力还有待大大提高...
过几天再弄一个KEYGEN,再发,希望届时能再有些须提高.

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

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
强人啊,支持
2008-3-30 01:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ltr
3
学习一下...
2008-3-30 16:48
0
雪    币: 47147
活跃值: (20380)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
下次来点分析过程,就可得精华了。;)
2008-3-30 16:59
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢KANXUE~呵呵~下周尽量找时间再做一个~
2008-3-30 17:39
0
雪    币: 191
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
慕名前来瞻仰。
2008-4-2 16:26
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
呵呵 你已经不是菜鸟了
2008-4-2 17:06
0
游客
登录 | 注册 方可回帖
返回
//