新CrackMe160之138 - bytel0rds_crackme_n1

OD载入程序, 搜索界面查看到成功关键词定位到00403BDF,上面算法开始处00403BA1下好断点
跟踪可知, 00403BC5和00403BD4两个方法都是关键算法
00403BC5:

  1. 0040383F ~ 00403892 用户名累加转2进制,并计算2进制中1的个数为num1
  2. 004038D8, 00403922, 0040396C 注册码是13位的格式为: 123-456-789-A
  3. 004038A0 ~ 00403995 注册码通过算法累加结果为sum, 这个数在500以内 (999-999-999-Y => 487)
  4. 004039C0 ~ 004039D6 sum = sum ^ num1, 这个数会非常大,所以需要控制一下num1,最好是6以内(500^6 = 1.5625e18),再大就超过长整形了
  5. 004039EB ~ 00403A53 系列号为全数字,并转为数字
  6. 00403A68 rlt = sum % 系列号
  7. 00403773 ~ 00403787 rlt / 2 余1

注册机:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main() {
	srand((unsigned int)time(NULL));
	int rlt[15] = {3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; //5位以内的一直除以2余数都是1的数 
	char user[6] = {0};
	printf("用户名: ");
	scanf("%s", user); getchar();
	int i, j, s, len = strlen(user), len1 = 0, sum = 0;
	if(len != 5){
		printf("用户名只能是5位");
		getchar(); return 0;
	}
	for(i=0; i<len; i++){ sum += user[i]; }
	while(sum > 0){
		j = sum % 2;
		sum = sum / 2; 
		if(j == 1) len1++; 
	}
	if(len1 > 6){
		printf("用户名累加数转二进制后1的个数(%d)太多了,导致后面乘方数溢出无法运算,换一个用户名吧^_^\n", len1);
		getchar(); return 0;
	}
	char code[14] = {0};
	code[3] = '-';
	code[7] = '-';
	code[11]= '-';
	code[0] = rand() % 9 + 0x31; // 1 ~ 9
	code[1] = rand() % 9 + 0x31;
	code[2] = rand() % 9 + 0x31;
	code[4] = rand() % 9 + 0x31;
	code[5] = rand() % 9 + 0x31;
	code[6] = rand() % 9 + 0x31;
	code[8] = rand() % 9 + 0x31;
	code[9] = rand() % 9 + 0x31;
	code[10]= rand() % 9 + 0x31;
	code[12]= rand() % 26 + 'A'; // A ~ Z
	printf("注册码: %s\n", code);
	
	sum = 0;
	int x = 1; 
	sum += (code[0] - 0x30) * (0xB - x - 0);
	sum += (code[1] - 0x30) * (0xB - x - 1);
	sum += (code[2] - 0x30) * (0xB - x - 2);
	x = 5;
	sum += (code[4] - 0x30) * (0xC - x - 0);
	sum += (code[5] - 0x30) * (0xC - x - 1);
	sum += (code[6] - 0x30) * (0xC - x - 2);
	x = 9;
	sum += (code[8] - 0x30) * (0xD - x - 0);
	sum += (code[9] - 0x30) * (0xD - x - 1);
	sum += (code[10]- 0x30) * (0xD - x - 2);
	
	sum += (code[12] & 1);
	long double sum1 = 1, sum2;
	sum1 = powl(sum, len1);
	
	for(i=0; i<15; i++){
		s = 0;
		for(j=10000; j<100000; j++){
			sum2 = sum1 - rlt[i];
			if(fmod(sum2, j) == 0){
				s = 1;
				break;
			}
		}
		if(s == 1) break;
	}
	if(s == 1) printf("系列号: %d\n", j);
	else printf("无符合的系列号, 请重新输入用户名");
	
	getchar(); return 0;
}

运行示例:
用户名: crack
注册码: 493-143-287-L
系列号: 18722

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

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

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

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