新手破解练习Crackme160之118 - KeyGenMe

这个程序有两个验证, 1. 用户名和系列号, 2. 注册码, 同样也是98的程序
98下OD载入程序(我98下也只有这个工具了, 其它的没去验证能不能用, 这个工具还是很牛的, 从16位到64位的系统都能用), 程序有错误提示信息, 我们用智能搜索查看, 没有相关信息, 我们用暂停法, F9运行程序, 点check(1), 弹出sorry框, 这时点暂停键可以看到错误信息是内存中调用的(00401BED处), 98下好像不支持内存断点(应该是兼容问题吧), 没办法了, 不能找到关键断点, 只能直接大概看一下代码了~ 重新加载程序, F8单步运行, 在程序开头下面不远处看到了错误提示信息(00401064) Please try Name/Serial combination first意思就是要先破解第一个才能继续第二个, 那这个应该是第二个按钮的入口吧~ 不管先下个断点(00401053)~ F9运行按第一个按钮确实没停下来, 第二个按钮停下了, 说明第二个按钮事件找到了~ 我们继续找第一个事件就在下面的几行看到了"Name"的标识(0040109F) 也下个断点~ 点第一个按钮, 果然在这里停下了~ 这样两个事件都找到了, 接下来就正确破解了, 分析各自算法~
算法1:
1). 004010BC Name必须4位以上, 004010F2 Serial不能为空
2). 0040111B ~ 00401129 将用户名每一位值乘长度加起来~
3). 00401135 ~ 00401142 再将用户名每一位值异或长度再累加起来~
4). 00401145 再把2). 3). 结果加起来
5). 0040115A ~ 00401179 将用户名每一位分别与每一位相乘加起来~ 再与上面结果加起来~
6). 00401193 ~ 004011B5 将上面的结果每一位处理到小于9的数倒序存到00401C60处
7). 004011CD 对比结果长度与Serial长度是否相等~
8). 004011EE ~ 004011FC 比较Serial与计算值是否相等~
算法分析完成, 开始写注册机: keygen1.c

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

int main() {
	int lenn, codei = 0;
	unsigned long rlt = 0; 
	char name[21] = {0};
	char code[21] = {0};
	printf("用户名: "); scanf("%s", name);
	lenn = strlen(name);
	if(lenn < 4){
		printf("用户名4位以上!");
		return 0;
	}
	
	for(int i=0; i<lenn; i++){
		rlt += name[i] * lenn + (name[i] ^ lenn);
	}
	
	for(int i=0; i<lenn; i++){
		for(int j=0; j<lenn; j++){
			rlt += name[i] * name[j];
		}
	}
	while (rlt > 0){
		lenn = rlt & 0xF; //取出最后一位
		rlt = rlt >> 4;
		while(lenn>9) lenn -= 4;
		code[codei] = lenn + 0x30;
		codei+=1;
	}
	printf("序列号: %s\n", code);
	
	getchar();getchar();
	return 0;
}

算法2:
1). 0040125D 取用户名前4位加上"-"
2). 加上系列号再加上"-"
3). 系列号每一位乘以0x2D, 结果每一位处理到小于9, 倒序加到上面结果, 再加"-"
4). 004012D5 最后加上一个"X", 结果与注册码比较

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

int main() {
	int lenn, codei = 0;
	unsigned long rlt = 0; 
	char name[51] = {0};
	char code[21] = {0};
	printf("用户名: "); scanf("%s", name);
	lenn = strlen(name);
	if(lenn < 4){
		printf("用户名4位以上!");
		return 0;
	}
	
	for(int i=0; i<lenn; i++){
		rlt += name[i] * lenn + (name[i] ^ lenn);
	}
	
	for(int i=0; i<lenn; i++){
		for(int j=0; j<lenn; j++){
			rlt += name[i] * name[j];
		}
	}
	while (rlt > 0){
		lenn = rlt & 0xF; //取出最后一位
		rlt = rlt >> 4;
		while(lenn>9) lenn -= 4;
		code[codei] = lenn + 0x30;
		codei+=1;
	}
	printf("序列号: %s\n", code);
	
	rlt = 0;
	name[4] = '-'; //将注册码存于name中
	lenn = strlen(code);
	for(int i=0; i<lenn; i++){
		rlt += code[i] * 0x2D;
		name[5+i] = code[i];
	}
	name[5+lenn] = '-';
	codei = 0;
	for(int i=0; i<21; i++) code[i] = 0;
	while (rlt > 0){
		lenn = rlt & 0xF; //取出最后一位
		rlt = rlt >> 4;
		while(lenn>9) lenn -= 4;
		code[codei] = lenn + 0x30; //倒序存 
		codei+=1;
	}
	lenn = codei;
	codei = strlen(name);
	for(int i=0; i<lenn; i++){
		name[codei] = code[lenn-1-i]; //再倒序取 
		codei += 1; 
	}
	name[codei] = '-';
	name[codei+1] = 'X';
	
	printf("注册码: %s\n", name);
	
	getchar();getchar();
	return 0;
}

运行示例:
用户名: abcde
序列号: 67883
注册码: abcd-67883-2790-X

 
 
 
这是160个软件part1
这是160个软件part2

1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载

新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~

下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~
OD界面布局

posted @ 2024-07-22 16:09  hankerstudio  阅读(40)  评论(0)    收藏  举报