新CrackMe160之154 - cpp_crackme1

OD载入程序, 搜索界面看到了一些不太像关键词的东东,, 有个Error看着像,点开看是一个弹框标题,, "Edit"对应的是创建窗体控件"CreateWindowExA", 感觉越下越接近算法区域了,
继续点一堆的符号":&:&*&...",每个都双击定位到左侧观察, 发现了关键代码处004016C6 GetWindowTextA, 这个是获取文本框的值, 下面还有关键对比, 所以就在这里下个断点
点"CHECK"按钮后,果然能在这里停下来,看来按钮入口找对了,输入超过1位的用户名, 代码就跳过失败来到00401739的算法区了
一路F8执行到004018BE处,获取系列号,判断长度要大于等于24位(强制修改寄存器S的值,双击修改)让它先满足条件,继续执行到00401A1C处,
发现这里需要对系列号后4位(20~23)进行强校验, 结果必须为0141,所以后4位是固定的,前几位也是固定的"ULT"
现在重头开始详细分析算法:(用户名1位以上, 系列号24位)
注册机:

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

int ror(unsigned int num, unsigned char i){
	return (num >> i) | (num << (sizeof(int) * 8 - i));
}

int main() {
	int i, len; 
	char str[] = {0x16,0x0F,0x17,0x11,0x02,0x10,0x0C,0x16,0x0D,0x07,0x00,0x11,0x02,0x00,0x08,0x0E,0x06,0x52,0x16,0x0F,0x17,0x11,0x02,0x10,0x0C,0x16,0x0D,0x07,0x00,0x11,0};
	char user[30] = {0};
	char code[60] = {0};
	int rlt[30] = {0}; 
	char tmp;
	unsigned int eax = 0;
	printf("用户名: "); scanf("%s", user); getchar();
	len = strlen(user);
	for(i=0; i<len; i++){
		code[i] = user[i] ^ (i+1);
	}
	for(; i<30; i++){
		code[i] = (((str[i] ^0x5A) + i) % 0x39) + 0x41;
	} 
	for(i=0; i<30; i+=2){
		code[30+i] = code[i+1]; //每2位换位 
		code[30+i+1] = code[i];
		eax = (eax & 0xFFFFFF00) + code[30+i];
		eax = ror(eax, 1);
		code[30+i] = eax & 0xFF;
		eax = (eax & 0xFFFFFF00) + code[30+i+1];
		eax = ror(eax, 1);
		code[30+i+1] = eax & 0xFF;
		rlt[i] = code[i] * code[30+i] + (code[i] ^ code[30+i]); //两两运算得到一个值 
		rlt[i+1] = code[i+1] * code[30+i+1] + (code[i+1] ^ code[30+i+1]);
	}
	for(i=0; i<15; i++){ //将30个数分两半,再分别加对应位置加起来 
		rlt[i] += rlt[15+i];
		code[i] = (rlt[i] & 0xFF) % 9 + 0x30; //将最终的15个值模9转数字字符 
	}
	code[i] = 0;
	printf("系列号: ULT-%s-0141\n", code);
	getchar();
	return 0;
}

运行示例:
用户名: CPP_Crackme1
系列号: ULT-651813322431375-0141

 
 
本节高手录制的视频,点击前往查看

 
 
 
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载

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

posted @ 2024-12-30 14:36  hankerstudio  阅读(10)  评论(0)    收藏  举报