php-8.0.30-src/dec_interceptor copy.c

136 lines
4.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dec_interceptor.h"
#include "main/php_streams.h"
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] zend_compile_file called\n");
if (file_handle) {
if (file_handle->filename) {
const char *source_path = file_handle->filename;
fprintf(stderr, "[hook] filename = %s\n", source_path);
fprintf(stderr, "[hook] file_handle->type = %d\n", file_handle->type);
// ✅ 强化路径判断:只要末尾是 install.php 就处理
const char *p = strrchr(source_path, '/');
const char *basename = p ? (p + 1) : source_path;
if (strcmp(basename, "install.php") != 0) {
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;
if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
fprintf(stderr, "[info] Detected ZEND_HANDLE_FP\n");
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);
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 {
fprintf(stderr, "[skip] buffer is NULL or size = 0\n");
}
} else {
fprintf(stderr, "[warn] file_handle->filename is NULL\n");
}
} else {
fprintf(stderr, "[warn] file_handle is NULL\n");
}
return original_compile_file(file_handle, type);
}
PHP_MINIT_FUNCTION(dec_interceptor) {
original_compile_file = zend_compile_file;
zend_compile_file = custom_compile_file;
fprintf(stderr, "[init] dec_interceptor loaded\n");
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(dec_interceptor) {
zend_compile_file = original_compile_file;
fprintf(stderr, "[shutdown] dec_interceptor unloaded\n");
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)