本帖最后由 H夜 于 2019-6-6 18:13 编辑
本人对破解完全出于兴趣,这次要破解的程序《英格驾驶员考试学习系统2016版》单机版,官网网址如下:http://www.jsyst.cn/product/,安装程序在此下载,注册机见附件。 这个程序无壳,比较简单,适合我等学习练手。废话不多说,先直接双击程序,进入界面如下,需要注册码,随便输入数字,点击注册,弹出对话框,知道程序是重启验证。
1
由此想着MessageBox断点,于是用OD载入,断在此处:
2
可知程序是VB写的,下bpx RtcMessageBox,看看能否断下,下完断点,点击注册,程序没断下来,只好另寻他路。搜索字符串(UNICODE),可以找到点有用的信息:“注册码已保存,重启程序生效!”来到这个位置:
3
向上翻不远处,可以看到vbaFileOpen函数,还有\reg.dat字符串。
4
于是大胆猜测:reg.dat就是我们输入注册码后保存的地方。可以在程序根目录下发现reg.dat文件。记事本打开这个文件,发现并不是我们输入的12345,应该是加密了的,不管他。继续猜:既然是重启验证,肯定下次启动时,程序会先读reg.dat,才能跟正确的注册码判断。 大胆猜测,小心求证:直接搜索reg.dat字符串下断也行,给__vbaFileOpen下断也行,重启后果然断下,来到:
5
跟进这个call 0048C2B0:
6
继续跟,通过这个call调用DeviceIOControl函数,得到硬盘序列号(我的机器是8字节)和硬盘型号等信息。 回到00490E5F,知道了这个函数功能是取硬盘序列号,返回值在EAX里,再往下走几步,到了关键算法:
7
创建一个固定数组A[8]={37,18,17,4A,30,3E,79,D4},然后依次与硬盘序列号每一字节异或。得到新数组B[8],然后有一固定序列(长度为62,十六进制为3E): ; abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ, B%3E+1,在序列里找到;然后B/3E+1,在序列里找到,最后组成16字节数组就是注册码。剩下任务就是写注册机了。(由于是菜鸟,写个注册机还要翻基础知识,特别是读取硬盘序列号还是从网上copy的函数,还有char*转char[],关于char运算要先转换为unsigned char,再转换为int,注册机程序在本机xp系统下测试通过,不知道在win7以上效果如何。) 第一次发文,朋友们轻喷,不对的地方,请指正。 之前的分析确实有点问题,出于咱严谨的态度,经过再一次调试。
最后算法基本如下:
1、取得本机第一个硬盘的序列号并转化为char型数组A[c](各硬盘序列号位数c可能不一样);
2、创建一个十位char数组B[10]={37,18,17,4A,30,3E,79,D4,B7,93};
3、依次取A[]^B[10](满足A[c]的位数:当c<=10时,B[10]按顺序取,当c>10时,B[10]取完了重新取B[0]),结果放入C[c];
4、读取固定字符串"bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",并转化为char数组D[62],字符串的长度为62(即0x3E);
5、依次从数组C[c]中取C,将C除以D[62]的长度0x3E,商存入Ei,余数存入Fi;
6、依次从数组D[62]中取D[Fi]、D[Ei],结果存入char数组G[2*c],这个G[]就是最后的序列号。 源代码如下: int main(int argc, char* argv[]) { char* temp; char hdID[256]; char sample[256]; char serial[256]; char crypt[10]={0x37,0x18,0x17,0x4A,0x30,0x3E,0x79,0xD4,0xB7,0x93}; strcpy(sample,"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\0"); int samlenth=62; CGetHDSerial HDSerial; // 创建实例 temp=HDSerial.GetHDSerial(); // 得到硬盘序列号 int i=0; int j=0; int h=0; int n=0; int k=0; int m=0; while(temp!='\0')//去掉硬盘序列号前面的空格 { if(temp!=0x20) { hdID[j]=temp; j++; } i++; } hdID[j]='\0'; cout<<"your computer harddisk serial number is:"<<hdID<<endl<<endl<<endl; for(i=0;i<j;i++) { h=(i>=10)?(i-10):i; {k=2*i; hdID=hdID^crypt[h]; n=(int)(unsigned char)hdID%samlenth; m=(int)(unsigned char)hdID/samlenth; serial[k]=sample[n]; serial[k+1]=sample[m]; } } serial[k+2]='\0'; cout<<"the serial number is: "<<serial<<endl; getchar(); return 0; } |