新手破解练习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
1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号