DiskGenius Pro 40注册算法简析.docx

上传人:b****6 文档编号:6998228 上传时间:2023-01-15 格式:DOCX 页数:12 大小:987.01KB
下载 相关 举报
DiskGenius Pro 40注册算法简析.docx_第1页
第1页 / 共12页
DiskGenius Pro 40注册算法简析.docx_第2页
第2页 / 共12页
DiskGenius Pro 40注册算法简析.docx_第3页
第3页 / 共12页
DiskGenius Pro 40注册算法简析.docx_第4页
第4页 / 共12页
DiskGenius Pro 40注册算法简析.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

DiskGenius Pro 40注册算法简析.docx

《DiskGenius Pro 40注册算法简析.docx》由会员分享,可在线阅读,更多相关《DiskGenius Pro 40注册算法简析.docx(12页珍藏版)》请在冰豆网上搜索。

DiskGenius Pro 40注册算法简析.docx

DiskGeniusPro40注册算法简析

DiskGeniusPro4.2.0.100注册算法简析

初次接触DiskGenius已经成为遥远的记忆,那个时候还只有DOS版本。

后来到Windows版,用它来处理过几个找回丢失分区的案例,方便实用。

到现在它的功能越来越强大,成为喜好启动技术和桌面支持人员的必备工具之一。

回想起好几年前的一个案例,一个用了很久的老机器突然崩盘,磁盘引导部分物理损坏,无法启动系统。

一般的数据当然可以用DiskGenius等工具来恢复,但重点已经不在这里了,因为大部分数据我有备份。

让人焦虑的是我有一个EFS加密的文件和Outlook邮件偏偏就没有备份。

里面含有个人和公司全部软件系统及服务器的帐户、授权信息。

进不了系统,就意味着我要和它们永久地说拜拜了,着实令人不寒而栗。

尝试了很多数据恢复工具,包括Windows系统和其他系统的"NTFS/EFSRecovery"、"RawCopy"等等,全都没用。

因为没有数字证书,这个EFS文件等同于一堆垃圾字节,也没办法进入邮件帐户。

交给专业的数据恢复公司又不放心,当然我没有冠希同学那样的秘密,要是他当初EFS一下,就不会招致那么多的口水和对那么多人的生活造成影响,呵呵。

后来自己终归解决了这个问题,说穿了很简单:

在另一个系统里构造一个和宕机的系统完全一样的帐户,至少我还记得用户名和密码。

要点是保证新建帐户和原帐户的SID一致,这样SAM里的Hash就和原来的相同,系统通过SID将帐户和文件的所有者对应起来。

在Windows系统中,得到了别人的这个Hash,就可以进入他的系统。

曾在MarcusMurray的某个MicrosoftTechEd演示"KnowingtheEnemy-Alightningdemonstrationonhowhackersattacknetworks"中看到,使用Hash将网络中的一台机器作为跳板入侵另一台机器。

这方面还有大家熟知的MarkRussinovich。

得到的教训是,鸡蛋不能放在一个篮子里:

备份、备份还是备份;另外,EFS就真的那么安全?

真要用的话,请遵循“最佳实践”:

备份证书,并将其从系统中移除。

这个故事脱离了本主题,按下不表。

事情的起因是前段时间的一个“事故”:

小弟的小弟替员工重装系统,拿错了映像,造成其他分区数据丢失。

这就要命,搁谁也谁也郁闷,得帮人家恢复。

好久都没干这种事了,凭以往的经验用DiskGenius和R-STUDIO,感觉DiskGenius更有效和准确一些。

DiskGenius分免费版和专业版。

免费版是体验用的,恢复文件时有64KB大小限制,搜索算法也相对简单,和未注册的专业版相同。

由于有限制,基本上没法用,要么购买要么“破解”。

出于对逆向的偏好,加上对传说中“暗桩”的好奇,决定玩一玩,也学习一下它的方法。

当然首先要找几个“破解版”在虚拟机上试一下,发现只有版本3.8那个是“真破解”,其他都是“伪破解”。

甚至某“破解补丁”在内存中改程序的Title和About,难免被人批为大日本帝国的军人——“自慰”队员。

很少有人提到激活文件Options.ini,见过的其中注册码也是错误的。

本文以目前最新的DiskGeniusPro4.2.0.100为例,设想是不通过“破解”,而是弄清楚它的注册算法,实现完美激活。

乱套一下“不战而屈人之兵”,是谓伐谋与攻心,乃最高境界。

先官样文章地声明一下,纯技术探讨,觉得软件有用请购买。

这里不会暴露具体的细节,故命题为“简析”,到是整个过程中一些好玩的东西可能更有趣。

一.注册码的奥秘

未注册的专业版用户界面窗口标题会有“未注册”字样,“关于”对话框多一个“立即注册”按钮:

点进去,出现“注册DiskGenius”对话框,随便填些东东,再点“立即激活”,提示“无效的注册码,请重新输入。

”。

非常友善,是不是。

从这个对话框我们了解到,激活分网络(在线/离线)和加密锁两种方式,另外输入的注册码不符合它的要求,类似网页提交前客户端有一个初步的验证。

直截了当,就从此对话框的窗口过程入手,找到它的验证算法,一探注册码的奥秘。

通过代码分析得知,内部有一个简单加密的Base36字符集,但不是标准序列、而是自定义的,最后4个字符是'01IO',从解码算法证实:

注册码实际上是Base32编码,弃用了容易误识的数字和字母,每5个字符一组、5组共25个字符,以'-'分隔。

类似Microsoft的CDKEY或ProductKey,不过MSFT用的是Base24,还弃用了易被误认的'5AELNSUZ'。

不会涉及椭圆曲线签名算法吧?

让人望而生畏!

有一点可以肯定,Hash(或者说Checksumbits)是有的,用于验证注册码的有效性。

显然,Base32比Base24表示的大整数要大很多,意味着我们选择的余地更大、相对容易一些。

有了Base32字符集和校验算法,我们就可以开始生成自己的注册码了。

但是我不想抄那些反汇编代码,换一种玩法:

用HTML页面+浏览器作UI,Javascript作算法实现,只需一个支持高亮和好用的文本编辑器,比如EmEditor就可以方便地设计界面和修改程序进行调试了。

因为我有一个现成的来自A的"PasswordGenerator"页面,稍加修改成为"regcodeGenerator"随机生成注册码,再用校验算法得到Hash。

About的页面简洁、美观,Layout全部用DIV+CSS,不象其他大多数人用TABLE,记得以前有过DIV和TABLE的争论。

Javascript和C++都是面向Object的,Javascript具有C++没有的"RegularExpressions",但两者都没有汇编指令ROR/ROL这样简单的运算符,两条指令C++实现的例子可在BruceEckel的"ThinkinginC++",Volume1中找到。

但是注册码生成器中Javascript有两个问题需要解决,大整数和无符号整数。

在Javascript里,数字都用符合IEE754规范的64位双精度浮点数表示。

显然注册码轻松地超过了64位限制,需要找一个简单的Javascript库处理"BigNumber",可参考stanford.edu的"RSAandECCinJavaScript"里相关内容,但我们这里不用整这么复杂。

数据类型方面,MSFT到"InternetExplorer10"才在"WindowsRuntimeTypes"中引入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已然成为一个试图一统天下的超级客户端,以满足服务器端产品的要求,同时和操作系统密不可分,十分地臃肿。

下图为"regcodeGeneratorforDiskGenius"的页面:

这部分很容易,先随机生成注册码的前22位,再将16bits的Hash值编码为Base32字符得到注册码的末3位。

二.激活请求发送了什么

现在注册码是有效的了,试着激活。

但这次是服务器回答“Error:

注册码无效!

”,这里可理解为:

注册码仍然有问题、确实无效,或有效、但在它的数据库中没有记录,还可能数据库存在记录、但其他字段不匹配。

无论那种情况都不可能指望它返回有用的信息,也不好意思老去骚扰人家的服务器。

换个思路,转而从处理返回结果的代码着手。

为方便和避免错误,我需要在本地启用HTTP服务,将激活服务器的地址指向本地,进行模拟。

程序需要什么数据,就按要求响应它,让我能一步一步走下去。

但再这之前,得搞清楚程序向激活服务器发送了些什么数据,以帮助我们猜测和理解返回数据的构成。

用Wireshark这类的工具记录一下HTTP的Request和Response内容。

捕获的数据简单明了,它使用GET方法发送请求数据,URL中各字段依次为(在跟程序时也可观察到):

1.ver=4.2.0.100

2.code=YH23U-R65WC-CKPA2-RN2JB-XENVZ

3.name=MistHill

4.email=misthill%

5.mid=mOD_CDOcD^OFHLOHLHLL%1A%1A%1A%1A%1A%1CL%1C

6.appname=DiskGenius

7.diskinfo1=XCyo|kXg|z{obGJKFo|jJ|gxkQ>%3F>>>>>>>>>>>>>>>>>%3FQ:

%3F7:

%3D>:

>

复制代码

注意到:

首先,传递的值一定要编码为有效的URI(UniformResourceIdentifier)。

其次,mid和diskinfo1的内容是加密的,其他字段的含义一目了然。

mid从字面上理解意为机器码,为三次CPUID指令的结果变化而成。

diskinfo1显然代表磁盘信息,我在调试的机器上都只挂了一块硬盘,两块及以上的情况是不是还会发送diskinfo?

,没仔细查程序代码,不能确认。

程序为找到的每一个磁盘都创建一个磁盘对象,共支持0x80个磁盘。

对每个磁盘对象,调用两次KERNEL32.DeviceIoControl。

第一次取Geometry,第二次取ProductId和SerialNumber。

根据Geometry计算出磁盘的总扇区数,再加上ProductId(型号)和SerialNumber(序列号)得到diskinfo1的内容。

三.实现一个简单的HTTP服务

前面讲到激活分网络和加密锁两种方式。

没有加密锁可以写一个Driver来模拟,为使事情变得简单,我选择网络方式。

在本地如果有现成的IIS或Apache[Tomcat],可简单地写个页面来响应请求。

这里我决定借用现成的模板写一个APP来实现简单的HTTP服务,我就不用在调试虚拟机上搞一大堆东西,也方便以后类似的工作。

可以找到很多类似的东西,但我希望尽可能简单,并一定要有详细的文档。

来自IBM的NigelGriffiths有一篇"nweb:

atiny,safeWebserver(staticpagesonly)"就非常不错,全部C源码仅200行,支持静态页面.html或.htm、图像、压缩文件。

遗憾它需要UNIX系统,如Ubuntu、Fedora、OpenSUSE和Debian等。

我需要Windows环境的。

MSFT的DavidCook一篇"WriteaSimpleHTTP-basedServerUsingMFCandWindowsSockets"正是我要找的,文章发表于MSJ(MicrosoftSystemsJournal-MSDN的前身)February1996。

嗯…,这么古老的东西?

没错,就是它。

越早越容易被奉为经典。

它的工程名称为Webster,文章十分详细,涵盖HTML、HTTP、Sockets等,可设置Server的基本选项,高度可控;"MIMEDataTypes"可扩展;支持详细的调试和日志记录;支持"SystemTray"图标;源码注释得也很好。

编译连接后,先用Telnet测试一下:

啊哈,工作完全正常!

现在我们可以使用自己的“激活服务器”了。

但是激活时Webster服务器Hung在那里,追查Bug:

发现用于接收GET请求URI的Buffer太小,请求的URI字符串太长造成“缓冲区溢出”。

再来,这次没问题了:

对工程Webster改了大概以下几处:

a)HTTP/1.1协议支持,96年那时还只有HTTP/0.9和HTTP/1.0。

b)URI缓冲区大小。

c)由CScrollView派生的CWebView水平滚动条支持。

d)由CPropertySheet派生的CWebProps各属性标签CPropertyPage里Controls的字体。

四.完美激活

接下来,根据程序处理激活码那部分代码的分析,开始写注册机。

因为要用到CPUID指令和API调用,用VC++来写。

激活码(ActivationKey)实际上是对激活时提交信息进行变换、加密处理后的结果。

这是激活服务器后台干的事,程序解密激活码后对那些信息逐一进行对比,没有问题激活就成功了。

激活码可视为一张证书,分好几种类型。

比如是否限制了特定版本,若无则通用证书适用于其他版本;还有试用证书,可指定过期日期。

大概还有一种,决定硬件信息的比对来源,是加密锁还是API,没详细看代码,无法肯定。

图中uncheck两个Encrypted的Checkbox会显示mid和diskinfo1各自的明文。

激活成功后,程序会写激活文件Options.ini,用于重启验证;同时会复制一份到dos文件夹给DOS版使用。

格式基本上是这样子:

1.[license]

2.user="MistHill"

3.email="misthill@"

4.regcode="YH23U-R65WC-CKPA2-RN2JB-XENVZ"

5.key="9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA"

6.[LicenseInfo]

7.Show="N"

复制代码

这里注册码(regcode)目前看来是“有效的”;激活码(key)是我手工敲的,显然无效,不能通过验证。

但已足够让程序去掉Title里的“未注册”字样和“关于”对话框的“立即注册”按钮:

貌视已注册成功,此为“暗桩”之一。

五.注册码兮,注册码

将key的内容改回注册机(DiskGeniusKeygen)里"ActivationKey"的内容,这下能通过重启验证,应该是“完美激活”了吧?

No,No,No...,Somethingwrong!

试图恢复大于64KB的文件时失败,错误类型表明还是“未注册”!

看来还有玄机。

重新审查激活码验证通过后的代码,发现确实有调用对注册码再次进行验证,当前这个regcode没有通过!

在仔细研究了那段代码后,我才恍然大悟,它还真是跟MSFT的CDKEY学来的,注册码由三部分组成:

序列号(SerialNumber)+签名(Signature)+校验位(Hash)。

签名由序列号按签名算法得到,校验位为根据前两部分计算出的结果。

同时也搞清楚了哪几个关键标志DWORDs的值应该是什么才表明它是真正注册成功了。

回到第一节的"regcodeGeneratorforDiskGenius"页面,"PhaseI"解决了Hash的问题,接下来"PhaseII"解决签名的问题。

先随机生成一个RegCode,得到序列号部分,根据它的逆算法得到签名部分,最后计算校验位部分。

这样整个DiskGenius的注册过程分为两个步骤:

1)用HTML页面产生有效的注册码;2)用注册机生成激活码。

Webster只是分析问题时的一个工具,不再需要了。

再试一试恢复大于64KB的文件,这次当然不会再有问题:

最后,感谢DiskGenius的作者,很好的工具,希望它更加强大!

我从分析它代码的过程中得到乐趣。

谢谢您阅读此文!

谬误之处,请批评指正。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 实习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1