新手破解练习Crackme160之007 - aLoNg3x.2

暴力破解:

  1. DarkDe分析
    CancellaClick 00442B98 (试了一下这个应该只有清0的作用)
    AboutClcik 00442CC8
    RegisterzClick 00442F28
    AgainClick 004430BC (这个是界面上没看到的隐藏按钮事件)
    以上4处都先打上断点

  2. 什么都不想输, 直接点注册按钮, 进入00442F28这个断点, F8向下执行, 遇到第一个关键跳00442F64, 改为 jmp 00442FC2 直接跳转到成功分支, 成功干掉注册按钮, 保存~

  3. 上一步注册按钮成功隐藏了, 但又新显示出一个重试按钮, 好吧, 我们还需努力~
    进入断点004430BC后发现跟注册按钮的写法完全一样, 接下来就同样操作, 第一个关键跳004430F6改为 jmp 0044315B 到成功分支, 保存测试完全搞定~

正常破解:
ctrl+F2或菜单上操作重新运行程序, 输入用户名abc, 注册码123, 点击注册, 断点处停下(上面4个断点还在), F8单步跟踪分析算法:
1). 00442F59处, 将注册码转16进制, 123=0x7B
2). 00442FB9处, 是用户名验证算法, 继续进入分析
3). 004429D7处, 判断用户长度是否<=4, 所以我们上面输入的abc不符合要求, 我们换成abcde与12345, 重来一遍, 12345=0x3039
4). 00442A03处, 循环计算ebx += user[0] * user[len-1] * edi
5). 下面便是一堆运算这里不再列出, 看具体代码
6). 然后比较ebx 与 code(0x3039), 即ebx就是答案了
从上面上步骤分析可知, 其中还有个未知数edi, 具体分析得知, 他来自方法入参eax, eax又来自内存地址[0x445830], 经调试, 每次这个值都为0, 那我们就需要查什么时候这个值才会变, 于是我们右键查找所有常量, 查到的结果有10个之多, 其中有8个会对其赋值,
00442F86 mov dword ptr ds:[0x445830],eax ;;这个可疑先标记
00442FB4 mov eax,dword ptr ds:[0x445830] ;;这个上读取, 不是
00442FEB mov dword ptr ds:[0x445830],eax ;;这个双击进去看到eax=0, 不是
00442FF4 mov dword ptr ds:[0x445830],eax ;;这个双击进去看到eax=0, 不是
00443007 mov dword ptr ds:[0x445830],eax ;;这个双击进去看到eax=0, 不是
00443118 mov dword ptr ds:[0x445830],eax ;;这个在AgainClick按钮事件中, 也不是
0044314D mov eax,dword ptr ds:[0x445830] ;;这个上读取, 不是
004431C7 mov dword ptr ds:[0x445830],eax ;;这个也是在AgainClick中, 且eax=0, 不是
004431D0 mov dword ptr ds:[0x445830],eax ;;这个也是在AgainClick中, 且eax=0, 不是
0044320A mov dword ptr ds:[0x445830],eax ;;这个也是在AgainClick中, 且eax=0, 不是
所以只有第一个才可是有用的, 但这个是在失败分支中, 也就是说, 我们第一步得先失败一次, 不然永远都无法成功, 我们把注册码改成非数字的6位以上字符串a12345进入失败分支分析算法:
1). 00442AB4处, 判断长度是否<=5
2). esi = 0x37B, ebx=len, edx = [eax-0x8] = 2
3). 循环计算

直接开始写注册机代码:

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

int main() {
    char x[21] = {0};
    char y[21] = {0};
    int lenx=0, leny=0, v=0; 
    while(lenx < 5) {
	    printf("请输入用户名(5位以上): "); 
	    scanf("%s", x);
	    lenx = strlen(x);
	}
    while(leny < 6) {
    	printf("请输入错误注册码(不能全数字6位以上): "); 
	    scanf("%s", y);
	    leny = strlen(y);
	    v = atoi(y);
	    if(v > 0){ continue; } //说明是数字 
	}
	int edi=0x37B;
    for(int i=1; i<leny; i++){ edi += (y[i] % 0x11 + 1) * y[i-1]; }
    edi %= 0x7148; //得到edi 
	printf("EDI为: %d\n", edi);
    
    //开始计算注册码
    int ebx = 0;
	for(int i=0; i<lenx; i++){
		for(int j=lenx-1; j>=0; j--){
			ebx += x[i] * x[j] * edi;
		}
	}
	ebx %= 0xA2C2A;
	printf("EBX为: %d\n", ebx);
	ebx -= 1;
	int code = 0;
	//ebx -1 == code / 0x59 + code % 0x50;
	code = ebx * 0x59; //取最大值那个 
	code = code - (code % 0x50) + 1; //同时满足%0x50条件 
	printf("正确注册码为: %d\n\n", code);
	//这是所有的 
	for(int i=(ebx-0x50)*0x59; i<ebx*0x59; i++){
		if(i / 0x59 + i % 0x50 == ebx) { printf("找到:%d\n",i); }
	}
    getchar();getchar();
    return 0;
}

操作流程为:

  1. 输入5位以上用户名
  2. 输入6位以上非纯数字的注册码
  3. 点击注册按钮, 弹出错误信息, 点确定, 注册码变为0
  4. 输入正确的注册码, 点注册按钮, 注册按钮隐藏, 重试按钮显示
  5. 输入6位以上非纯数字的注册码(重复操作2.~4.步)
  6. 点击重试按钮, 弹出错误信息, 点确定, 注册码变为0
  7. 重新输入刚才正确的注册码, 点重试按钮, 重试按钮也隐藏
  8. 后记: 查看取消按钮代码可知, 作者还隐藏了小惊喜在这里, 这个按钮事件不光只是注册码置0的功能, 还有个成功分支, 条件是当用户名与注册码相同时进入~ 测试可喜提两个提示框

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

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

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

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

posted @ 2024-04-10 14:59  hankerstudio  阅读(109)  评论(0)    收藏  举报