随着互联网技术的发展,软件的分发变得越来越便捷,但同时也带来了盗版问题。为了保护PHP软件不被非法复制和分发,开发了一套代码混淆工具。这套工具旨在允许用户在购买前试用软件,同时限制软件的非法传播。
在开发过程中,研究了多种PHP源代码保护方案,包括开源的编码器和混淆器,以及一些闭源的字节码编译器。面临的问题是,字节码编译器要么需要与应用程序一起分发额外的运行时可加载模块,要么需要在服务器上安装如Zend这样的扩展。由于无法保证脚本将被安装在的服务器的功能状态,决定不采用任何涉及字节码编译的解决方案。
流行的开源混淆器无一例外地破坏了源代码,或者要求更改源代码以适应混淆器。发现,编写自己的C#混淆器比更改所有PHP代码以适应混淆器强加的任意代码指南要快。当然,自己的混淆器对它能够混淆的代码施加了自己的指南,这是由于自己的编码风格和内部PHP编码实践。
使用这个混淆器编码PHP脚本的主要规则是,它不理解在HTML主体中声明的PHP变量。这意味着,如果将输入标签命名为foo,不能在PHP代码中使用变量$foo,除非它被PHP混淆器应用程序的用户明确排除。当然,解决这个问题的方法是使用$_REQUEST、$_POST或$_GET数组处理所有HTML输入变量,因为$_REQUEST['foo']即使在脚本被混淆后仍然有效。
这个混淆器主要是为了编码一个名为PHP Email Manager的PHP软件。这个应用程序要求能够从混淆过程中排除各种文件和变量,以便支持用户在config.php文件中定义的配置。这个文件将为应用程序的其余部分设置变量,但重要的是这个文件保持可读,并且在应用程序的其余部分中表达的变量名称保持不变。
混淆应用有三个主要部分:
使用混淆器类是一个简单的过程,只需实例化一个带有ObfuscatorUI对象参数的混淆器类,并调用Start。ObfuscatorUI是IObfuscatorUI接口的实现,它为混淆器提供了以下函数:StatusUpdate(String)、Done()和Error(string)。通过这三个函数,混淆器类可以在编码源代码的过程中与调用它的任何组件进行通信。
C#
ObfuscatorUI ui = new ObfuscatorUI();
Obfuscator obfuscator = new Obfuscator(ui);
obfuscator.Start(config, false);
在上面的例子中,ObfuscatorUI UI对象是一个简单的类,定义在Program.cs中,它只是将混淆器返回的状态输出到控制台窗口。
混淆器类有三个功能组件:
通过这三个功能的组合,源代码变得难以阅读,但仍然完全可用。
当混淆过程开始时,如果目标目录已经存在,用户会被提示以便可以删除它。删除它是必要的,因为这是将源目录中的每个文件复制和修改的目录。目标目录将成为源目录层次结构的精确副本,除了对所有文件执行的编码。
创建目标目录后,从源目录到目标目录进行递归复制。复制所有文件,无论它们是否被选中进行编码。复制每个文件是为了确保目标目录中的最终结果是一个完整的解决方案,而不仅仅是编码的文件。
一旦所有未编码的文件存在于目标目录中,混淆就开始了。每个被选中的文件都被打开,提取PHP代码块。不应该处理PHP文件的HTML部分。从每个代码块中,移除注释,然后重命名变量(从原始名称创建MD5),然后移除空白。然后使用正则表达式检测此代码块中的函数和类声明,并将它们添加到列表中,以便在所有选定文件的第二遍中重命名,假设它们不匹配phpFunctions类中内置的函数名称列表。