From 5ee10d32d9a4fa16f9397df925e6e6443d4f186c Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 31 Jul 2025 16:50:03 +0800 Subject: [PATCH] . --- dec_interceptor/dec_interceptor.c | 110 ++++++------ dec_interceptor/dec_interceptor.c.old | 243 -------------------------- 2 files changed, 49 insertions(+), 304 deletions(-) delete mode 100644 dec_interceptor/dec_interceptor.c.old diff --git a/dec_interceptor/dec_interceptor.c b/dec_interceptor/dec_interceptor.c index dcd84d39..79b4dfeb 100644 --- a/dec_interceptor/dec_interceptor.c +++ b/dec_interceptor/dec_interceptor.c @@ -3,103 +3,84 @@ #include "ext/standard/info.h" #include "php_dec_interceptor.h" #include -#include "main/php_streams.h" zend_op_array *(*prev_compile_file)(zend_file_handle *file_handle, int type) = NULL; zend_op_array *(*prev_compile_string)(zend_string *source_string, const char *filename) = NULL; void (*prev_execute_ex)(zend_execute_data *execute_data) = NULL; + zend_op_array *hook_compile_file(zend_file_handle *file_handle, int type) { FILE *log = fopen("/tmp/dec_interceptor.log", "a"); - if (log && file_handle && file_handle->filename) { - fprintf(log, "[%ld] hook_compile_file called: %s\n", (long)time(NULL), file_handle->filename); + if (log) { + fprintf(log, "[%ld] hook_compile_file called\n", (long)time(NULL)); + if (file_handle && file_handle->filename) { + fprintf(log, "[%ld] file_handle->filename = %s\n", (long)time(NULL), file_handle->filename); + } } - // 只针对 install.php(你可自行扩展) + // 判断是否是 install.php 或其他目标加密文件 if (file_handle && file_handle->filename && strstr(file_handle->filename, "install.php")) { - char buffer[32769] = {0}; // 32KB 缓冲 - size_t len = 0; - - php_stream *stream = NULL; - int is_wrapped = 0; - if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { - stream = php_stream_fopen_from_FILE(file_handle->handle.fp, file_handle->filename, "rb"); - is_wrapped = 1; + // 通过 php_stream 读取内容(最多 10KB) + php_stream *stream = php_stream_fopen_from_FILE(file_handle->handle.fp, file_handle->filename, "rb"); + if (stream) { + if (php_stream_seek(stream, 0, SEEK_SET) == 0) { + char buffer[10241] = {0}; // 额外 1 字节存 null terminator + size_t len = php_stream_read(stream, buffer, 10240); + + if (len > 0 && log) { + fprintf(log, "[%ld] [DECRYPTED_STREAM_SOURCE install.php] (%zu bytes):\n", (long)time(NULL), len); + fprintf(log, "%.*s\n", (int)len, buffer); + } + php_stream_seek(stream, 0, SEEK_SET); // 恢复位置 + } + php_stream_close(stream); // 不会关闭 file_handle->handle.fp,只是释放包装层 + } else if (log) { + fprintf(log, "[%ld] failed to wrap fp in php_stream\n", (long)time(NULL)); + } } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) { - stream = (php_stream *)file_handle->handle.stream.handle; - } - - if (stream) { + php_stream *stream = (php_stream *)file_handle->handle.stream.handle; if (php_stream_seek(stream, 0, SEEK_SET) == 0) { - len = php_stream_read(stream, buffer, sizeof(buffer) - 1); - php_stream_seek(stream, 0, SEEK_SET); + char buffer[10241] = {0}; + size_t len = php_stream_read(stream, buffer, 10240); - // 写日志 - if (log && len > 0) { + if (len > 0 && log) { fprintf(log, "[%ld] [DECRYPTED_STREAM_SOURCE install.php] (%zu bytes):\n", (long)time(NULL), len); fprintf(log, "%.*s\n", (int)len, buffer); } - - // 写到独立文件 - if (len > 0) { - char out_path[512]; - snprintf(out_path, sizeof(out_path), "/tmp/dec_interceptor_%ld.php", time(NULL)); - FILE *out = fopen(out_path, "w"); - if (out) { - fwrite(buffer, 1, len, out); - fclose(out); - if (log) fprintf(log, "[%ld] dumped to: %s\n", (long)time(NULL), out_path); - } else if (log) { - fprintf(log, "[%ld] failed to write to output file\n", (long)time(NULL)); - } - } - } else if (log) { - fprintf(log, "[%ld] failed to seek stream\n", (long)time(NULL)); + php_stream_seek(stream, 0, SEEK_SET); } - - if (is_wrapped) php_stream_close(stream); // 只关闭包装的,不破坏原始 fp } else if (log) { - fprintf(log, "[%ld] unsupported file_handle type=%d or failed to wrap stream\n", (long)time(NULL), file_handle->type); + fprintf(log, "[%ld] unsupported file_handle->type: %d\n", (long)time(NULL), file_handle->type); } } - if (log) fclose(log); + if (log) { + fclose(log); + } return prev_compile_file ? prev_compile_file(file_handle, type) : NULL; } + + zend_op_array *hook_compile_string(zend_string *source_string, const char *filename) { - FILE *log = fopen("/tmp/dec_interceptor.log", "a"); - time_t now = time(NULL); - if (log) { - fprintf(log, "[%ld] hook_compile_string: filename = %s, length = %zu\n", - (long)now, filename ? filename : "(null)", ZSTR_LEN(source_string)); + FILE *f = fopen("/tmp/dec_interceptor.log", "a"); + if (f) { + fprintf(f, "[%ld] hook_compile_string: filename = %s\n", (long)time(NULL), filename ? filename : "(null)"); + fprintf(f, "[DECRYPTED] %.*s\n", (int)(ZSTR_LEN(source_string) > 200 ? 200 : ZSTR_LEN(source_string)), ZSTR_VAL(source_string)); + fclose(f); } - // 写入源码文件 - char path[512]; - snprintf(path, sizeof(path), "/tmp/dec_interceptor_%ld.php", now); - FILE *out = fopen(path, "w"); - if (out) { - fwrite(ZSTR_VAL(source_string), 1, ZSTR_LEN(source_string), out); - fclose(out); - if (log) { - fprintf(log, "[%ld] [DUMPED] wrote source to: %s\n", (long)now, path); - } - } else if (log) { - fprintf(log, "[%ld] [ERROR] failed to write file: %s\n", (long)now, path); - } - - if (log) fclose(log); return prev_compile_string ? prev_compile_string(source_string, filename) : NULL; } void hook_execute_ex(zend_execute_data *execute_data) { const zend_function *func = execute_data->func; + if (func && ZEND_USER_CODE(func->type)) { const zend_op_array *opa = &func->op_array; FILE *f = fopen("/tmp/dec_interceptor.log", "a"); @@ -107,6 +88,7 @@ void hook_execute_ex(zend_execute_data *execute_data) const char *fname = func->common.function_name ? ZSTR_VAL(func->common.function_name) : "(no name)"; const char *file = opa->filename ? ZSTR_VAL(opa->filename) : "(no file)"; fprintf(f, "[%ld] hook_execute_ex: %s (from %s)\n", (long)time(NULL), fname, file); + fprintf(f, " op_array dump: %d opcodes\n", opa->last); for (int i = 0; i < opa->last; ++i) { const zend_op *op = &opa->opcodes[i]; @@ -115,6 +97,12 @@ void hook_execute_ex(zend_execute_data *execute_data) } fclose(f); } + } else { + FILE *f = fopen("/tmp/dec_interceptor.log", "a"); + if (f) { + fprintf(f, "[%ld] hook_execute_ex: (internal or unknown function)\n", (long)time(NULL)); + fclose(f); + } } if (prev_execute_ex) { @@ -126,7 +114,7 @@ PHP_RINIT_FUNCTION(dec_interceptor) { FILE *f = fopen("/tmp/dec_interceptor.log", "a"); if (f) { - fprintf(f, "[%ld] RINIT called\n", (long)time(NULL)); + fprintf(f, "[%ld] RINIT: zend_compile_file = %p\n", (long)time(NULL), zend_compile_file); fclose(f); } return SUCCESS; diff --git a/dec_interceptor/dec_interceptor.c.old b/dec_interceptor/dec_interceptor.c.old deleted file mode 100644 index ca65c5af..00000000 --- a/dec_interceptor/dec_interceptor.c.old +++ /dev/null @@ -1,243 +0,0 @@ -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_dec_interceptor.h" -#include - -zend_op_array *(*prev_compile_file)(zend_file_handle *file_handle, int type) = NULL; -zend_op_array *(*prev_compile_string)(zend_string *source_string, const char *filename) = NULL; -void (*prev_execute_ex)(zend_execute_data *execute_data) = NULL; - - -// zend_op_array *hook_compile_file(zend_file_handle *file_handle, int type) -// { -// FILE *log = fopen("/tmp/dec_interceptor.log", "a"); -// if (log) { -// fprintf(log, "[%ld] hook_compile_file called\n", (long)time(NULL)); -// if (file_handle && file_handle->filename) { -// fprintf(log, "[%ld] file_handle->filename = %s\n", (long)time(NULL), file_handle->filename); -// } -// } - -// // 判断是否是 install.php 或其他目标加密文件 -// if (file_handle && file_handle->filename && strstr(file_handle->filename, "install.php")) { -// if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { -// // 通过 php_stream 读取内容(最多 10KB) -// php_stream *stream = php_stream_fopen_from_FILE(file_handle->handle.fp, file_handle->filename, "rb"); -// if (stream) { -// if (php_stream_seek(stream, 0, SEEK_SET) == 0) { -// char buffer[10241] = {0}; // 额外 1 字节存 null terminator -// size_t len = php_stream_read(stream, buffer, 10240); - -// if (len > 0 && log) { -// fprintf(log, "[%ld] [DECRYPTED_STREAM_SOURCE install.php] (%zu bytes):\n", (long)time(NULL), len); -// fprintf(log, "%.*s\n", (int)len, buffer); -// } -// php_stream_seek(stream, 0, SEEK_SET); // 恢复位置 -// } -// php_stream_close(stream); // 不会关闭 file_handle->handle.fp,只是释放包装层 -// } else if (log) { -// fprintf(log, "[%ld] failed to wrap fp in php_stream\n", (long)time(NULL)); -// } -// } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) { -// php_stream *stream = (php_stream *)file_handle->handle.stream.handle; -// if (php_stream_seek(stream, 0, SEEK_SET) == 0) { -// char buffer[10241] = {0}; -// size_t len = php_stream_read(stream, buffer, 10240); - -// if (len > 0 && log) { -// fprintf(log, "[%ld] [DECRYPTED_STREAM_SOURCE install.php] (%zu bytes):\n", (long)time(NULL), len); -// fprintf(log, "%.*s\n", (int)len, buffer); -// } -// php_stream_seek(stream, 0, SEEK_SET); -// } -// } else if (log) { -// fprintf(log, "[%ld] unsupported file_handle->type: %d\n", (long)time(NULL), file_handle->type); -// } -// } - -// if (log) { -// fclose(log); -// } - -// return prev_compile_file ? prev_compile_file(file_handle, type) : NULL; -// } - - -zend_op_array *hook_compile_file(zend_file_handle *file_handle, int type) -{ - FILE *log = fopen("/tmp/dec_interceptor.log", "a"); - if (log) { - fprintf(log, "[%ld] hook_compile_file called\n", (long)time(NULL)); - if (file_handle && file_handle->filename) { - fprintf(log, "[%ld] file_handle->filename = %s\n", (long)time(NULL), file_handle->filename); - } - } - - if (file_handle && file_handle->filename && strstr(file_handle->filename, "install.php")) { - char buffer[10241] = {0}; // 最多 10KB + null terminator - size_t len = 0; - - if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { - php_stream *stream = php_stream_fopen_from_FILE(file_handle->handle.fp, file_handle->filename, "rb"); - if (stream) { - if (php_stream_seek(stream, 0, SEEK_SET) == 0) { - len = php_stream_read(stream, buffer, 10240); - php_stream_seek(stream, 0, SEEK_SET); - } - php_stream_close(stream); - } else if (log) { - fprintf(log, "[%ld] failed to wrap fp in php_stream\n", (long)time(NULL)); - } - } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) { - php_stream *stream = (php_stream *)file_handle->handle.stream.handle; - if (php_stream_seek(stream, 0, SEEK_SET) == 0) { - len = php_stream_read(stream, buffer, 10240); - php_stream_seek(stream, 0, SEEK_SET); - } - } else if (log) { - fprintf(log, "[%ld] unsupported file_handle->type: %d\n", (long)time(NULL), file_handle->type); - } - - if (len > 0) { - if (log) { - fprintf(log, "[%ld] [DECRYPTED_STREAM_SOURCE install.php] (%zu bytes):\n", (long)time(NULL), len); - fprintf(log, "%.*s\n", (int)len, buffer); - } - - // ✅ 保存为独立文件 - char path[512]; - snprintf(path, sizeof(path), "/tmp/dec_interceptor_%ld_install.php", time(NULL)); - FILE *out = fopen(path, "w"); - if (out) { - fwrite(buffer, 1, len, out); - fclose(out); - if (log) { - fprintf(log, "[%ld] source dumped to file: %s\n", (long)time(NULL), path); - } - } else if (log) { - fprintf(log, "[%ld] failed to write to %s\n", (long)time(NULL), path); - } - } - } - - if (log) { - fclose(log); - } - - return prev_compile_file ? prev_compile_file(file_handle, type) : NULL; -} - - - -zend_op_array *hook_compile_string(zend_string *source_string, const char *filename) -{ - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - fprintf(f, "[%ld] hook_compile_string: filename = %s\n", (long)time(NULL), filename ? filename : "(null)"); - fprintf(f, "[DECRYPTED] %.*s\n", (int)(ZSTR_LEN(source_string) > 200 ? 200 : ZSTR_LEN(source_string)), ZSTR_VAL(source_string)); - fclose(f); - } - - return prev_compile_string ? prev_compile_string(source_string, filename) : NULL; -} - -void hook_execute_ex(zend_execute_data *execute_data) -{ - const zend_function *func = execute_data->func; - - if (func && ZEND_USER_CODE(func->type)) { - const zend_op_array *opa = &func->op_array; - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - const char *fname = func->common.function_name ? ZSTR_VAL(func->common.function_name) : "(no name)"; - const char *file = opa->filename ? ZSTR_VAL(opa->filename) : "(no file)"; - fprintf(f, "[%ld] hook_execute_ex: %s (from %s)\n", (long)time(NULL), fname, file); - - fprintf(f, " op_array dump: %d opcodes\n", opa->last); - for (int i = 0; i < opa->last; ++i) { - const zend_op *op = &opa->opcodes[i]; - fprintf(f, " [%03d] opcode=%d op1_type=%d op2_type=%d result_type=%d\n", - i, op->opcode, op->op1_type, op->op2_type, op->result_type); - } - fclose(f); - } - } else { - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - fprintf(f, "[%ld] hook_execute_ex: (internal or unknown function)\n", (long)time(NULL)); - fclose(f); - } - } - - if (prev_execute_ex) { - prev_execute_ex(execute_data); - } -} - -PHP_RINIT_FUNCTION(dec_interceptor) -{ - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - fprintf(f, "[%ld] RINIT: zend_compile_file = %p\n", (long)time(NULL), zend_compile_file); - fclose(f); - } - return SUCCESS; -} - -PHP_MINIT_FUNCTION(dec_interceptor) -{ - prev_compile_file = zend_compile_file; - zend_compile_file = hook_compile_file; - - prev_compile_string = zend_compile_string; - zend_compile_string = hook_compile_string; - - prev_execute_ex = zend_execute_ex; - zend_execute_ex = hook_execute_ex; - - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - fprintf(f, "[%ld] MINIT done\n", (long)time(NULL)); - fclose(f); - } - - return SUCCESS; -} - -PHP_MSHUTDOWN_FUNCTION(dec_interceptor) -{ - zend_compile_file = prev_compile_file; - zend_compile_string = prev_compile_string; - zend_execute_ex = prev_execute_ex; - - FILE *f = fopen("/tmp/dec_interceptor.log", "a"); - if (f) { - fprintf(f, "[%ld] MSHUTDOWN done\n", (long)time(NULL)); - fclose(f); - } - - 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), - PHP_RINIT(dec_interceptor), - NULL, - PHP_MINFO(dec_interceptor), - PHP_DEC_INTERCEPTOR_VERSION, - STANDARD_MODULE_PROPERTIES -}; - -ZEND_GET_MODULE(dec_interceptor)