《XXX考试学习系统2016单机版》破解笔记
本帖最后由 H夜 于 2019-6-6 18:13 编辑本人对破解完全出于兴趣,这次要破解的程序《英格驾驶员考试学习系统2016版》单机版,官网网址如下:http://www.jsyst.cn/product/,安装程序在此下载,注册机见附件。 这个程序无壳,比较简单,适合我等学习练手。废话不多说,先直接双击程序,进入界面如下,需要注册码,随便输入数字,点击注册,弹出对话框,知道程序是重启验证。由此想着MessageBox断点,于是用OD载入,断在此处:可知程序是VB写的,下bpx RtcMessageBox,看看能否断下,下完断点,点击注册,程序没断下来,只好另寻他路。搜索字符串(UNICODE),可以找到点有用的信息:“注册码已保存,重启程序生效!”来到这个位置:
向上翻不远处,可以看到vbaFileOpen函数,还有\reg.dat字符串。于是大胆猜测:reg.dat就是我们输入注册码后保存的地方。可以在程序根目录下发现reg.dat文件。记事本打开这个文件,发现并不是我们输入的12345,应该是加密了的,不管他。继续猜:既然是重启验证,肯定下次启动时,程序会先读reg.dat,才能跟正确的注册码判断。大胆猜测,小心求证:直接搜索reg.dat字符串下断也行,给__vbaFileOpen下断也行,重启后果然断下,来到:跟进这个call 0048C2B0:
继续跟,通过这个call调用DeviceIOControl函数,得到硬盘序列号(我的机器是8字节)和硬盘型号等信息。回到00490E5F,知道了这个函数功能是取硬盘序列号,返回值在EAX里,再往下走几步,到了关键算法:
创建一个固定数组A={37,18,17,4A,30,3E,79,D4},然后依次与硬盘序列号每一字节异或。得到新数组B,然后有一固定序列(长度为62,十六进制为3E): ;abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,B%3E+1,在序列里找到;然后B/3E+1,在序列里找到,最后组成16字节数组就是注册码。剩下任务就是写注册机了。(由于是菜鸟,写个注册机还要翻基础知识,特别是读取硬盘序列号还是从网上copy的函数,还有char*转char[],关于char运算要先转换为unsigned char,再转换为int,注册机程序在本机xp系统下测试通过,不知道在win7以上效果如何。)第一次发文,朋友们轻喷,不对的地方,请指正。之前的分析确实有点问题,出于咱严谨的态度,经过再一次调试。
最后算法基本如下:
1、取得本机第一个硬盘的序列号并转化为char型数组A(各硬盘序列号位数c可能不一样);
2、创建一个十位char数组B={37,18,17,4A,30,3E,79,D4,B7,93};
3、依次取A[]^B(满足A的位数:当c<=10时,B按顺序取,当c>10时,B取完了重新取B),结果放入C;
4、读取固定字符串"bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",并转化为char数组D,字符串的长度为62(即0x3E);
5、依次从数组C中取C,将C除以D的长度0x3E,商存入Ei,余数存入Fi;
6、依次从数组D中取D、D,结果存入char数组G,这个G[]就是最后的序列号。源代码如下:int main(int argc, char* argv[]){ char* temp; char hdID; char sample; char serial; char crypt={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=temp; j++; } i++; } hdID='\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; n=(int)(unsigned char)hdID%samlenth; m=(int)(unsigned char)hdID/samlenth; serial=sample; serial=sample; } } serial='\0'; cout<<"the serial number is: "<<serial<<endl; getchar(); return 0;} Hmily 发表于 2016-7-26 15:17
建议把算法分析部分完善一下。
有老大的支持,必须重新再梳理一遍。
之前的分析确实有点问题,出于咱严谨的态度,经过再一次调试。
算法基本如下:
1、取得本机第一个硬盘的序列号并转化为char型数组A(各硬盘序列号位数c可能不一样);
2、创建一个十位char数组B={37,18,17,4A,30,3E,79,D4,B7,93};
3、依次取A[]^B(满足A的位数:当c<=10时,B按顺序取,当c>10时,B取完了重新取B),结果放入C;
4、读取固定字符串"bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",并转化为char数组D,字符串的长度为62(即0x3E);
5、依次从数组C中取C,将C除以D的长度0x3E,商存入Ei,余数存入Fi;
6、依次从数组D中取D、D,结果存入char数组G,这个G[]就是最后的序列号。
由于现在在单位,注册机以及c源码回家后重新再写,一并奉上。 byh3025 发表于 2016-7-29 15:43
不过现在我用假码注册时出现了这,不知是哪里出问题了
确实是。
0045AD54 .83F8 09 cmp eax,0x9 ;Switch (cases 0..9)这里应该是个消息处理函数,9个分支,可以到每个分支里看看,如果往下2行有 JE语句,改成JNE,爆破OK。
0045AD57 .0F87 3C130000 ja 货车科目.0045C099
0045AD5D .FF2485 FCC045>jmp dword ptr ds:
0045AD64 >E8 C75F0300 call 货车科目.00490D30 ;Case 0 of switch 0045AD54
0045AD69 .66:85C0 test ax,ax
0045AD6C .0F84 BE120000 je 货车科目.0045C030 就是这里JE改为JNE
搞不懂这种科目一的软件还要收费,网上不是一大堆免费吗?科目二模拟车的收费还正常! Jack.K 发表于 2016-7-24 22:26
搞不懂这种科目一的软件还要收费,网上不是一大堆免费吗?科目二模拟车的收费还正常!
所以说要撸掉嘛。 这个软件无壳,函数和注册码也都是明文保存,破解起来不难。关键是真要写点东西的时候,还是要到网上查知识,学到不少。感觉学破解还是要靠兴趣,不然没法支撑下去啊。 感谢分享,学习了 来保存一下,为以后考车试嘛。 我也在背科目一的题目,不过好像一般用不到这个软件 不知道驾考宝典和这个差多少 好教程! 虽然驾照已经考了三年了,但是考驾照的经历历历在目,不容易的说。