潜在的问题和一般的解决方法
混淆对于保障软件的安全是一个合理的选择,同时它要保证软件正常的功能不受影响。但是,在一些具体的例子中,混淆器所做的转换操作在不经意间破坏了正常工作的代码。下面的章节会讨论常见的问题和推荐的解决方法。
动态类载入
要确保对于包,类,方法,和变量的更名操作会运行正常,必须能够保证整个软件系统中所有的相关名称都被修改。混淆器必须保证在字节码中所有的 static 引用都指向了新的名称。但是,如果代码中使用
了 Class.forName或者
ClassLoader.loadClass() 来进行动态类载入,这将会调用原始的类名称,结果就是出现一个
ClassNotFound 异常。现在的混淆器已经可以很完善的处理此类问题,它们会尝试修改代码语句,使语句指向新的名称。但是,如果代码语句是在runtime 期间创造的,或者是通过读取属性文件获得名称的,那么混淆器就无法应付状况。优秀的混淆器会产生一个日志文件,指出代码中具有潜在 runtime 问题的地方。
最简单的解决方法,就是配置混淆器,使它在混淆过程中保留动态载入类的名称。而类的内容,诸如方法,变量,和代码,依然可以被转换。
Trenches 的故事
最具有革新意义的产品是 CreamTec 出品的 WebCream,它提供了一个网络的免费下载版本。免费的版本只能供给5个用户使用,如果想要扩大用户数量,你就需要去购买一个产品的商业协议。在乌克兰生活的那段日子,我了解到有很多人更愿意去破解那些协议,把软件的免费版本变成无限制版本,从而节省许多美圆。在 CreamTec,我们使用了一个简单免费的混淆器,它的功能局限于更名而已。我们一直认为这个混淆器就足够满足要求了,直到有一天,我的一个朋友,他一向把限制功能的软件看作是一种对个人的侮辱,在他手里只花了不到15分钟,就破解了我们的协议代码。这给我们提供了足够的警告信号,于是我们决定去购买 Zelix KlassMaster 来尽可能的保护我们的产品。在我们使用了几种主动性的控制流混淆策略以后,我的朋友再也不能象上次那么容易得到我们的协议代码,因为他并不想在这个问题上花费几天时间,于是他放弃了。
映射
影射需要了解编译期间方法名和变量名的知识。所以它也可以通过混淆器来影响(翻译的不确定)。请选择一个优秀的混淆器,并去查看警告日志文件。如果混淆器会产生runtime 错误,比如说动态类载入的问题,你就必须在混淆操作中保留那些由
Class.getMethod 或者
Class.getField引用的方法名或者变量名。
(未完!!因为该系列文章没有包含我需要的东西,所以不继续翻译,到此为止)