前面(1)(2)基本上也隶属于序列号的保护方式中的一种。目前很多软件的保护方式仍使用这种序列号保护的方式。本文将系统的阐述这种保护方式。
大多数的序列号保护要求输入用户名及序列号,或者是提供机器码,要求输入序列号。这个就是我们上两篇文章中apk使用的验证方式。有一点不同的是在实际的软件注册过程中,一般要求输入用户名和序列号,或者是提供一个机器码,然后要求输入序列号。这个序列号一般是由机器中某个固定的值推算而来,比如WINDOW平台常用网卡MAC码,或者是其他的硬件的编码有效的组合得到这个注册码。注册的时候,你反馈该机器码给软件作者,并完成支付,软件作者向你提供一个对应的序列号,然后你便可以完成软件的注册。
Windows中的机器码-序列号注册模式
很明显,一般的序列号验证中,用户名/机器码 和 注册码中存在一个一一对应的关系。
(1)用户名-序列号模式一:以 用户名作为自变量,通过F函数变换得到了这个序列号。使用公式表示如下:
序列号 = F(用户名)
这种模式,会有一个明显的缺陷:在程序运算的过程中,F(用户名)其实就是正确的序列号,通过正确的序列号和输入的序列号进行对比来判断是否能注册成功。这种情况也就是说,在程序运行的上下文,我们能够从中找到这个序列号的明文。找到明文,那么就可以以smali代码注入的方式输出到logcat或者其他控件之中。
(2)用户名-序列号模式二:以输入的序列号作为自变量,通过F函数得到一个用户名,把这个用户名和输入的用户名进行对比,进而判断。这里必须要求F是个可逆变换。
用户名= F(序列号)或 F-1(用户名) = 序列号
同样,这种模式,也会有类似的问题,通过某个序列号,我们算出一个用户名,从而得到一个正确的 用户名/序列号 对。
(3)用户名-序列号模式三:若同户名通过F1函数与序列号通过F2函数的结果相等,那么认为该 用户名/序列号 是匹配的。此种模式使用公式描述为:
F1(用户名) = F2(序列号)
那么就认为该用户名和序列号是匹配的。此种模式相对2要好点,和2一样,同样运行过程中不会产生序列号的明文。设计的重点在于F1和F2函数。
(4)机器码-序列号验证模式。F必须是可逆变换。
机器码 = F(序列号)或 F-1(机器码) = 序列号
这种算法好处体现在若使用机器码-序列号验证,就算让你得到某序列号对应的正确的机器码,由于机器码大多数是由硬件资源固定下来的。所以这种模式且使用机器码-序列号的方式会好一些。当然,若采用机器码-序列号方式,理所当然也会增加开发者的额外负担,因为用户注册必须把机器码发回软件作者,软件作者通过F可逆的变换算的正确的序列号,再发会给用户,用户才能完成注册。
从公式也可以看出,若解密者找到了F的可逆变换,那么就能写出注册机。所以F函数的设计显得尤为重要,因为如果F函数能够轻易被逆转,那么破解者就能轻松的写出F的可逆变换,完成这个注册机。