新CrackMe160之088 - %5bKFC%5dfish's%20CrackMe

OD载入程序,搜索界面无关键信息,F9运行程序,按OK按钮弹出错误提示框,此时再打开搜索界面还是没有信息,那只能使用暂停法了,F12暂停程序,再按K看堆栈界面,看到了错误词,下面一行定位到主代码区00401601,那上面就是算法了,找到方法入口00401440下好断点,重新运行程序,发现程序一闪就没了,说明作者做了防调试功能,也说明程序中有个计时器,在api插件中添加SetTimer断点,发现添加失败,试着手动添加,在导航栏上的Command中输入bp SetTimer 回车,发现添加成功了,说明程序中确实有这个方法, F9运行程序,程序正常停下, 在下面数据区可以看来这个方法的调用来自00401300,将第一个参数push 0x0(其实是第4个参数)改为push 0x1即可停用timer, 保存后重新载入修改后程序(注意,程序还校验了原程序文件名的大小什么,防修改,所以文件名不能变)
OD重新载入程序后运行,发现程序一闪就没了直接退出了,说明防调试还在(前面的断点还在),只能重新来过,单步调试直到00401EAF处,程序闪退了,F7进入这个方法,来么系统方法中,继续F8向下操作,一直到7A024F38处有call esi (esi=004010B0)返回到了用户代码块,F8运行程序就一闪没了,说明就是这个程序阻止了调试,F7进入方法单步继续跟踪,这个方法里又调用了两个用户方法004010E2和004010FA, 004010E2进入发现有个LoadIconA应该是窗体初始化用的,004010FA里面有LoadLibraryA和PostQuitMessage, LoadLibraryA的参数是Kernel32.dll和IsDebuggerPresent,嗯,到这里应该是发现程序退出的真正原因了,程序开启了Debugger的功能,这里应该就是阻止调试的地方了, 我们试着nop掉004010FA这行,重新运行程序,发现程序正常运行了,到此防止调试就被我们搞定了,保存
再次重新载入破解后程序,发现程序正常运行了,(意外发现文件名改完后也可以正常运行了,后面详细调试后才发现文件名的验证也在004010FA这个方法里的这行0040176D call 004017A0这个方法里,倒是无心插柳了), 【后记:其实API常用断点插件中直接就有IsDebuggerPresent这个断点,在进程函数下,有了这个就可以不用一直单步调试找了,前提是得有这个经验知道防调试是用这个方法的】
重新在按钮入口00401440下好断点,开始分析算法
1). 用户名与注册码不能为空
2). 注册码前9位循环异或0xAA累加 rlt1 += code[i] ^ 0xAA
3). 00401989 ~ 00401992 用户名累加
4). 00401996 ~ 004019B5 9位固定串"KEY-KANON"与用户名累加值运算 rlt += (((str[i] * sum) % 0x1A) + 0x61) ^ 0xAA
5). rlt与注册码累加对比
由2).5).可得 ((str[i] * sum) % 0x1A) + 0x61 = code[i], 注册机如下:

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

int main() {
	char user[33] = {0};
	char code[10] = {0};
	char *str = "KEY-KANON";
	printf("用户名: ");
	fgets(user, sizeof(user), stdin);
	int i, len = strlen(user) - 1, sum = 0;
	user[len] = 0;
	for(i=0; i<len; i++){
		sum += user[i];
	}
	for(i=0; i<9; i++){
		code[i] = ((str[i] * sum) % 0x1A) + 0x61;
	}
	printf("注册码: %s", code);
	getchar();
	return 0;
}

运行示例:
用户名: CrackMe
注册码: qwcuqaama
其中注册码只验证前9位,所以验证码可以大于9位,且9位以后可为任意数

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

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

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

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