1.下载php源码
进入官网找到相应的版本下载地址
wget -c https://www.php.net/distributions/php-8.1.11.tar.gz
2.编译并安装php
解压下载的文件后进入目录
./buildconf --force
./configure --prefix=/usr/local/soft/php8 --with-config-file-path=/usr/local/soft/php8/etc --with-curl --with-freetype --enable-gd --with-jpeg --with-gettext --with-kerberos --with-libdir=lib64 --with-libxml --with-mysqli --with-openssl --with-pdo-mysql --with-pdo-sqlite --with-pear --enable-sockets --with-mhash --with-ldap-sasl --with-xsl --with-zlib --with-zip -with-bz2 --with-iconv --enable-fpm --enable-pdo --enable-ftp --enable-bcmath --enable-mbregex --enable-mbstring --enable-opcache --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvsem --enable-xml --enable-sysvsem --enable-cli --enable-opcache --enable-intl --enable-calendar --enable-static --enable-mysqlnd
make && make install
3.生成自定义扩展
1.php安装完成后进入源码路径
cd /usr/local/src/php-src-php-8.1.11
2.使用脚手架
#php ext/ext_skel.php --ext <name>
php ext/ext_skel.php --ext yaoling_encrypt_file
3.验证
看到ext目录下生成 yaoling_encrypt_file 文件夹即为成功
4.开发自定义扩展
1.修改yaoling_encrypt_file.stub.php 自定义方法 跟php语法一致
<?php
/** @generate-class-entries */
function encrypt_file_cache(string $fileName = '',string $fileData = ''): string
{
}
2.执行源码中脚手架gen_stub.php生成头文件
php build/gen_stub.php ext/yaoling_encrypt_file/yaoling_encrypt_file.stub.php
3.修改源码
zend_module_entry yaoling_encrypt_file_module_entry = {
STANDARD_MODULE_HEADER,
"yaoling_encrypt_file", /* 扩展名 */
ext_functions, /* zend_function_entry */
NULL, /* PHP_MINIT - Module initialization 模块初始化加载 【进程启动】*/
NULL, /* PHP_MSHUTDOWN - Module shutdown 模块卸载 【进程停止】*/
PHP_RINIT(yaoling_encrypt_file), /* PHP_RINIT - Request initialization 每次请求*/
NULL, /* PHP_RSHUTDOWN - Request shutdown 每次请求结束*/
PHP_MINFO(yaoling_encrypt_file), /* PHP_MINFO - Module info 扩展信息 phpinfo中能看到*/
PHP_YAOLING_ENCRYPT_FILE_VERSION, /* Version */
STANDARD_MODULE_PROPERTIES
};
4.定义扩展的方法
PHP_FUNCTION(encrypt_file_cache)
{
zend_string *fileName = NULL;
zend_string *fileData = NULL;
//参数
ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_STR(fileName)
Z_PARAM_STR(fileData)
ZEND_PARSE_PARAMETERS_END();
//todo
zend_string *retval = strpprintf(0, "fileName %s => fileData %s", fileName->val, fileData->val);
RETURN_STR(retval);
}
5.编译测试安装
phpize #phpize的路径
./configure --with-php-config=/usr/local/php8.1.11/bin/php-config #php-config的路径
make
1.测试文件
--TEST--
encrypt_file_cache($fileName, $fileData) function
--EXTENSIONS--
yaoling_encrypt_file
--FILE--
<?php
encrypt_file_cache('fileName','fileData');
echo "Done\n";
?>
--EXPECT--
Done
2.执行
make test
3.查看结果
PASS Check if yaoling_encrypt_file is loaded [tests/001.phpt]
PASS encrypt_file_cache($fileName, $fileData) function [tests/002.phpt]
=====================================================================
TEST RESULT SUMMARY
---------------------------------------------------------------------
Exts skipped : 0
Exts tested : 40
---------------------------------------------------------------------
Number of tests : 2 2
Tests skipped : 0 ( 0.0%) --------
Tests warned : 0 ( 0.0%) ( 0.0%)
Tests failed : 0 ( 0.0%) ( 0.0%)
Tests passed : 2 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken : 0 seconds
=====================================================================
4.安装
make instll
----------------------------------------------------------------------
Installing shared extensions: /usr/local/php8.1.11/lib/php/extensions/no-debug-non-zts-20210902/
ls -la /usr/local/php8.1.11/lib/php/extensions/no-debug-non-zts-20210902/
total 38712
······
-rwxr-xr-x 1 pengbin staff 51700 2 28 09:27 yaoling_encrypt_file.so
·····
5.验证
php -m|grep yaoling_encrypt_file
php -r "var_dump(encrypt_file_cache('k','v'));"
string(24) "fileName k => fileData v"
6.源码解密
1.定义一个hook
static zend_op_array *(*orig_compile_file)(zend_file_handle *file_handle, int type);
2.修改
/* {{{ PHP_MINIT_FUNCTION 每次request时修改zend_compile_file
*/
PHP_MINIT_FUNCTION(yaoling_encrypt)
{
//替换
orig_compile_file = zend_compile_file;
zend_compile_file = yaoling_compile_file;
return SUCCESS;
}
/* }}} */
//还原 zend_compile_file
PHP_MSHUTDOWN_FUNCTION(yaoling_encrypt)
{
zend_compile_file = orig_compile_file;
return SUCCESS;
}
3.解密
zend_op_array *yaoling_compile_file(zend_file_handle *file_handle, int type)
{
//todo 执行解密
return orig_compile_file(file_handle, type);
}
3.1 打开文件
// 打开源文件
FILE *fp = fopen(file_handle->filename->val, "rb");
3.2 验证文件是否符合解密
// key header
bool key_tag = true;
for (int i = 0; i < strlen(YAOLING_ENCRYPT_LIB); i++)
{
int a = fscanf(fp, "%hd", &temp);
temp <<= 1;
temp >>= 5;
char ch = (char)temp;
//不满足的头信息会直接退出
if (toascii(ch) - toascii(YAOLING_ENCRYPT_LIB[i]) != 0 || !ch)
{
key_tag = false;
break;
}
}
// header不满足
if (key_tag == false)
{
return orig_compile_file(file_handle, type);
}
3.3 解密真正的body
if (file_handle->type == ZEND_HANDLE_FP)
fclose(file_handle->handle.fp);
#ifdef ZEND_HANDLE_FD
if (file_handle->type == ZEND_HANDLE_FD)
close(file_handle->handle.fd);
#endif
file_handle->type = ZEND_HANDLE_FP;
fp = tmpfile();
fwrite(realbuf, 1, reallen, fp);
rewind(fp);
file_handle->handle.fp = fp;
free(realbuf);
return orig_compile_file(file_handle, type);
8.加解密原理
一个char 8位 00000000
以大写字母(A-Z):65 (A)~ 90(Z)中Z为例
字母Z 对应 二进制为: 01011010
1.加密
1.char 转为 short
对应二进制为: 0000000001011010
1.左移4位
二进制变为:0000010110100000
2.或运算
0x8000 转为二进制 111100000000
0000010110100000 |111100000000 = 1111010110100000
3.随机数
0-16的随机数 随机数 %16 不包含16
1111010110101111 转为short 存入文件
2.解密
1111010110101111
1.左移 1位
1110101101011110
2.又移动5位
0000011101011010
3.short转为char
0000011101011010 拿到 01011010转为对应的字符
标签:enable,encrypt,--,扩展,开发,file,handle,php From: https://www.cnblogs.com/pengb/p/17169231.html