新CrackMe160之147 - Prolixe - KeygenMe#1
第一步 去NAG, OD载入程序,一眼就看到了弹框代码MessageBoxA(0040822A), 将00408228这行的push 0x0改为push 0x1指向一个不存在的父级,就不弹了, 把整个弹框代码nop掉也是可以的(0040821C ~ 0040822A)
第二步 正常破解, 重新载入去NAG程序, 搜索失败关键词"Enter a Serial"定位到00407FDD, 可看到程序只验证是否为空,没有长度限制
在0040800D处下好断点,输入伪码: abc 123, 单步分析算法: 下面有4个关键call, 分别多次测试分析,可知关键算法处为: 0040802C, 最后00408050是比较, 所以我们进入0040802C详细分析:
00407E58 ~ 00047E81 对用户名进行循环运算: code[i] = user[i] ^ (i+1+5) + user[i] + 0xA
00407EAE 处将code与两个固定串连接起来得到最终注册码: code = "HZF-" + code + "-GFD"
注册机如下:
#include <stdio.h>
#include <string.h>
int main() {
char user[30] = {0};
char code[30] = {0}; //"PAYPALISHIRING";
printf("用户名: ");scanf("%s",user);getchar();
int i, len = strlen(user);
for(i=0;i<len;i++){
code[i] = (user[i] ^ (i+6)) + user[i] + 0xA;
}
printf("注册码: HZF-%s-GFD\n", code);
getchar();
return 0;
}
运行示例:
用户名: Keygen
注册码: HZF-⒀暨掭-GFD
可看到生产出来的注册码看起来像乱码似的中文, 能否为0x20~0x7A的单可见字符呢, 我们分析一下算法code[i] = (user[i] ^ (i+6)) + user[i] + 0xA;
结果code[i]要在0x20~0x7A, 如果code[i] = 0x7A, 那(user[i] ^ (i+6)) + user[i] = 0x70, 那user[i]大概在0x38左右,这不就是数字区域吗
我们用数字作用户名测试一下:
运行示例:
用户名: 1111
注册码: HZF-rqts-GFD
成功了~
如果结果想控制在大写字母内,(user[i] ^ (i+6)) + user[i] + 0xA = [0x41,0x5A], 那用户名就在0x25左右, 得是特殊符号了
运行示例:
用户名: !!!!
注册码: HZF-RQTS-GFD
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号