现在的位置: 首页 > 综合 > 正文

修改Zend引擎实现PHP源码加密的原理及实践

2013年02月21日 ⁄ 综合 ⁄ 共 2822字 ⁄ 字号 评论关闭

修改Zend引擎实现PHP源码加密的原理及实践

  PHP文件的源码都是明文,这对于某些商业用途来说,并不适合。 
  因此考虑使用加密的手段保护源码。 

  实在不耐烦等待zend出编译器,而且编译和加密本质上不是一回事儿。自己动手、开始修改。 

一、基本原理

  考虑截获PHP读取源文件的接口。一开始,我考虑从Apache和PHP之间的接口处 处理,参见apache的src/modules/php4/mod_php4.c (这个是PHP用static方式编译进apache,make install 后的文件),在send_php()函数中截获文件指针,采用临时文件的方式,解密后替换文件指针。这种方
法经过测试实践,证明是可行的。但是,必须使用两次文件操作,效率低下,而且对于DSO方式不可采用。 

  由此,重新考虑截获PHP读取文件并装载至缓存的过程,经过费力的寻找,发现在Zend引擎中zend-scanner.c是做此处理的。开始对此文件修改。 

二、实现方法示意 

  采用libmcrypt作为加 密模块,现在采用的是DES方法ECB模式加密, 

下面是文件加密的源代码: 

/* ecb.c-------------------cut here-----------*/ 
/* encrypt for php source code version 0.99 beta 
we are using libmcrypt to encrypt codes, please 
install it first. 
compile command line: 
gcc -O6 -lmcrypt -lm -o encryptphp ecb.c 
please set LD_LIBRARY_PATH before use. 
GNU copyleft, designed by wangsu , miweicong */ 

#define MCRYPT_BACKWARDS_COMPATIBLE 1 
#define PHP_CACHESIZE 8192 
#include < mcrypt.h > 
#include < stdio.h > 
#include < stdlib.h > 
#include < math.h > 
#include < sys/types.h > 
#include < sys/stat.h > 
#include < fcntl.h > 

main(int argc, char** argv) 

int td, i,j,inputfilesize,filelength; 
char filename[255]; 
char password[12]; 
FILE* ifp; 
int readfd; 
char *key; 
void *block_buffer; 
void *file_buffer; 
int keysize; 
int decode=0; 
int realbufsize=0; 
struct stat *filestat; 

if(argc == 3) { 
strcpy(password,argv[1]); 
strcpy(filename,argv[2]); 
} else if(argc == 4 && !strcmp(argv[1],"-d")){ 
strcpy(password,argv[2]); 
strcpy(filename,argv[3]); 
decode=1; 
printf("Entering decode mode ... n"); 
} else { 
printf("Usage: encryptphp [-d] password filenamen"); 
exit(1); 

keysize=mcrypt_get_key_size(DES); 
key=calloc(1, mcrypt_get_key_size(DES)); 

gen_key_sha1( key, NULL, 0, keysize, password, strlen(password)); 
td=init_mcrypt_ecb(DES, key, keysize); 

if((readfd=open(filename,O_RDONLY,S_IRUSR|S_IWUSR|S_IRGRP))==-1){ 
printf("FATAL: Can't open file to read"); 
exit(3); 

filestat=malloc(sizeof(stat)); 

fstat(readfd,filestat); 
inputfilesize=filestat- >st_size; 
printf("filesize is %d n",inputfilesize); 
filelength=inputfilesize; 

inputfilesize=((int)(floor(inputfilesize/PHP_CACHESIZE))+1)*PHP_CACHESIZE; 

if((file_buffer=malloc(inputfilesize))==NULL){ 
printf("FATAL: can't malloc file buffer.n"); 
exit(2); 

if((block_buffer=malloc(PHP_CACHESIZE))==NULL){ 
printf("FATAL: can't malloc encrypt block buffer.n"); 
exit(2); 

j=0; 
while(realbufsize=read (readfd,block_buffer, PHP_CACHESIZE)){ 
printf("."); 
if(!decode){ 
if(realbufsize< PHP_CACHESIZE){ 
for(i=realbufsize;i< PHP_CACHESIZE;i++){ 
((char *)block_buffer)[i]=' '; 


mcrypt_ecb (td, block_buffer, PHP_CACHESIZE); 
} else { 
mdecrypt_ecb (td, block_buffer, realbufsize); 

memcpy(file_buffer+j*PHP_CACHESIZE,block_buffer,PHP_CACHESIZE); 
j++; 

close(readfd); 

if((ifp=fopen(filename,"wb"))==NULL){ 
printf("FATAL: file access error.n"); 
exit(3); 

fwrite ( file_buffer, inputfilesize, 1, ifp); 

free(block_buffer); 
free(file_buffer); 
free(filestat); 
fclose(ifp); 
printf("n"); 

return 0; 


/*--- end of ecb.c ------------------------------------*/ 

抱歉!评论已关闭.