From d0b8d25070d868a3bd1d6717653741f178714ea0 Mon Sep 17 00:00:00 2001 From: hailin Date: Wed, 30 Jul 2025 17:41:24 +0800 Subject: [PATCH] . --- dec_interceptor/dec_interceptor.c | 68 ++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/dec_interceptor/dec_interceptor.c b/dec_interceptor/dec_interceptor.c index f7765233..e33248bf 100644 --- a/dec_interceptor/dec_interceptor.c +++ b/dec_interceptor/dec_interceptor.c @@ -6,43 +6,63 @@ 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) { - // 尝试拷贝解密后的 PHP 文件 - if (file_handle && file_handle->filename && file_handle->handle.fp) { - const char *source_path = file_handle->filename; + fprintf(stderr, "[hook] file_handle->type = %d\n", file_handle->type); - php_printf("[dec_interceptor] compiling: %s\n", source_path); // ✅ 输出调试信息 - - FILE *fp = fopen(source_path, "rb"); - if (fp) { + 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:标准文件句柄(明文 PHP 文件) + if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { + FILE *fp = file_handle->handle.fp; fseek(fp, 0, SEEK_END); - long size = ftell(fp); + size = ftell(fp); fseek(fp, 0, SEEK_SET); - if (size > 0 && size < 100 * 1024 * 1024) { // 限制大小避免错误 - char *buffer = emalloc(size + 1); + if (size > 0 && size < 100 * 1024 * 1024) { + buffer = emalloc(size + 1); fread(buffer, 1, size, fp); buffer[size] = '\0'; - fclose(fp); - - // 保存到同目录 .dec.php 文件 - 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); - } - - efree(buffer); } + + // ✅ 情况2:stream(Swoole 加密文件,通过 swoole_loader 解密) + } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.reader) { + zend_stream_handle *stream = &file_handle->handle.stream; + size = stream->handle.len; + if (size > 0 && size < 100 * 1024 * 1024) { + buffer = emalloc(size + 1); + size_t read_bytes = stream->reader(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); } } - // 调用原始编译器 + // 调用原始 Zend 编译器 return original_compile_file(file_handle, type); } + PHP_MINIT_FUNCTION(dec_interceptor) { original_compile_file = zend_compile_file; zend_compile_file = custom_compile_file;