DiskGenius Pro 4.2.0.100注册算法简析
初次接触DiskGenius已经成为遥远的记忆,那个时候还只有DOS版本。后来到Windows版,用它来处理过几个找回丢失分区的案例,方便实用。到现在它的功能越来越强大,成为喜好启动技术和桌面支持人员的必备工具之一。
回想起好几年前的一个案例,一个用了很久的老机器突然崩盘,磁盘引导部分物理损坏,无法启动系统。一般的数据当然可以用DiskGenius等工具来恢复,但重点已经不在这里了,因为大部分数据我有备份。 让人焦虑的是我有一个EFS加密的文件和Outlook邮件偏偏就没有备份。里面含有个人和公司全部软件系统及服务器的帐户、授权信息。进不了系统,就意味着我要和它们永久地说拜拜了,着实令人不寒而栗。 尝试了很多数据恢复工具,包括Windows系统和其他系统的\Recovery\、\Copy\等等,全都没用。因为没有数字证书,这个EFS文件等同于一堆垃圾字节,也没办法进入邮件帐户。
交给专业的数据恢复公司又不放心,当然我没有冠希同学那样的秘密,要是他当初EFS一下,就不会招致那么多的口水和对那么多人的生活造成影响,呵呵。
后来自己终归解决了这个问题,说穿了很简单:在另一个系统里构造一个和宕机的系统完全一样的帐户,至少我还记得用户名和密码。要点是保证新建帐户和原帐户的SID一致,这样SAM里的Hash就和原来的相同,系统通过SID将帐户和文件的所有者对应起来。
在Windows系统中,得到了别人的这个Hash,就可以进入他的系统。曾在Marcus Murray的某个Microsoft TechEd演示\中看到,使用Hash将网络中的一台机器作为跳板入侵另一台机器。这方面还有大家熟知的Mark Russinovich。 得到的教训是,鸡蛋不能放在一个篮子里:备份、备份还是备份;另外,EFS就真的那么安全?真要用的话,请遵循“最佳实践”:备份证书,并将其从系统中移除。
这个故事脱离了本主题,按下不表。事情的起因是前段时间的一个“事故”:小弟的小弟替员工重装系统,拿错了映像,造成其他分区数据丢失。这就要命,搁谁也谁也郁闷,得帮人家恢复。
好久都没干这种事了,凭以往的经验用DiskGenius和R-STUDIO,感觉DiskGenius更有效和准确一些。
DiskGenius分免费版和专业版。免费版是体验用的,恢复文件时有64KB大小限制,搜索算法也相对简单,和未注册的专业版相同。由于有限制,基本上没法用,要么购买要么“破解”。出于对逆向的偏好,加上对传说中“暗桩”的好奇,决定玩一玩,也学习一下它的方法。
当然首先要找几个“破解版”在虚拟机上试一下,发现只有版本3.8那个是“真破解”,其他都是“伪破解”。甚至某“破解补丁”在内存中改程序的Title和About,难免被人批为大日本帝国的军人——“自慰”队员。很少有人提到激活文件Options.ini,见过的其中注册码也是错误的。
本文以目前最新的DiskGenius Pro 4.2.0.100为例,设想是不通过“破解”,而是弄清楚它的注册算法,实现完美激活。乱套一下“不战而屈人之兵”,是谓伐谋与攻心,乃最高境界。
先官样文章地声明一下,纯技术探讨,觉得软件有用请购买。这里不会暴露具体的细节,故命题为“简析”,到是整个过程中一些好玩的东西可能更有趣。
一.注册码的奥秘
未注册的专业版用户界面窗口标题会有“未注册”字样,“关于”对话框多一个“立即注册”按钮:
点进去,出现“注册DiskGenius”对话框,随便填些东东,再点“立即激活”,提示“无效的注册码,请重新输入。”。
非常友善,是不是。从这个对话框我们了解到,激活分网络(在线/离线)和加密锁两种方式,另外输入的注册码不符合它的要求,类似网页提交前客户端有一个初步的验证。直截了当,就从此对话框的窗口过程入手,找到它的验证算法,一探注册码的奥秘。
通过代码分析得知,内部有一个简单加密的Base36字符集,但不是标准序列、而是自定义的,最后4个字符是'01IO',从解码算法证实:注册码实际上是Base32编码,弃用了容易误识的数字和字母,每5个字符一组、5组共25个字符,以'-'分隔。类似Microsoft的CDKEY或Product Key,不过MSFT用的是Base24,还弃用了易被误认的'5AELNSUZ'。不会涉及椭圆曲线签名算法吧?让人望而生畏!有一点可以肯定,Hash(或者说Checksum bits)是有的,用于验证注册码的有效性。
显然,Base32比Base24表示的大整数要大很多,意味着我们选择的余地更大、相对容易一些。有了Base32字符集和校验算法,我们就可以开始生成自己的注册码了。但是我不想抄那些反汇编代码,换一种玩法:用HTML页面+浏览器作UI,Javascript作算法实现,只需一个支持高亮和好用的文本编辑器,比如EmEditor就可以方便地设计界面和修改程序进行调试了。
因为我有一个现成的来自About.com的\页面,稍加修改成为\随机生成注册码,再用校验算法得到Hash。About的页面简洁、美观,Layout全部用DIV+CSS,不象其他大多数人用TABLE,记得以前有过DIV和TABLE的争论。
Javascript和C++都是面向Object的,Javascript具有C++没有的\,但两者都没有汇编指令ROR/ROL这样简单的运算符,两条指令C++实现的例子可在Bruce Eckel的\in C++\
Volume 1中找到。
但是注册码生成器中Javascript有两个问题需要解决,大整数和无符号整数。
在Javascript里,数字都用符合IEE754规范的64位双精度浮点数表示。显然注册码轻松地超过了64位限制,需要找一个简单的Javascript库处理\,可参考stanford.edu的\JavaScript\里相关内容,但我们这里不用整这么复杂。
数据类型方面,MSFT到\才在\中引入UInt8、Int32、Int64[-2^53, 2^53]和Uint64[0, 2^53]等等;Mozilla到是早就在ctypes里支持Int64和UInt64。同样不打算弄得这么繁琐,只将必要的运算(左移位、加/带位加、异或/或等)改写,保证结果为UINT类型。 另外,数字需要经常在二进制、十进制和十六进制间转换,Javascript的Number.toPrecision([precision])却没法用,精度不够,得自己想办法。IE严格遵循JScript文档,precision超过21就报错,而Firefox中将precision设到40时返回的还是近似数。
FF的Javascript性能表现远远超过IE,这在编码大整数为Base32时能明显感觉到。意料中的事,MSFT早已不满足于将IE定位为单纯的Browser,IE已然成为一个试图一统天下的超级客户端,以满足服务器端产品的要求,同时和操作系统密不可分,十分地臃肿。
下图为\的页面: