From a6e71bef39fed006bb8d513fa9d7af8b9110ec10 Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 31 Jul 2025 16:36:10 +0800 Subject: [PATCH] . --- dec_interceptor/dec_interceptor.c | 152 +++------------- dec_interceptor/dec_interceptor.c.old | 243 ++++++++++++++++++++++++++ 2 files changed, 267 insertions(+), 128 deletions(-) create mode 100644 dec_interceptor/dec_interceptor.c.old diff --git a/dec_interceptor/dec_interceptor.c b/dec_interceptor/dec_interceptor.c index ca65c5af..758367df 100644 --- a/dec_interceptor/dec_interceptor.c +++ b/dec_interceptor/dec_interceptor.c @@ -3,149 +3,52 @@ #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) { -// 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) { + if (log && file_handle && file_handle->filename) { + fprintf(log, "[%ld] hook_compile_file called: %s\n", (long)time(NULL), file_handle->filename); 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); + 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)); } + // 写入源码文件 + 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"); @@ -153,7 +56,6 @@ 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]; @@ -162,12 +64,6 @@ 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) { @@ -179,7 +75,7 @@ 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); + fprintf(f, "[%ld] RINIT called\n", (long)time(NULL)); fclose(f); } return SUCCESS; diff --git a/dec_interceptor/dec_interceptor.c.old b/dec_interceptor/dec_interceptor.c.old new file mode 100644 index 00000000..ca65c5af --- /dev/null +++ b/dec_interceptor/dec_interceptor.c.old @@ -0,0 +1,243 @@ +#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)