- 浏览: 1608238 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (603)
- T_java (145)
- T_script&ASP (51)
- T_C/C++ (25)
- T_PowerBuilder (11)
- T_Database (53)
- T_odoo (7)
- T_应用服务器 (50)
- T_专_条形码 (6)
- T_专_负载均衡器 (4)
- T_操作系统 (94)
- T_信息安全 (41)
- T_专_搜索引擎 (14)
- T_L_PHP (58)
- T_L_Delphi (18)
- T_L_.NET、C#、VisualStudio (25)
- T_L_Objective-C (6)
- T_移动开发 (53)
- T_网络 (109)
- T_大数据 (2)
- T_嵌入式 (2)
- T_小众技术 (24)
- T_未分类 (58)
- L_旅游印记 (1)
- L_生活随笔 (48)
- L_中国文化 (18)
- L_户外与生存 (0)
最新评论
-
csbean4004:
不知道哪传来得恶习,发帖子不好好发,故意弄错一些东西,很讨厌
让HTML5支持后置摄像头 -
withthewind:
终于找到一个可以用的了。。。
如何用VBA取得Word文档中的标题前面的序号 -
busbby:
兄弟,无法下载,说文件不完整
一个好用的Outlook ost格式文件转pst文件的工具 -
yijavakevin:
密码啊~解压密码多少?
一个二维条形码组件 -
vipbooks:
你给的那个链接根本无法下载,跳到官网看了下最新版12M,但点下 ...
十步以内完成精细web打印
windows下用c写php扩展(加密解密php源代码)
首先用hello world试手一下。
下载php源码包,ext目录就是扩展目录了,里面有2个重要的文件是ext_skel以及ext_skel_win32.php。
下载cygwin,有了这个就可以方便的在windows下创建php扩展了。
下载中……
下载完后用php ext_skel_win32.php --extname=hello来编译生成我们的扩展开发目录hello,然后开始写测试程序hello world。在hello.c文件里添加函数定义以及函数注册语句:
函数注册语句:
const zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) PHP_FE(sayHello,NULL)//这句是我们手动添加的 {NULL, NULL, NULL} };
函数定义:
PHP_FUNCTION(sayHello){ php_printf("Hello C extension"); }
好像说是一定要以PHP_FUNCTION出现的宏形式,因为如果直接裸写c代码可能会发生命名冲突或是其他的冲突。然后在php_hello.h里面添加函数声明语句:
PHP_FUNCTION(sayHello);
写好测试程序,编译结果出现:
../main/config.w32.h': No such file or directory
网上查了一下,好像是要下载额外的包。。。麻烦啊!
http://www.php.net/extra/bindlib_w32.zip
http://www.php.net/extra/win32build.zip
将这两个包放在一起,我把它们放在win32/build目录下,然后执行php源码包根目录下的buildconf.bat(最好在命令行运行,不然显示结果会一闪而过)。
然后把bison.exe(在刚下载的包里面)所在的目录设置为环境变量,再运行configure.bat。完后就生成/main/config.w32.h这个文件了。
然后再次编译刚才hello项目结果出现一大推错误。
形如:
..\..\main\streams/php_stream_transport.h(85) : error C2143: syntax error : missing ')' before '*'
..\..\main\streams/php_stream_transport.h(85) : error C2081: 'socklen_t' : name in formal parameter list illegal
网上说是由于找不到宏定义才会这样,那应该是socklen_t这个宏没定义了,但是它具体的宏定义应该是怎么样的呢,总不能随便写一个吧,所以打开
\main\streams/php_stream_transport.h
发现应该是个类型别名,而且是个int ,因为有socklen_t addrlen; addrlen 按字面应该是存储长度的值。
所以在这个文件中添加
typedef int socklen_t;
并保存,再编译刚才的项目,错误少了很多,但是还有7个,经检查发现是输入了中文符号。改正再编译。。。还有一个错误:
LINK : fatal error LNK1181: cannot open input file "php5ts.lib"
于是将寻找php5ts.lib这个文件并将它放到项目目录下或是VC6 lib文件默认搜索目录下也可以。找啊找啊找。。。
tmd,用windows搜索找了好久都没找到。百度是说在php二进制代码包里面。所以先下个同版本的二进制代码包(应该就是平时写php所必须下载的那个包吧)
这里先说下环境吧windows+vc6+php5.3.5(二进制代码包和源码包)+cygwin
下载完毕,找到,复制 ,编译,成功!
但是出现了一个很严重的问题,dll文件没出来,,,我哭!创建出来的是php_hello.exp和php_hello.lib。怎么会是静态的呢??
其实已经生成了,只是不在本目录下的Release_TS目录下,而是在ext上级的Release_TS目录下。
然后测试。哈哈,说是未定义函数,有没可能是测试的php版本和我扩展的php版本不一样的关系呢?
测试了一下也不是,只要在ini里一设置加载php_hello.dll重启apache就会出现内存不能读的错误。
总觉得代码没有问题,应该还是前面配置编译的时候有问题。
经过一番又一番的测试,发现时php二进制包下错了我下了vc9的应该下vc6的。
接下来要开始写加密和解密了。加密解密算法本身不是这里的重点,重点是如何在zend层用zend本身的接口结合c来编程,在zend编译源文件之前将文件解密(当然文件之前要是有加过密的)。
为了使用的方便。我的想法是像php_screw一样生成dll的同时,生成一个加密的可执行文件,这加密的可执行文件由我们手动执行,传入目录参数,能够对该目录下的所有文件进行加密。
在网上找了一堆资料后,再看看php_screw的代码,还有有些吃力,所以决定根据自己的思路来写。当然有些地方时会借鉴php_screw的代码
首先是先写一个对文件进行解密的函数。这个函数利用我们现成的解密算法对文件内容进行解密。
这个函数应该有一个参数用来接收当前请求文件的句柄(貌似是zend_compile_file这个东西,百度之,确认一下,几篇文章说是函数指针,我看了下源代码确实是函数指针)
extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
那么要如何得到当前请求文件的文件指针呢?或许和zend_compile_file函数指针所指函数的作用有关。在源代码中发现了:
zend_compile_file = compile_file;
该函数的定义在zend_language_scanner.c,不过要看懂该函数有点难度,网上的说法是:
-------------
zend_compile_file负责将要执行的脚本文件编译成由ZE的基本指令序列构成的op codes 。
PHP执行这段代码会经过如下4个步骤:
1. Scanning (Lexing) ,将PHP代码转换为语言片段(Tokens)
2. Parsing , 将Tokens转换成简单而有意义的表达式
3. Compilation , 将表达式编译成Opocdes
4. Execution , 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能。
-------------
所以我们应该要在这个四个步骤之前将文件解密。
想法是重写一个函数 myCompile 判断在文件被compile之前先将它解密,然后再调用默认的complie函数。定义好 myCompile 后,应该在请求初始化的时候将 myCompile 传递给函数指针zend_compile_file
PHP_MINIT_FUNCTION(dencrypt){ old_comlie_file = zend_complie_file;//保留默认的compile,以便等一下调用 zend_complie_file = myCompile; return SUCCESS; } ZEND_API zend_op_array *myCompile(zend_file_handle *file_handle,int type TSRMLS_DC){ //这里的TSRMLS_DC是一个宏类似于,...(宏的定义暂时找不到)总之是跟多线程环境下全局变量的线程安全有关系的,以后再深究 //这里是解密代码。。。 old_comlie_file(file_handle); .... }
但是问题还是没有解决,因为我们还是不知道如何获取到文件指针。我看php_screw里面的解密步骤挺长的,参考之。。。找到了:
fp = fopen(file_handle->filename, "r");
原来file_handle里面有文件名的信息(其实如果找到file_handle的结构体定义语句也就知道了)。但是php_screw里面还有这么一段:
char fname[32]; memset(fname, 0, sizeof fname); if (zend_is_executing(TSRMLS_C)) { //TSRMLS_C获得全局变量 //获取当前调用函数的名字(当前调用函数?哪里的函数?php函数?想想当然是zend里面的函数。而不是php层的函数,因为现在都还没编译,更没执行呢) if (get_active_function_name(TSRMLS_C)) { strncpy(fname, get_active_function_name(TSRMLS_C), sizeof fname - 2); } } if (fname[0]) { if ( strcasecmp(fname, "show_source") == 0 //也就是说如果当前是这两个函数则不解密也不编译了。恩,看样子没错。 || strcasecmp(fname, "highlight_file") == 0) { return NULL; } }
所以这段还是必要的,不然遇到以上两个函数就没法实现了,compile_file函数里面应该也有这步才对。所以这里主要是不要让它被解密,而是直接显示密文。
还有这么一段:
fp = fopen(file_handle->filename, "r"); if (!fp) { //如果打开失败则直接调用默认compile函数 return org_compile_file(file_handle, type); } fread(buf, PM9SCREW_LEN, 1, fp); //一下5句的作用是:如果发现时未加密的文件则不进行解密。 if (memcmp(buf, PM9SCREW, PM9SCREW_LEN) != 0) { fclose(fp); return org_compile_file(file_handle, type); } if (file_handle->type == ZEND_HANDLE_FP) fclose(file_handle->handle.fp); //判断文件句柄类型,应用相应的关闭函数。 if (file_handle->type == ZEND_HANDLE_FD) close(file_handle->handle.fd); file_handle->handle.fp = pm9screw_ext_fopen(fp); //调用解密文件的函数,并用file_handle里面的fp接收函数返回结果 file_handle->type = ZEND_HANDLE_FP; //将句柄类型设置为文件指针类型 file_handle->opened_path = expand_filepath(file_handle->filename, NULL TSRMLS_CC);
上面这句有点不懂,猜想是不是接受当前文件的路径呢?一路追踪找到了expand_filepath_ex这个函数这个函数的最后一句是return real_path;看样子应该就是返回当前要编译文件的路径吧。但是为什么要有上面那两步呢?就是设置类型和路径这两部。如果我们不做解密操作就不用这两步,我的猜想是因为fclose(file_handle->handle.fp)这里改变了file_handle的状态,所以才需要重新设置吧!(但是有一个疑问是,这样做是Compilation之前解密,还是在Scanning之前解密?我初步认为从语义上来讲是在Compilation之前解密,但是从实际情况来看应该是要在Scanning之前解密,这边后期可以验证,事实证明后者是对的,因为compile_file函数里有对open_file_for_scanning函数的调用,也就是说在compile_file函数里执行了前面所说的123步)。
入口点有了(还有4分之3的问题需要解决)。
接下来开始写解密文件的函数。
需要考虑的问题有,解密文件后的明文代码,并不需要写入文件,那么如何取得这些明文的文件指针呢?用临时文件来做?但是如果每个请求都用不同的临时文件那会生成很多临时文件(显然不可行),如果对同一个php文件的不同请求只用一个临时文件,也会出现资源等待的问题(显然也不可行)。能不能直接在内存中指定一个文件指针呢?先看看php_screw的做法,调用tmpfile()产生临时文件,但是在程序退出时便会自动删除!其实我认为的在内存中的文件也是这样实现的。
直接下来把之前用php写的可逆加解密算法用c来实现,可是c并没有现成了md5和base64函数,看来只能抛弃这2个了。
写好后就开始编译了,遇到了一些错误也都改过来了。
然后链接的时候出现了错误:
error LNK2001: unresolved external symbol _zend_compile_file
搜索了一下,貌似是因为函数编译方式的不一样所导致的找不到函数,加入:
BEGIN_EXTERN_C() ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); END_EXTERN_C()
即可。
生成dll文件成功,但是不知道如何生成用于加密的可执行文件,当然最简单的解决方法就是另外建一个项目。看来只好先这样了,因为对vc的一些编译机制还有参数设置也不是很熟悉(以后再研究程序员的自我修炼好像有讲这个的)。
之后又遇到c的指针传递问题(很久没弄,一些基础的都忘了,最后用二级指针来解决指针作为参数回传的问题)。
又遇到了链接时找不到_zend_compile_file符号的问题(跟zend_api宏有关dllimport\dllexport)
然后又遇到读写文件的问题,其实没错,只是我把写入文件的密文手动复制内容到另一个文件中去测试,结果会出错,如果直接复制文件,或直接操作该原始文件则正确。
最后又遇到了内存不能读的错误。。。
最后是发现是由于文件读取方式的问题,以二进制读取就可以了,如果以文本方式读写,会将某些特殊字符进行处理。
...最后测试功能是可以了,不过如果真的要应用的话要改进一下,比如我加密的时候是在原来目录下直接生成加密后的文件,更好的做法应该是要把原来的php文件打包起来,方便管理。
接下来开始搞zf框架了,都快忘光了,而且当初还有还多东西没用到的。
===============================
原文地址:
http://blog.sina.com.cn/s/blog_4d06da1f0100pgmj.html
发表评论
-
SpringBoot Fat Jar解压运行
2018-06-28 21:40 2258SpringBoot已经成为当前最流行的微服务 ... -
TeamViewer13+Patch
2018-05-13 22:19 3180下载地址: https://www.datafilehos ... -
来算google的可视化编程工具——Blockly,不仅仅是玩具
2017-10-16 21:34 33120Blockly - 来自Google的可 ... -
Linux挂载阿里云对象存储OSS作为本地磁盘扩充空间备份网站
2017-09-25 08:54 1931p.s.挂载oss之后,使用rsync可以同步图片数据,非 ... -
Chrome核心的自定义浏览器
2017-07-04 17:19 826以Chrome为核心的自定义浏览器源代码,有时候可能用得到,保 ... -
十步以内完成精细web打印
2017-06-21 11:44 7367注意: 康虎云报表组 ... -
浏览器端精准打印或套打组件
2017-01-18 13:05 6695注意: 康虎云报表 ... -
让ie6 7 8 9支持html5 websocket
2016-12-23 20:52 2315结果: 从github上的 web ... -
网站获取用户手机号码的方法、系统、客户端及服务器(坑爹的玩意儿)
2016-11-22 14:22 2277网站获取用户 ... -
Sql注入之sqlmap+dvwa实例演练
2016-10-27 16:27 1591Sql注入之sqlmap+dvwa实例演练 相信 ... -
Ubuntu16.04上安装MT7601网卡驱动(TL-W725N/W725N)
2016-09-15 23:01 0I suggest you get a temporary ... -
如何在palcedoler中放置图标
2016-09-10 09:52 640如何在H5的palceholder中设置一个图标? ... -
一个下载youtube视频的Linux工具
2016-07-01 08:50 934我们要介绍工具是youtube-dl。这是一个跨平台的工具, ... -
另一个穿透内网的工具(类似ngrok)
2016-06-20 20:26 4830前段时间介绍过两种把内网端口映射到公网的工具:ngrok ... -
Docker无法拉取镜像的一个解决办法
2016-06-16 12:47 14126在阿里云ECS上安装了docker,安装完成后,运行hell ... -
ODOO9 SAAS 全自动安装脚本 基于Ubuntu 14.04 LTS
2016-05-09 10:37 2488install-odoo-saas.sh #! ... -
基于 HTTP/2 的 WEB 内网穿透实现(转)
2016-04-22 15:50 1495基于 HTTP/2 的 WEB 内网穿透实现 HTTP ... -
搭建自己的ngrok服务(转)
2016-04-22 15:42 893搭建自己的ngrok服务 在国内开发、企业号 ... -
一个把内网端口映射到外网的工具ngrok(类似与花生壳)
2016-04-22 14:35 1407Secure tunnels to localhost ... -
申请Let's encrypt的免费SSL证书的正确姿势(转)
2016-03-30 19:16 1380申请Let's encrypt的免费SS ...
相关推荐
在Windows环境下编译PHP-beast扩展是一个较为复杂的过程,涉及到选择合适的编译器、设置编译环境、准备编译文件、以及执行具体的编译步骤。本文将详细说明如何在Windows系统中编译PHP-beast扩展,同时会提供必要的...
在 Windows 操作系统下开发 PHP 扩展可以不使用 Cygwin,这篇教程将指导您从头开始创建自己的 PHP 扩展。 准备工作 首先,您需要 PHP 源码包和 Windows 下的二进制包,以及安装 Visual C++。并将 Microsoft Visual...
2. **Visual C++ Compiler**: PHP扩展通常需要使用C语言编写,而Visual C++编译器则提供了强大的C/C++编译能力。本教程中提到的是使用VC6,但现代环境下建议使用更现代的编译器如Visual Studio 2019及以上版本。 3. ...
通常,PHP的安装路径可能是`C:\php`或类似的位置,而`ext`目录包含了所有可用的PHP扩展。 完成文件放置后,需要编辑PHP的配置文件`php.ini`。找到该文件并使用文本编辑器打开。在`php.ini`中,添加以下行以启用...
总的来说,Windows下的Redis部署涉及多个步骤,包括Redis服务器的安装、PHP扩展的配置以及自动启动工具的设置。通过这些步骤,开发者能够在Windows环境中充分利用Redis的强大功能,为Web应用提供快速的数据存储和...
**Windows环境下PHP7-Memcache扩展的安装与配置** ... 以上就是Windows环境下PHP7-Memcache扩展的安装、配置和使用方法。确保正确操作每一步,以充分利用Memcache的高效缓存功能,提升Web应用的性能。
在Windows环境下,我们通常会使用PECL(PHP Extension Community Library)来安装PHP扩展。但Yaf不直接支持PECL安装,因此我们需要下载预编译好的dll文件。在"php扩展yaf 3.3.3 for Windows-php7.3-php8.0-7.4.zip"...
标题 "php7,memcache扩展文件,windows" 涉及到的是PHP编程语言与Memcached缓存系统在Windows环境下的集成。Memcache是广泛应用于Web开发中的一个高性能分布式内存对象缓存系统,它可以减轻数据库负载,提高动态、...
PHP扩展是用C语言编写的,它们通过ZEND引擎与PHP内核交互,提供新的功能或者增强已有功能。使用Cygwin,开发者可以在Windows系统上构建这些C扩展,而无需安装完整的Linux环境。以下是一些使用Cygwin进行PHP扩展开发...
2.在终端(也即cmd命令界面)下输入'c:\memcached\memcached.exe -d install'安装 3.再输入:'c:\memcached\memcached.exe -d start'启动。NOTE:以后memcached将作为windows的一个服务每次开机时自动启动。这样...
- 对于Windows系统,根据系统的位数(32位或64位),intl扩展文件应放置在相应的系统目录下:64位系统放在`C:\Windows\SysWOW64`,32位系统放在`C:\Windows\System32`。 - 安装完成后,还需要在php.ini文件中启用...
PHP扩展开发流程是PHP开发者深入理解其内部机制和增强功能的重要途径。以下是一个详细的步骤指南,帮助你了解如何从头开始构建一个PHP扩展。 一、准备环境 1. 安装VC++ 6:这是微软的Visual C++ 6.0编译器,用于...
标题中的“VC建立php扩展”指的是使用Visual C++(VC)编译器来构建PHP的扩展模块。在PHP中,扩展通常用C或C++编写,以增加PHP语言...通过博客文章和提供的工具,我们可以学习如何在Windows环境下使用VC来实现这一目标。
2. **复制到PHP扩展目录**:将下载的dll文件复制到PHP的`ext`目录下,这个路径通常为`C:\php\ext`(假设你的PHP安装在C盘)。 3. **编辑php.ini配置**:在PHP的配置文件`php.ini`中,添加以下行: ``` extension=...
本文将详细介绍如何使用C语言编写PHP扩展,包括预定义、扩展骨架生成、源码修改、编译安装以及PHP调用等关键步骤。 首先,当我们希望创建一个新的PHP扩展时,通常需要从一个函数定义文件开始,该文件包含了我们希望...
首先,理解PHP扩展的本质:它们是用C或C++编写的库,与PHP解释器交互,提供了新的数据类型、函数和行为。CMake作为构建工具,允许我们以一致的方式管理这些扩展的编译和链接过程,无论是在Linux、Windows还是macOS等...
Swoole是一个高性能的、基于C语言开发的PHP扩展,专为PHP提供了异步并行编程的能力。标题指出“php7.0以上swoole扩展”,这意味着Swoole扩展自PHP 7.0版本起就被广泛支持,这在很大程度上提升了PHP处理网络并发和I/O...
在Windows操作系统下开发并编译PHP扩展是一个涉及多个步骤的过程,对普通程序员来说可能显得比较神秘,但只要具备C语言知识并熟悉开发的步骤与规则,就能够顺利完成这项工作。以下是详细的步骤和知识点: 1. 准备...