win下编译tonyenc扩展并使用加密php代码
事出有因,因为公司的web项目是安装在win上的(不要疑惑,就是win,受限于领域和市场等要素,以后再聊这个),提出要对php代码进行加密,经讨论确定使用tonyenc扩展进行php代码加密(之前说使用yakpro.po进行代码混淆,所有工程弄完发现不妥,然后自己有尝试来php-beast扩展,然后还是用不上,大家有需要在出教程吧)
然后我上网查到有现成的tonyenc.dll扩展可用,可无奈php版本对不上,无法加载使用,会报错
[26-May-2020 01:22:53 UTC] PHP Warning: PHP Startup: Unable to load dynamic library 'D:/ipwebV2/PHP7/ext\php_tonyenc_php70_x64_nts.dll' - %1 不是有效的 Win32 应用程序
于是乎上网查资料,看到有前人已实现,PHP7VS2015,故在其基础之上实操并完善下教程,并不是说原博主的文章有误,只是添加了些细节,毕竟遇到了各种坑。
其中我省去了编译安装php的过程,因为我本机已安装来php7.0.1,直接安装自己需要的扩展就好了。
一、准备工具和文件
以下工具都是本人成功编译php7.0.1的工具列表,可能如果你要编译的php版本不同需要不同对应不同版本工具或运行库。
如果你所在的网络不稳定,可能第一步就需要花你很长时间;如果你软件安装过程中出错,你可能需要花更多的时间;如果你坚持,那你花的时间都是值得的。
Visual Studio 2015
![](https://img.haomeiwen.com/i7429691/900be82d7d8ce1b6.png)
网上说php7要用Visual Studio 2015
VC14运行库
![](https://img.haomeiwen.com/i7429691/9b74f12977dc5777.png)
vc14运行库在哪个地方下载都可以,当然无毒是前提。
如果你本地已安装更高版本的运行库,例如2017,可能你安装不了,需要卸载在重新安装vc14。
cygwin工具
![](https://img.haomeiwen.com/i7429691/92f0f0a19766c80b.png)
Cygwin是一个在windows平台上运行的类UNIX模拟环境,是cygnus solutions公司开发的自由软件(该公司开发的著名工具还有eCos,不过现已被Redhat收购)。它对于学习UNIX/Linux操作环境,或者从UNIX到Windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用GNU工具集在Windows上进行嵌入式系统开发,非常有用
默认安装到C:\cygwin,这样就不需要修改ext_skel_win32.php
php7的sdk工具
![](https://img.haomeiwen.com/i7429691/6925313c547a2c85.png)
下载deps-7.1-vc14-x86.7z
![](https://img.haomeiwen.com/i7429691/e46062a51471a214.png)
php7.0.1源码
![](https://img.haomeiwen.com/i7429691/4f0ad00d8bf1c746.png)
下载tonyenc扩展源码
二、方法步骤
1、解压sdk工具包
解压PHP-sdk-binary-tools-20110915.zip,例如解压到D:\vcmyprojects\php-sdk,目录结构如下:
> D:\vcmyprojects\php-sdk
> -- bin
> -- script
> -- share
![](https://img.haomeiwen.com/i7429691/018fda8c6815fe2b.png)
2、打开VS2015开发人员命令行提示(切记)
在win左下角的搜索里输入vs2015,然后进入目录D:\vcmyprojects\php-sdk
D:
cd D:\vcmyprojects\php-sdk
![](https://img.haomeiwen.com/i7429691/6b2362d7d9c60dfe.png)
3、设置环境变量
添加D:\vcmyprojects\php-sdk\bin到path
D:\vcmyprojects\php-sdk\bin
4、编辑phpsdk_buildtree.bat
编辑D:\vcmyprojects\php-sdk\bin\phpsdk_buildtree.bat
在GOTO EXIT前加入
MD %_%\vc14\x86\deps\bin
MD %_%\vc14\x86\deps\lib
MD %_%\vc14\x86\deps\include
MD %_%\vc14\x64\deps\bin
MD %_%\vc14\x64\deps\lib
MD %_%\vc14\x64\deps\include
5、创建php-sdk目录phpdev
phpsdk_buildtree.bat phpdev
查看D:\vcmyprojects\php-sdk目录下多了一个phpdev文件夹
6、解压deps-7.0-vc14-x86.7z覆盖
解压deps-7.0-vc14-x86.7z的内容覆盖到D:\vcmyprojects\php-sdk\phpdev\vc14\x86\deps,是我们必要的库文件和工具
![](https://img.haomeiwen.com/i7429691/5d68302f356adbf6.png)
7、解压php7.0.1源码
解压php7.0.1源代码(如果你下载的文件带php.exe就不是源码)到D:\vcmyprojects\php-sdk\phpdev\vc14\x86,命名为php-7.0.1-src
![](https://img.haomeiwen.com/i7429691/a400efd2064411eb.png)
8、编译php的tonyenc扩展
进入前面生成的扩展文件夹内,执行ext_skel_win32.php文件
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\ext
php ext_skel_win32.php --extname=tonyenc
然后你就在ext文件夹内看到生成来tonyenc文件夹
![](https://img.haomeiwen.com/i7429691/102d58c3858223c6.png)
9、使用VS2015打开并设置参数
打开软件,如果新建出错看下是不是缺少c++的运行环境,根据错误查下缺了什么吧。
我们来新建一个现有项目
![](https://img.haomeiwen.com/i7429691/ee24e5015a07d991.png)
选择C + +
![](https://img.haomeiwen.com/i7429691/5d702ed5fd773e4a.png)
选择你的php扩展文件夹路径,命名tonyenc
![](https://img.haomeiwen.com/i7429691/0a9d88d190de8572.png)
选择动态链接库(DLL)项目
![](https://img.haomeiwen.com/i7429691/dcd50853a2399a50.png)
直接下一步,后面再设置
![](https://img.haomeiwen.com/i7429691/75fdcfff9d144efa.png)
设置Release
![](https://img.haomeiwen.com/i7429691/dc1f30388bd5c5e6.png)
右键项目属性,C/C++,常规,附加包含目录,编辑
![](https://img.haomeiwen.com/i7429691/22a3036ea97dc25a.png)
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\main
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\main
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\Zend
D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\ext\standard
![](https://img.haomeiwen.com/i7429691/d501a0f2c4e3d159.png)
右键项目属性,C/C++,预处理器,预处理器定义,编辑,加入以下变量:
WIN32
NDEBUG
_WINDOWS
_USRDLL
TONYENC_EXPORTS
![](https://img.haomeiwen.com/i7429691/0cb7a95d6d5d0b31.png)
再链接器-常规中加入
D:\ipwebV2\PHP7\dev
![](https://img.haomeiwen.com/i7429691/48b08a9168d1148a.png)
再链接器-输入中加入
php7.lib
![](https://img.haomeiwen.com/i7429691/f3fb64e83771a8fe.png)
然后把 D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\win32\build\config.w32.h.in 复制到 D:\vcmyprojects\php-sdk\phpdev\vc14\x86\php-7.0.1-src\main\config.w32.h (注意没有了后面的 in),然后在 config.w32.h 中加入:
#define PHP_COMPILER_ID "VC14"
10、覆盖tonyenc代码
用网上下载tonyenc代码,覆盖tonyenc下代码,点击生成,生成解决方案,将可以在tonyenc目录下存在一个tonyenc.dll文件,这个就是我要的加密扩展了。
![](https://img.haomeiwen.com/i7429691/13caf77c93556a02.png)
三、使用tonyenc扩展加密代码
![](https://img.haomeiwen.com/i7429691/87fed13321b67193.png)
在win,基于php7.0.1版本下,使用VS2015编译了tonyenc.dll扩展。
1、加密特征头和密钥
16进制,自己随便改,这样别人将不容易解密你的代码了
/* Modify tonyenc_header to disguise your encrypt file */
const u_char tonyenc_header[] = {
0x66, 0x88, 0xff, 0x4f,
0x68, 0x86, 0x00, 0x56,
0x11, 0x61, 0x16, 0x18,
};
/* Modify tonyenc_key to set the secret key */
const u_char tonyenc_key[] = {
0x9f, 0x49, 0x52, 0x00,
0x58, 0x9f, 0xff, 0x23,
0x8e, 0xfe, 0xea, 0xfa,
0xa6, 0x33, 0xf3, 0xc6,
};
2、win使用扩展
- 将仅加密的tonyenc.dll扩展放置php扩展加载目录中
- 编辑php.ini文件,添加使用扩展
3、检验是否加载扩展成功
如果在win下设置了php环境变量则
php -m
4、加密方法
指定加密文件或某一目录下的php文件进行加密(如果是相对路径必须确保能找到改文件或目录)),然后执行命令,例:(执行文件见附件)
加密文件
php tonyenc.php test.php
加密目录
test下有a.php b.php 均会被加密
php tonyenc.php test
效果
原文件内容
<?php
echo "Hello World";
加密后内容
fˆÿOj‹[�b��<_pÅp
�eÕh 1H�l`o‡WÙrÚdÝ;
5、验证方法
将刚刚加密后的源代码在任何未集成该tonyenc php扩展的运行环境中,全部报错,无法运行,同时打开源代码,发现全部是大小写字母、数字、特殊字符等等组成的加密文件,完全无法辨识,当在有集成该tonyenc php 扩展的运行环境中打开时,运行完全正常。
6、测试
加密扩展 | 代码 | 功能 | 性能 |
---|---|---|---|
加载 | 加密 | 正常 | 待测试 |
加载 | 不加密 | 正常 | 待测试 |
不加载 | 不加密 | 正常 | 待测试 |
不加载 | 加密 | 不正常 | 待测试 |
7、tonyenc.php代码
<?php
/**
* tonyenc.php: Encrypt or decrypt the script with tonyenc.
*
* A high performance and cross-platform encrypt extension for PHP source code.
*
* @author: Tony
* @site: lihancong.cn
* @github: github.com/lihancong/tonyenc
*/
if (version_compare(PHP_VERSION, 7, '<'))
die("PHP must later than version 7.0\n");
if (php_sapi_name() !== 'cli')
die("Must run in cli mode\n");
if (!extension_loaded('tonyenc'))
die("The extension: 'tonyenc' not loaded\n");
if ($argc <= 1)
die("\nusage: php tonyenc.php file.php ... encrypt the php file(s) or directory(s)\n\n");
array_shift($argv);
foreach ($argv as $fileName) {
if (is_file($fileName)) {
handle($fileName);
} elseif (is_dir($fileName)) {
$DirectoriesIt = new RecursiveDirectoryIterator($fileName, FilesystemIterator::SKIP_DOTS);
$AllIt = new RecursiveIteratorIterator($DirectoriesIt);
$it = new RegexIterator($AllIt, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);
foreach ($it as $v)
handle($v[0]);
} else {
echo "Unknowing file: '$fileName'\n";
}
}
function handle($file)
{
if ($fp = fopen($file, 'rb+') and $fileSize = filesize($file)) {
$data = tonyenc_encode(fread($fp, $fileSize));
if ($data !== false) {
if (file_put_contents($file, '') !== false) {
rewind($fp);
fwrite($fp, $data);
}
}
fclose($fp);
}
}