记录生活点滴,或痛苦,或快乐

把apache2和php5及其各自的模块编译到一个exe中去

2010-09-04

把apache2和php5及其各自的模块编译到一个exe中去,这种事情即无聊又痛苦,如果没有目的真的很难坚持做完。一来是添加加密模块是必须自己编译PHP的,再是编译成一个EXE并裁剪并限制不必要的功能和参数也可以减少被破解的风险。

编译环境是VC9,由于php5可以做为apache2的模块编译,所以将php5的源码一股脑儿地往apache2的工程里添加。一边添加,一边试着编译,中间需要参考php目录下的Makefile中用到的宏定义,总共有十几个选项要手工指定,像APR(apache的可移植函数库,除了apache自己Subversion也在用它)的APR_DECLARE_STATIC, php的PHP_STATIC,ZEND_DEBUG,_USE_32BIT_TIME_T之类。添加的文件从php源码目录的sapi/apache2handler开始,先对每个.c文件单独编译,添加宏定义及排除语法错误,然后看链接时缺少什么函数,再将有依赖关系的c文件添加进来。

apache2 win32平台内嵌模块,是在os/win32/modules.c中完成的,即只要把相应的apache2模块头文件include进来,并将模块变量塞进名为ap_prelinked_modules和ap_preloaded_modules的数组中去,这样编译出来的httpd.exe即引入了这些模块。最终将“core, win32, mpm_winnt, http, so, access, auth, isapi, asis, cgi, autoindex, info, actions, alias, dir, imap, negotiation, rewrite, log_config, log_forensic, logio, php5, mime”这些个模块编译进来。

php也是用模块概念的,也可以内嵌编译,做法同apache2有点像。内嵌模块信息在main/internal_functions.c当中,同样是需要include相应模块的头文件,以及将phpext_*_ptr的模块变量指针塞进名为php_builtin_extensions的数组中。最终编译了必须的一些模块“date, ereg, filter, pcre, reflection, session, sockets, spl, standard, json, iconv, gd, mbstring, php_screw”。

其中php_screw是php文件加密模块,别人都说很好用,可是我却搞了半天没搞定。screw的原理是先用工具将php源文件加密一遍,然后在模块加载时劫持php“编译”(类似于编译)函数,判断是否加密过,放过明文,对加密过的解码,然后替换php传递给“编译”函数的文件指针为临时文件指针,解码后的内容被写到这个tmpfile()产生的临时文件中去。 加密过程是,对数据使用密钥进行位异或操作,然后将数据使用zlib压缩一下,解密过程相反。也许是我准备的zlib有问题,测试时发现,部分加密过的php在解密过程中常因为zlib解压而失败。没能力修改,只好找来DES加密解密类库,替换掉scew的加解密函数,效果好像还可以。

最终Release版本EXE大小为5.8MB。之所以说过程挺痛苦,还在于vc9在链接之后,“生成代码”一般要花上5分钟左右,也就是改一处代码就要“休息”上五分钟。

作者:sunu | 分类目录:C/C++ | 标签:

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">