【问题标题】:zend_compile_file hook not working in PHP Extensionzend_compile_file 钩子在 PHP 扩展中不起作用
【发布时间】:2021-04-22 11:39:43
【问题描述】:

问题背景

我正在为学习目的制作一个 PHP 7 扩展。在扩展中,我的最终目标是使用 OpenSSL (AES_256_CBC) 实现加密/解密。我计划公开一个函数encdec7_compile_file,它将编译并给出PHP文件。另外,在同一个扩展中,我想在编译/执行之前挂钩zend_compile_file 以解密内存中的文件。

到目前为止我做了什么?

我制作了简单的扩展代码,以测试以上两个功能是否正常工作。在encdec7_compile_file,我只是打印参数并生成警告,它工作正常。

在 zend_compile_file 中,我正在尝试打印/记录以确认函数被调用但没有日志,所以我相信函数没有被调用。我的代码

encdec7.c

/* encdec7 extension for PHP 7 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "php_encdec7.h"

static zend_op_array *compile_binary_file(zend_file_handle *, int TSRMLS_DC);

/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE() \
    ZEND_PARSE_PARAMETERS_START(0, 0) \
    ZEND_PARSE_PARAMETERS_END()
#endif

// static void php_encdec_init_globals(zend_encdec_globals *encdec_globals)
// {
//  encdec_globals->initialized = 0;
// }
// ENCDECG(initialized) = 1;

PHP_MINIT_FUNCTION(encdec7)
{
    // ZEND_INIT_MODULE_GLOBALS(encdec7, php_encdec_init_globals, NULL);
    // REGISTER_INI_ENTRIES();

    // if (!ENCDECG(initialized)) {
        orig_compile_file = zend_compile_file;
        zend_compile_file = compile_binary_file;
        // ENCDECG(initialized) = 1;
    // }

    REGISTER_STRING_CONSTANT("ENCDEC_EXT_VERSION", PHP_ENCDEC7_VERSION, CONST_CS | CONST_PERSISTENT);
    
    return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(encdec7)
{
    // if (ENCDECG(initialized)) {
        zend_compile_file = orig_compile_file;
    // }
    // UNREGISTER_INI_ENTRIES();

    // ENCDECG(initialized) = 0;
    return SUCCESS;
}

/* {{{ string encdec7_compile_file( [ string $var ] )
 */
PHP_FUNCTION(encdec7_compile_file)
{
    // End PHP user will call this function with two parameters ($src, $target)
    // Name and length of source and target
    char *filename;
    size_t filename_len;
    char *effective_path = NULL;
    size_t effective_path_len;

    // Get the parameters
    ZEND_PARSE_PARAMETERS_START(2, 2)
        Z_PARAM_STRING(filename, filename_len)
        Z_PARAM_STRING(effective_path, effective_path_len)
    ZEND_PARSE_PARAMETERS_END();

    encdec_warning("Checking how warning displays - 3\n");

    php_printf("src = %s and target = %s\r\n", filename, effective_path);
}
/* }}}*/

/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(encdec7)
{
#if defined(ZTS) && defined(COMPILE_DL_ENCDEC7)
    ZEND_TSRMLS_CACHE_UPDATE();
#endif

    return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(encdec7)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "encdec7 support", "enabled");
    php_info_print_table_end();
}
/* }}} */

/* {{{ encdec7_functions[]
 */
static const zend_function_entry encdec7_functions[] = {
    PHP_FE(encdec7_compile_file, NULL)
    PHP_FE_END
};
/* }}} */

/* {{{ encdec7_module_entry
 */
zend_module_entry encdec7_module_entry = {
    STANDARD_MODULE_HEADER,
    "encdec7",                  /* Extension name */
    encdec7_functions,          /* zend_function_entry */
    NULL,                           /* PHP_MINIT - Module initialization */
    NULL,                           /* PHP_MSHUTDOWN - Module shutdown */
    PHP_RINIT(encdec7),         /* PHP_RINIT - Request initialization */
    NULL,                           /* PHP_RSHUTDOWN - Request shutdown */
    PHP_MINFO(encdec7),         /* PHP_MINFO - Module info */
    PHP_ENCDEC7_VERSION,        /* Version */
    STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_ENCDEC7
# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
# endif
ZEND_GET_MODULE(encdec7)
#endif

static zend_op_array* compile_binary_file(zend_file_handle* h, int type TSRMLS_DC) {
    zend_file_handle *orig_file_handle = h;

    encdec_warning("Warning from compile_binary_file");
    php_printf("Printed from compile_binary_file");

    FILE *fptr;

    char c[] = "Printed from compile_binary_file in /home/kapil/program.txt";
    fptr = fopen("/home/kapil/program.txt", "w");

    if (fptr == NULL) {
        exit(1);
    }

    fprintf(fptr, "%s", c);
    fclose(fptr);

    // Comment below to knowingly add error so that it break, but not breaking.
    // return orig_compile_file(orig_file_handle, type TSRMLS_CC);
}

php_encdec7.h

/* encdec7 extension for PHP */

#ifndef PHP_ENCDEC7_H
# define PHP_ENCDEC7_H

#define encdec_error(format...)   php_error(E_ERROR, format)
#define encdec_warning(format...) php_error(E_WARNING, format)

extern zend_module_entry encdec7_module_entry;
# define phpext_encdec7_ptr &encdec7_module_entry

# define PHP_ENCDEC7_VERSION "0.1.0"

ZEND_BEGIN_MODULE_GLOBALS(encdec)
    zend_bool initialized;
ZEND_END_MODULE_GLOBALS(encdec)

zend_op_array *(*orig_compile_file)(zend_file_handle *, int TSRMLS_DC);

# if defined(ZTS) && defined(COMPILE_DL_ENCDEC7)
ZEND_TSRMLS_CACHE_EXTERN()
# endif

// #ifdef ZTS
// #define ENCDECG(v) TSRMG(encdec_globals_id, zend_encdec_globals *, v)
// #else
// #define ENCDECG(v) (encdec_globals->v)
// #endif

#endif  /* PHP_ENCDEC7_H */

测试

我正在尝试使用简单的 PHP 文件对其进行测试

test.php

<?php

include_once("test2.php");

echo "Calling encdec7_compile_file<br/>" . PHP_EOL;

encdec7_compile_file("Kapil", "Sharma");

test2.php

<?php

echo "Printed from test2";

问题

运行php test.php或在浏览器中,生成以下输出:

Printed from test2Calling encdec7_compile_file

Warning: Checking how warning displays - 3 in /var/www/html/test.php on line 7
src = Kapil and target = Sharma 

但是,compile_binary_file 中的代码未执行,因为控制台/Web 中没有输出 + program.txt 为空白。还尝试评论最后一行,但没有错误。

有人能指出我犯了什么错误吗?

【问题讨论】:

    标签: php c php-extension


    【解决方案1】:

    问题是,我们定义了 MINIT 和 MSHUTDOWN 但没有告诉 Zend 引擎。这个问题会解决的

    zend_module_entry encdec7_module_entry = {
        STANDARD_MODULE_HEADER,
        "encdec7",                  /* Extension name */
        encdec7_functions,          /* zend_function_entry */
        PHP_MINIT(encdec7),         /* PHP_MINIT - Module initialization */
        PHP_MSHUTDOWN(encdec7),     /* PHP_MSHUTDOWN - Module shutdown */
        PHP_RINIT(encdec7),         /* PHP_RINIT - Request initialization */
        NULL,                           /* PHP_RSHUTDOWN - Request shutdown */
        PHP_MINFO(encdec7),         /* PHP_MINFO - Module info */
        PHP_ENCDEC7_VERSION,        /* Version */
        STANDARD_MODULE_PROPERTIES
    };
    

    我们在zend_module_entry 中分别添加了PHP_MINIT(encdec7)PHP_MSHUTDOWN(encdec7) 而不是NULL 作为第4 个和第5 个参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-16
      • 2012-01-22
      • 2015-02-19
      • 2021-04-06
      • 1970-01-01
      • 2015-03-04
      • 2012-09-18
      • 1970-01-01
      相关资源
      最近更新 更多