gpt4 book ai didi

php - PHP7 opcached 文件可以在没有源代码的情况下分发吗?

转载 作者:可可西里 更新时间:2023-10-31 23:10:40 25 4
gpt4 key购买 nike

PHP7 提供了一种称为opcache 的字节码缓存机制。 .我想知道是否有任何方法可以在不分发其源代码的情况下分发和运行 PHP 脚本(.bin 文件扩展名)的“opcached”版本。 (我在php.ini中启用了opcache.file_cache指令来获取.bin文件。)

我假设在执行脚本时,PHP7 将检查 opcache 目录以查找具有匹配名称、时间戳的 .bin 文件,甚至可能比较校验和或哈希值。如果一切都匹配,PHP7 将执行 .bin 文件而不是解析 .php 文件。也许即使相应的 .php 脚本不存在,也可以“欺骗”PHP 执行 .bin 文件?

最佳答案

PHP 需要能够打开文件以便调用 opcache;如果不存在,则无法加载...

让我们look详细点,看我们能玩什么花样:

if (!file_handle->filename || !ZCG(enabled) || !accel_startup_ok) {
/* The Accelerator is disabled, act as if without the Accelerator */
return accelerator_orig_compile_file(file_handle, type);
#ifdef HAVE_OPCACHE_FILE_CACHE
} else if (ZCG(accel_directives).file_cache_only) {
return file_cache_compile_file(file_handle, type);
#endif
} else if ((!ZCG(counted) && !ZCSG(accelerator_enabled)) ||
(ZCSG(restart_in_progress) && accel_restart_is_active())) {
#ifdef HAVE_OPCACHE_FILE_CACHE
if (ZCG(accel_directives).file_cache) {
return file_cache_compile_file(file_handle, type);
}
#endif
return accelerator_orig_compile_file(file_handle, type);
}

我们可以看到,在启用文件缓存的情况下,它优先于共享内存缓存。

接下来,我们要看file_cache_compile_file :

  1. block signals
  2. protect shared memory
  3. zend_file_cache_script_load

现在我们看zend_file_cache_script_load :

  1. open
  2. read header ( layout )
  3. verify magic "OPCACHE"
  4. verify system id
  5. optionally validate timestamp
  6. perform read of cached file
  7. verify checksum

所以我们遇到的第一个问题是 system id不是唯一的,而是由以下元素组成:

  1. PHP 版本
  2. Zend 扩展构建标识符
  3. 二进制标识符,包含以下内容:
    1. sizeof(char)
    2. sizeof(int)
    3. sizeof(long)
    4. sizeof(size_t)
    5. sizeof(zend_long)
    6. ZEND_MM_ALIGNMENT
  4. 如果不使用 PHP 的开发版本(未发布,来自 git):
    1. ___DATE__ 二进制编译日期
    2. ___TIME___ 二进制编译时间

PHP 版本和构建标识符是必需的,因为至少以下内容可能会在版本或构建之间发生变化:

  • 操作码的完整标识符
  • 内部结构布局
  • VM 期望的指令序列(现有控制结构的细节可能会改变,例如 foreach)
  • 由 opcache 执行的优化(因为之前的优化可能被发现是不安全的)

二进制标识符是必需的,因为至少 zval 的布局随着字节序和架构的变化:架构可能会影响一些基本编译器类型(long、size_t 等)的大小以及这些类型的上限和下限,而字节序会影响结构中成员的顺序,以及作为基本编译器类型的二进制表示。

请注意,相当多的努力花费在识别当前系统上,这应该让你停下来思考......

禁用时间戳验证 opcache.validate_timestamps=0 将允许加载文件缓存条目,即使文件系统上的当前文件为空也是如此。

header 中包含的校验和仅用于验证文件的脚本部分(位于 header 之后),它不(也不能)包含写入系统标识符或校验和本身的 header .

因此,您可以通过更改 header 中的系统标识符来欺骗 PHP 从另一台机器加载缓存文件。缓存文件的名称与目标机器标识符相对应。

你应该吗?

也许是为了好玩,但作为部署软件的一种方法,绝对不是

文件缓存不是为这个目的而设计的,从不同的架构和/或构建加载缓存会导致 PHP 崩溃。

关于php - PHP7 opcached 文件可以在没有源代码的情况下分发吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40667204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com