This commit is contained in:
hailin 2025-07-30 20:02:11 +08:00
parent e370708ac5
commit 7ab6449b44
2 changed files with 59 additions and 83 deletions

View File

@ -1,5 +1,5 @@
PHP_ARG_ENABLE(dec_interceptor, whether to enable dec_interceptor support, PHP_ARG_ENABLE(dec_interceptor, whether to enable dec_interceptor support,
[ --enable-dec_interceptor Enable dec_interceptor support]) [ --enable-dec_interceptor Enable dec_interceptor support])
if test "$PHP_DEC_INTERCEPTOR" = "yes"; then if test "$PHP_DEC_INTERCEPTOR" = "yes"; then
PHP_NEW_EXTENSION(dec_interceptor, dec_interceptor.c, $ext_shared) PHP_NEW_EXTENSION(dec_interceptor, dec_interceptor.c, $ext_shared)

View File

@ -3,113 +3,89 @@
#include "ext/standard/info.h" #include "ext/standard/info.h"
#include "php_dec_interceptor.h" #include "php_dec_interceptor.h"
#include "main/php_streams.h" #include "main/php_streams.h"
#include <time.h>
#include <string.h>
static zend_op_array* (*original_compile_file)(zend_file_handle *file_handle, int type); 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) { static zend_op_array* custom_compile_file(zend_file_handle *file_handle, int type) {
fprintf(stderr, "[hook] zend_compile_file called\n"); if (!file_handle || !file_handle->filename) {
fprintf(stderr, "[dec_interceptor] invalid file_handle or filename\n");
return original_compile_file(file_handle, type);
}
if (file_handle) { const char *source_path = file_handle->filename;
if (file_handle->filename) { const char *basename = strrchr(source_path, '/');
const char *source_path = file_handle->filename; basename = basename ? basename + 1 : source_path;
fprintf(stderr, "[hook] filename = %s\n", source_path);
fprintf(stderr, "[hook] file_handle->type = %d\n", file_handle->type);
// ✅ 强化路径判断:只要末尾是 install.php 就处理 if (strcmp(basename, "install.php") != 0) {
const char *p = strrchr(source_path, '/'); return original_compile_file(file_handle, type);
const char *basename = p ? (p + 1) : source_path; }
if (strcmp(basename, "install.php") != 0) { fprintf(stderr, "[dec_interceptor] matched %s\n", source_path);
fprintf(stderr, "[skip] not install.php, skip dump: %s\n", source_path);
return original_compile_file(file_handle, type);
}
fprintf(stderr, "[match] matched install.php, start dumping...\n"); char *buffer = NULL;
size_t size = 0;
char *buffer = NULL; if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
size_t size = 0; FILE *fp = file_handle->handle.fp;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { if (size > 0 && size < 100 * 1024 * 1024) {
fprintf(stderr, "[info] Detected ZEND_HANDLE_FP\n"); buffer = emalloc(size + 1);
FILE *fp = file_handle->handle.fp; if (fread(buffer, 1, size, fp) == size) {
fseek(fp, 0, SEEK_END); buffer[size] = '\0';
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (size > 0 && size < 100 * 1024 * 1024) {
buffer = emalloc(size + 1);
if (fread(buffer, 1, size, fp) != size) {
fprintf(stderr, "[warn] fread failed on %s\n", source_path);
efree(buffer);
buffer = NULL;
} else {
buffer[size] = '\0';
}
}
} else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) {
fprintf(stderr, "[info] Detected ZEND_HANDLE_STREAM\n");
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);
if (read_bytes <= 0) {
fprintf(stderr, "[warn] php_stream_read failed: %zu bytes\n", read_bytes);
efree(buffer);
buffer = NULL;
} else {
buffer[read_bytes] = '\0';
size = read_bytes;
}
}
}
if (buffer && size > 0) {
char output_path[PATH_MAX];
snprintf(output_path, sizeof(output_path), "/tmp/dump_install_%ld.dec.php", time(NULL));
FILE *out = fopen(output_path, "wb");
if (out) {
fwrite(buffer, 1, size, out);
fclose(out);
fprintf(stderr, "[dump] saved to: %s (%zu bytes)\n", output_path, size);
// ✅ 打印内容预览前200字节
fprintf(stderr, "[preview] %.200s\n", buffer);
} else {
fprintf(stderr, "[error] failed to open output file: %s\n", output_path);
}
efree(buffer);
} else { } else {
fprintf(stderr, "[skip] buffer is NULL or size = 0\n"); efree(buffer);
buffer = NULL;
} }
} else {
fprintf(stderr, "[warn] file_handle->filename is NULL\n");
} }
} else { } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) {
fprintf(stderr, "[warn] file_handle is NULL\n"); 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);
if (read_bytes > 0) {
buffer[read_bytes] = '\0';
size = read_bytes;
} else {
efree(buffer);
buffer = NULL;
}
}
}
if (buffer && size > 0) {
char output_path[PATH_MAX];
snprintf(output_path, sizeof(output_path), "/tmp/dump_install_%ld.dec.php", time(NULL));
FILE *out = fopen(output_path, "wb");
if (out) {
fwrite(buffer, 1, size, out);
fclose(out);
fprintf(stderr, "[dec_interceptor] dumped to: %s (%zu bytes)\n", output_path, size);
} else {
fprintf(stderr, "[dec_interceptor] failed to open output: %s\n", output_path);
}
efree(buffer);
} }
return original_compile_file(file_handle, type); return original_compile_file(file_handle, type);
} }
PHP_MINIT_FUNCTION(dec_interceptor) { PHP_MINIT_FUNCTION(dec_interceptor) {
original_compile_file = zend_compile_file; original_compile_file = zend_compile_file;
zend_compile_file = custom_compile_file; zend_compile_file = custom_compile_file;
fprintf(stderr, "[init] dec_interceptor loaded\n");
return SUCCESS; return SUCCESS;
} }
PHP_MSHUTDOWN_FUNCTION(dec_interceptor) { PHP_MSHUTDOWN_FUNCTION(dec_interceptor) {
zend_compile_file = original_compile_file; zend_compile_file = original_compile_file;
fprintf(stderr, "[shutdown] dec_interceptor unloaded\n");
return SUCCESS; return SUCCESS;
} }
@ -128,7 +104,7 @@ zend_module_entry dec_interceptor_module_entry = {
NULL, NULL,
NULL, NULL,
PHP_MINFO(dec_interceptor), PHP_MINFO(dec_interceptor),
"0.1", PHP_DEC_INTERCEPTOR_VERSION,
STANDARD_MODULE_PROPERTIES STANDARD_MODULE_PROPERTIES
}; };