先打开文件,
随便输入一下尝试:
所以该程序应该是破解掉Serial/Name。(ps:在被坑了一下午之后百度到一开始弹出来的东西叫nag窗口,要想办法把他给去掉。)
1. 去除NAG:
开始F8,到CALL 00429F8C的时候弹出了NAG,所以F2然后CTRL+F2重新开始
F9运行到断点处,F7进到函数内部继续F8到这个位置,再次弹出NAG(继续下断点重新调试)
接着F8到这里又出现弹窗,我们继续重复上面的操作。
又找到了这里,不过看这里的注释应该是快到终点了
看到了MessageBoxA,终于找到NAG的源头了
然后滚回去发现了个判断函数完美避开NAG
重新调试,改成JMP继续,这样NAG窗口就没了。
2. 解决NameSerial:
随便输入之后显示如下
然后在OD里面搜索Sorry这段字符串并进入相应汇编地址
随便看看发现了一个Congratz……似乎发现了什么
还发现上面的JNE正好跳到下面的Sorry处
其实到这里如果把JNE改成NOP掉就可以跳到成功的位置了,然而我们要写Keygen,这就很尴尬,接着继续推测出JNE上面的CALL应该是返回一个ZF值来判断的,再上面一个函数应该是生成这个serial的关键。
3. KEYGEN:
在这个函数位置设了断点后,F8几步后,发现栈中生成的serial:
输入了一下正确,那么接下来开始研究这个函数里面到底发生了什么吧。
进入到函数内部,发现了三个CALL,先下3个断点看看栈中的serial是什么时候生成的吧,额,一直都没生成,而且程序似乎在做死循环,我也说不清楚为什么。
然后我们接着从函数出来发现上方的两个字符串CW和CRACKED引起了我们的注意。F8后出现了一些我们想要的变化。
所以我们重新调试程序来研究最上面的过程究竟是什么样子:
分析如备注所示(从这个位置开始分析其实还是借助网上的参考,毕竟经验不足。)
然后我们知道了实际上CW和CRACKED中间的数字就是输入字符串的第一个字符乘以29h再乘以2得到的数值转化成相对应的字符串。
写出keygen如下:
#include<iostream>
using namespace std;
int main(int argc,char *argv[])
{
char name[50];
int serial=0;
while(1)
{
cout<<"Input the name : ";
cin>>name;
serial=name[0]*(0x29)*2;
cout<<"The serial is :"<<"CW-"<<serial<<"-CRACKED"<<endl;
cout<<"Continue or not(y/n)?";
char temp;
cin>>temp;
if(temp=='n') break;
}
system("pause");
}
(菜鸟的第一次做CrackMe,弄了好久才弄明白OD怎么用。在大量的参考下做出了这道题,积累经验,路还很长!)