msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

14 Aug 08 实现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;
}

这样,我们就实现了, 对已经编译文件的支持,和对文件编译的支持。
然后,需要编写我们的执行函数:

static void my_execute(zend_op_array *op_array TSRMLS_DC)
{
    old_execute(op_array TSRMLS_DC); //简单交由默认执行函数执行。
}

也许你要问为什么要包装以后的执行函数, 呵呵,我只是为了说明,一种方式,就是可以截获这个东东而已。。 有什么用,就看读者你有什么要求能通过这个方式实现了 ;)

恩,写到这里, 你也许就明白了, 如果想要对文件加密, 那么就定义个加密文件类型,比如 *.zec, 然后在my_compile_file中,判断文件类型,如果是加密文件,那么就执行解密,;),嘿嘿,简答吧?

至于怎么加密,,,那就要问你自己了,你想用什么方式,,,但是,记住,要可逆的哦~~ ^_^。


分享到:



Related Posts:

Tags: ,

11 Responses to “实现PHP的编译执行分离(separating compilation and execution)”

  1. 风雪之隅-鸟哥文章汇总 | 互联网菜鸟 |

    [...] Aug 08 实现PHP的编译执行分离(separating compilation and execution)  12 Aug 08 深入理解Zend SAPIs(Zend SAPI Internals) 12 Aug [...]

  2. bittercookie |

    请问一下,如果这种方式,如果使用了apc的话,兼容性上是否有问题,配置上加密模块和apc模块顺序上有没有强制性的要求? 本人菜鸟,求轻拍

  3. bird |

    鸟哥,什么群啊,我能加吗?

  4. 实现PHP的编译执行分离(separating compilation and execution) | 万维网黑客联盟 |

    [...] 本文地址: http://www.laruence.com/2008/08/14/250.html [...]

  5. 雪候鸟 |

    @phper 惭愧, 我没有测试过,只是谈个想法, 呵呵. 这块要实现, 还是要做很大实验的.

  6. phper |

    不加密怎么样保存op_array?怎么直接返回文件内容?
    zend_op_array好像是链表类的结构体.
    您有没有测试过?有实例代码吗?

    if(op_array){
    保存op_array;
    }

    if(strstr(file_handle->filename, “.ze”) != NULL){//是编译过的文件。
    直接返回文件内容.
    }

  7. Anonymous |

    最近研究這方面,在源代碼級別上開發有很多方面可以應用。

  8. 雪候鸟 |

    恩对,APC的实现原理和这个差不多,一般来说会存在内存,或者类dbm的数据库中。

  9. Leric |

    估计APC之类的opcode缓存就是这么实现的吧,也不知道那些缓存的东西都放哪儿了

  10. 雪候鸟 |

    呵呵,人各有志么,我只是说个实现方式。。
    我是坚实的开源拥护者。

  11. guoxiaod |

    为什么要为 中国的开源事业制造绊脚石呢?

Leave a Reply

*