This commit is contained in:
hailin 2025-07-30 19:01:35 +08:00
parent 27a5cfbb5e
commit ac12b34ed5
2 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,100 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dec_interceptor.h"
#include "main/php_streams.h" // ✅ 必须包含,用于 php_stream 结构
static zend_op_array* (*original_compile_file)(zend_file_handle *file_handle, int type);
static zend_op_array* custom_compile_file(zend_file_handle *file_handle, int type) {
fprintf(stderr, "[hook] file_handle->type = %d\n", file_handle->type);
if (file_handle && file_handle->filename) {
const char *source_path = file_handle->filename;
php_printf("[dec_interceptor] compiling: %s\n", source_path);
char *buffer = NULL;
size_t size = 0;
// ✅ 情况1标准文件句柄
if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
FILE *fp = file_handle->handle.fp;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (size > 0 && size < 100 * 1024 * 1024) {
buffer = emalloc(size + 1);
fread(buffer, 1, size, fp);
buffer[size] = '\0';
}
// ✅ 情况2stream 句柄swoole_loader 加密文件解密后走这个分支)
} else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) {
php_stream *stream = (php_stream *)file_handle->handle.stream.handle;
php_stream_seek(stream, 0, SEEK_END);
size = php_stream_tell(stream);
php_stream_seek(stream, 0, SEEK_SET);
if (size > 0 && size < 100 * 1024 * 1024) {
buffer = emalloc(size + 1);
size_t read_bytes = php_stream_read(stream, buffer, size);
buffer[read_bytes] = '\0';
size = read_bytes;
}
}
// ✅ 保存为 .dec.php
if (buffer && size > 0) {
char output_path[PATH_MAX];
snprintf(output_path, sizeof(output_path), "%s.dec.php", source_path);
FILE *out = fopen(output_path, "wb");
if (out) {
fwrite(buffer, 1, size, out);
fclose(out);
fprintf(stderr, "[dump] saved to: %s\n", output_path);
} else {
fprintf(stderr, "[dump] failed to save: %s\n", output_path);
}
efree(buffer);
}
}
return original_compile_file(file_handle, type);
}
PHP_MINIT_FUNCTION(dec_interceptor) {
original_compile_file = zend_compile_file;
zend_compile_file = custom_compile_file;
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(dec_interceptor) {
zend_compile_file = original_compile_file;
return SUCCESS;
}
PHP_MINFO_FUNCTION(dec_interceptor) {
php_info_print_table_start();
php_info_print_table_row(2, "dec_interceptor support", "enabled");
php_info_print_table_end();
}
zend_module_entry dec_interceptor_module_entry = {
STANDARD_MODULE_HEADER,
"dec_interceptor",
NULL,
PHP_MINIT(dec_interceptor),
PHP_MSHUTDOWN(dec_interceptor),
NULL,
NULL,
PHP_MINFO(dec_interceptor),
"0.1",
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE(dec_interceptor)

View File

@ -3,6 +3,7 @@
#include "ext/standard/info.h"
#include "php_dec_interceptor.h"
#include "main/php_streams.h" // ✅ 必须包含,用于 php_stream 结构
#include <string.h> // ✅ 用于 strcmp()
static zend_op_array* (*original_compile_file)(zend_file_handle *file_handle, int type);
@ -11,6 +12,16 @@ static zend_op_array* custom_compile_file(zend_file_handle *file_handle, int typ
if (file_handle && file_handle->filename) {
const char *source_path = file_handle->filename;
// ✅ 仅处理 install.php 文件
const char *filename_only = strrchr(source_path, '/');
if (!filename_only) filename_only = source_path; // 没有 / 就是本身
else filename_only += 1; // skip '/'
if (strcmp(filename_only, "install.php") != 0) {
return original_compile_file(file_handle, type); // ⛔ 忽略非目标文件
}
php_printf("[dec_interceptor] compiling: %s\n", source_path);
char *buffer = NULL;