合理设置加密点

所谓加密点,就是开发商在软件中调用比特运行库API的位置。加密点的放置既不能太密集——这样会影响软件的运行效率;也不能太少,以避免破解者轻易地绕过。一般来说,在软件的关键功能执行之前需要放置一个加密点,而且最好加密点的执行结果能够与后面关键功能的运行状态相关。举例来说:如果关键功能需要一个运行参数,可以把这个参数放置在授权文件一个“只读”类型的特征项里,而在关键功能执行前通过ReadFeature接口取得这个参数。

有效运用不同的特征类型

比特云平台提供了4种不同的特征类型,以满足不同的加密应用场合。

一般来说,“只读”和“读写”类型的特征项适合于存储开发商软件运行中的一些整数类型的参数;“算法”类型的特征项用于执行变换(Convert)操作,然后在变换后校验运算结果;“密钥”类型的特征项用于执行对软件中关键数据的加、解密操作。

通常“算法”类型特征项的安全强度要比其它类型要高,这是因为变换操作是单向的,而且其算法因子不会在软件中出现。虽然“密钥”因子也不会在软件中出现,但因为它是双向的,既可加密又可解密还原,所以相对来说更容易得到运算之后的结果。但是,相对于其它类型的特征项来说,“算法”类型的运算结果不容易与软件本身的运行数据进行关联。开发商需要结合软件本身的特点,合理地在程序的不同位置选择使用不同的算法调用。

有关特征类型的更多描述可以参考 产品特征项 (Feature)

增加随机性

增加随机性是指在软件中调用比特运行库API以及对调用过程中所使用的参数添加随机因素。时间可以作为一种随机因素,加密点并不一定每次都要调用,可以根据时间来判断是否调用。比如说,某个加密点只在周一调用,或者用一个随机天数作为每月的调用时间。随机调用加密点的好处是黑客很难找到软件内所有的加密点,并有针对性的破解。

此外,调用的参数也可以随机变化。比如说对一个“算法”特征,可以在比特云平台的“功能测试”页面生成多个输入、输出对,然后将这些输入、输出数据放在一个数组里,在进行调用之前随机选择使用其中的一组数据。

将API调用与调用结果的判断分开

不要在API调用之后马上使用或判断返回结果。软件破解者往往根据API调用点来寻找后面的判断点。将调用与结果使用分开,可以极大地提高破解及跟踪的复杂性。在代码中甚至可以尝试把API调用及判断点放在不同的模块或线程里。

合理使用API的返回结果

好的软件保护方法是将软件本身与API及其相关数据结合成一个整体,这样任何将软件与保护方案进行分离的尝试都会导致软件无法运行。比如,对软件中使用的关键数据或字符串,可以:

  • 用“读写”和“只读”特征项存储较短的数据(不大于4字节),或者使用“配置项”存储较长的数据(不大于1023字节)。
  • 可以使用API调用结果动态变换生成程序需要的数据常量或字符串。
  • 对一些关键数据,可以以加密的形式存储在本地或服务器上,加密密钥使用密钥特征项。使用这些关键数据时,调用DecryptFeature()函数实时解密使用。

文件的完整性检验和文件之间的相互认证

在许多情况下,破解是通过更改exe文件、更改或替换dll文件实现的,这种破解可以通过检查文件完整性进行防范。可以利用HASH算法计算出整个文件的校验和,在程序起动和运行中进行文件的完整性判断。如果检测到文件校验和发生变化,说明文件被更改,则退出执行。另外,exe和dll文件之间可以相互认证,比如exe文件的校验和放在dll中,而dll文件的校验和放在exe中。相互认证可以防止文件的更改和替换。

使用比特外壳工具

比特外壳可以实现对Windows PE格式EXE和DLL,.Net格式EXE和DLL、Java格式Jar和War程序的加密。外壳加密后程序是在执行时动态还原,可以有效防止静态跟踪破解,还可以通过设置“内外结合检查”和“检测调试器”选项来有效防止常用动态调试工具的破解。

不推荐的加密策略

  • 加密点的调用、判断、提示写在一起。
  • 重要的字符串或常量在程序中以明文出现。
  • 始终调用同一个特征项函数并且做同样的判断。
  • 程序缺乏随机性,每次执行的路径都一样。
  • 没有文件完整性检验或文件之间没有相互认证。