实现PHP的编译执行分离(separating compilation and execution)

刚刚在PHP群内和大家聊天,应承了大家要写一个关于如何实现PHP源码加密的文章,借着这会QA在冒烟的机会,就这个问题,我写点思路。

我以前的文章介绍过,ZE(Zend engine)执行一个PHP脚本会经历编译->执行,只不过它每次执行都会去重新编译PHP文件。并没有实现编译和执行分离。

在ZE的编译和执行阶段,有俩个重要的函数:

ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);

ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);

zend_compile_file负责将要执行的脚本文件编译成由ZE的基本指令序列构成的op codes,然后将op codes交由zend_execute执行,从而得到我们脚本的结果。

所以,我们完全可以通过修改默认的zend_complie_file和zend_execute来实现,PHP的执行和编译分离,进一步,我们还可以再这个基础上实现,对我们脚本的加密和解密。

我们通过一个PHP扩展模块来实现这个功能,首先,我们需要在模块初始化的时候:

PHP_MINIT_FUNCTION(sample)
{
old_compile_file = zend_compile_file; //保存现场
old_execute = zend_execute;
zend_compile_file = my_compile_file; //截获
zend_execute = my_execute;
return SUCCESS;
}

在我们的my_compile_file中,判断我们的文件是否是编译过的文件,假设后缀名是*.ze。

static zend_op_array *my_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
{
if(strstr(file_handle->filename, ".ze") != NULL){//是编译过的文件。
直接返回文件内容.
}
zend_op_array *op_array;
op_array = old_compile_file (file_handle, type TSRMLS_CC); //调用默认的compile,截获输出
if(op_array){
保存op_array;
}
return op_array;
}

时间: 2024-11-03 09:57:03

实现PHP的编译执行分离(separating compilation and execution)的相关文章

JAVA 文件编译执行与虚拟机(JVM)简单介绍

java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行.本文首先简要介绍从Java文件的编译到最终执行的过程,随后对JVM规格描述作一说明.    一.Java源文件的编译.下载.解释和执行  Java应用程序的开发周期包括编译.下载.解释和执行几个部分.Java编译程序将Java源程序翻译为JVM可执行代码?字节码.

qt4-QT4.8.6静态编译执行mingw32-make sub-src后出错

问题描述 QT4.8.6静态编译执行mingw32-make sub-src后出错 解决方案 http://blog.csdn.net/libaineu2004/article/details/24620709 解决方案二: 编译cpp的时候出现了Error,要再往上看看,还要看你的是否支持

页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码??

问题描述 页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码?? 页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码?? 解决方案 可以使用一些前端的模板引擎,java是编译的 解决方案二: ajax提交客户端输入的代码动态执行就行,看下面参考 ajax提交http://www.w3school.com.cn/jquery/ java中怎么执行字符串中的代码http://bbs.csdn.net/topics/3903563

解释执行和编译执行的区别?_其它综合

一:编译器 编译器是一种特殊的程序,它可以把以特定编程语言写成的程序变为机器可以运行的机器码.我们把一个程序写好,这时我们利用的环境是文本编辑器,这时我们把程序称为源程序,在此以后程序员可以运行相应的编译器,通过指定需要编译的文件的名称就可以把相应的源文件(通过一个复杂的过程)转化为机器码了. 二:机器码 机器语言(machine language)是一种指令集的体系.这种指令集,称机器码(machine code),是电脑的CPU可直接解读的. 三:目标程序 目标程序又称"目的程序"

如何让EditPlus可以编译执行Java程序

编译|程序|执行 在 USER TOOLS中选:Add Tool>>1.配置JAVACMenu Text:javacCommand:C:\jdk1.3.1\in\javac.exeArgument:$(FileName)Initial Derictory:$(FileDir)选中 Capture output2.配置JAVAMenu Text:javaCommand:C:\jdk1.3.1\in\java.exeArgument:$(FileNameNoExt)Initial Derictor

利用javax.tools动态编译执行java代码

inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ). 参考:使用 javax.tools 创建动态应用程序   javax.tools 包是一种添加到 Java SE 6 的标准 API,可以实现 Java 源代码编译,使您能够添加动态功能来扩展静态应用程序.本文将探查javax.tools包中提供的主要类,以Java表达式表示计算一个数值函数y=x*x+x.更多详情请参考<使用 javax.tools 创建动态应用程序>和jav

ASP.NET编译执行常见错误及解决方法汇总_实用技巧

1.检测到有潜在危险的 Request.Form 值 原因: (1)在提交数据的页面或webconfig中没有对validateRequest的属性进行正确的设置 (2)HTML里面写了两个<form>引起 解决: 方案一: 在.aspx文件头中加入这句: <%@ Page validateRequest="false" %> 方案二: 修改web.config文件: <configuration> <system.web> <pa

Lua教程(六):编译执行与错误_Lua

1. 编译:     Lua中提供了dofile函数,它是一种内置的操作,用于运行Lua代码块.但实际上dofile只是一个辅助函数,loadfile才是真正的核心函数.相比于dofile,loadfile只是从指定的文件中加载Lua代码块,然后编译这段代码块,如果有编译错误,就返回nil,同时给出错误信息,但是在编译成功后并不真正的执行这段代码块.因此,我们可以将dofile实现为: 复制代码 代码如下:  function dofile(filename)      local f = as

C#在.NET编译执行过程

1..NET语言的编译器接受源代码文件,并生成名为程序集的输出文件.   程序集要么是可执行的,要么是DLL 程序集里的代码并不是本机代码,而是一种名称为CIL的中间语言 程序集包含如下信息: 程序的CIL 程序中使用的类型的元数据 对其他程序集引用的元数据 2.   程序的编译过程    程序的CIL直到它被调用运行时才会被编译成本机代码.在运行时,CLR执行下面步骤: 检查程序集的安全特性 在内存中分配空间 把程序集中的可执行代码发送给实时编译器(JIT),把其中的一部分编译成本机代码. 程