初探php扩展层面(一)
字数 1090 2025-08-26 22:11:22

PHP扩展开发与HOOK技术深入解析

一、环境搭建与基础扩展开发

1.1 开发环境准备

推荐使用Docker环境进行PHP扩展开发,避免本地环境配置问题:

docker run -i -d --security-opt seccomp=unconfined -v /path/to/code:/home php5-debug

1.2 创建基础扩展

  1. 在PHP源码ext目录下执行:
./ext_skel --extname=extension_name
  1. 修改config.m4文件,取消注释:
PHP_ARG_ENABLE(extension_name, whether to enable extension_name support,
[ --enable-extension_name Enable extension_name support])
  1. 在头文件php_extension_name.h中添加函数声明:
PHP_FUNCTION(confirm_extension_name_compiled);
PHP_FUNCTION(extension_name);
  1. 在扩展源文件extension_name.c中添加函数映射:
const zend_function_entry extension_name_functions[] = {
    PHP_FE(extension_name, NULL)
    PHP_FE(confirm_extension_name_compiled, NULL)
    PHP_FE_END
};
  1. 实现基础函数:
PHP_FUNCTION(extension_name) {
    php_printf("hello world");
}
  1. 编译安装扩展:
phpize
./configure --enable-extension_name --enable-debug
make

二、PHP代码执行流程

PHP代码执行分为四个主要阶段:

  1. Scanning - 将PHP代码转换为语言片段(Tokens)
  2. Parsing - 将Tokens转化为简单而有意义的表达式
  3. Compilation - 将表达式编译成opcode
  4. Execution - 顺次执行opcodes,实现脚本功能

三、Opcode HOOK技术

3.1 基础HOOK实现

使用zend_set_user_opcode_handler函数HOOK特定操作码:

zend_set_user_opcode_handler(ZEND_ECHO, custom_handler);

自定义处理函数:

int custom_handler(ZEND_OPCODE_HANDLER_ARGS) {
    php_printf("hook success");
    return ZEND_USER_OPCODE_RETURN; // 不继续执行原操作
    // return ZEND_USER_OPCODE_DISPATCH; // 继续执行原操作
}

3.2 重要宏定义

  1. 执行环境宏

    • EG() - 访问符号表、函数、资源信息和常量
    • CG() - 访问核心全局变量
    • PG() - 访问PHP全局变量(php.ini映射)
    • FG() - 文件全局变量
  2. 函数类型定义

    #define ZEND_INTERNAL_FUNCTION 1      // 内部函数
    #define ZEND_USER_FUNCTION 2          // 用户定义函数
    #define ZEND_OVERLOADED_FUNCTION 3    // 重载函数
    #define ZEND_EVAL_CODE 4              // eval代码
    #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
    
  3. 执行数据结构

    struct _zend_execute_data {
        const zend_op *opline;           // 当前执行的opline
        zend_execute_data *call;         // 当前调用
        zval *return_value;              // 返回值
        zend_function *func;             // 执行的函数
        zval This;                       // this + call_info + num_args
        zend_execute_data *prev_execute_data;
        zend_array *symbol_table;
        // ...其他成员
    };
    

四、Webshell防御实践

4.1 Eval HOOK实现

HOOK ZEND_INCLUDE_OR_EVAL操作码防御危险函数:

static int HOOK_INCLUDE_OR_EVAL(ZEND_OPCODE_HANDLER_ARGS) {
    zend_op *opline = execute_data->opline;
    zval *operands = opline->op1.zv;
    char *cmd = Z_STRVAL_P(operands);
    
    if(cmd) {
        if((strstr(cmd, "system")==NULL) &&
           (strstr(cmd, "exec")==NULL) &&
           (strstr(cmd, "shell_exec")==NULL) &&
           (strstr(cmd, "passthru")==NULL) &&
           (strstr(cmd, "popen")==NULL)) {
            return ZEND_USER_OPCODE_DISPATCH;
        } else {
            return ZEND_USER_OPCODE_RETURN;
        }
    }
    return ZEND_USER_OPCODE_DISPATCH;
}

4.2 字符串变量处理

字符串变量特殊处理:

  • Z_STRVAL/Z_STRVAL_P/Z_STRVAL_PP - 获取字符串值
  • Z_STRLEN/Z_STRLEN_P/Z_STRLEN_PP - 获取字符串长度

4.3 防御局限性

仅HOOK ZEND_INCLUDE_OR_EVAL不足以防所有攻击,例如:

eval('echo `whoami`;');

需要额外HOOK DO_FCALL等操作码实现更全面的防御。

五、扩展开发进阶

  1. 变量操作

    • 使用zval结构处理PHP变量
    • 注意引用计数和内存管理
  2. 函数注册

    • 支持参数解析和返回值处理
    • 实现面向对象接口
  3. 资源管理

    • 注册自定义资源类型
    • 实现资源析构函数
  4. 线程安全

    • 考虑多线程环境下的安全性
    • 使用TSRM机制

六、参考资源

  1. PHP内部实现详解
  2. PHP内核解析
  3. Webshell防御实践
  4. PHP代码RASP技术

通过深入理解PHP扩展开发和HOOK技术,可以实现强大的功能扩展和安全防护能力。开发过程中需要注意PHP版本兼容性、内存管理和线程安全等问题。

PHP扩展开发与HOOK技术深入解析 一、环境搭建与基础扩展开发 1.1 开发环境准备 推荐使用Docker环境进行PHP扩展开发,避免本地环境配置问题: 1.2 创建基础扩展 在PHP源码ext目录下执行: 修改config.m4文件,取消注释: 在头文件php_ extension_ name.h中添加函数声明: 在扩展源文件extension_ name.c中添加函数映射: 实现基础函数: 编译安装扩展: 二、PHP代码执行流程 PHP代码执行分为四个主要阶段: Scanning - 将PHP代码转换为语言片段(Tokens) Parsing - 将Tokens转化为简单而有意义的表达式 Compilation - 将表达式编译成opcode Execution - 顺次执行opcodes,实现脚本功能 三、Opcode HOOK技术 3.1 基础HOOK实现 使用 zend_set_user_opcode_handler 函数HOOK特定操作码: 自定义处理函数: 3.2 重要宏定义 执行环境宏 : EG() - 访问符号表、函数、资源信息和常量 CG() - 访问核心全局变量 PG() - 访问PHP全局变量(php.ini映射) FG() - 文件全局变量 函数类型定义 : 执行数据结构 : 四、Webshell防御实践 4.1 Eval HOOK实现 HOOK ZEND_INCLUDE_OR_EVAL 操作码防御危险函数: 4.2 字符串变量处理 字符串变量特殊处理: Z_STRVAL / Z_STRVAL_P / Z_STRVAL_PP - 获取字符串值 Z_STRLEN / Z_STRLEN_P / Z_STRLEN_PP - 获取字符串长度 4.3 防御局限性 仅HOOK ZEND_INCLUDE_OR_EVAL 不足以防所有攻击,例如: 需要额外HOOK DO_FCALL 等操作码实现更全面的防御。 五、扩展开发进阶 变量操作 : 使用 zval 结构处理PHP变量 注意引用计数和内存管理 函数注册 : 支持参数解析和返回值处理 实现面向对象接口 资源管理 : 注册自定义资源类型 实现资源析构函数 线程安全 : 考虑多线程环境下的安全性 使用TSRM机制 六、参考资源 PHP内部实现详解 PHP内核解析 Webshell防御实践 PHP代码RASP技术 通过深入理解PHP扩展开发和HOOK技术,可以实现强大的功能扩展和安全防护能力。开发过程中需要注意PHP版本兼容性、内存管理和线程安全等问题。