First, the basic principle
Consider intercepting PHP to read the source file interface. At first, I considered processing from the interface between Apache and PHP, see Apache's src/modules/php4/mod_php4.c (this is the file that PHP compiles into the Apache,make install after the static method), Intercept the file pointer in the send_php () function, and use the temporary file to decrypt and replace the file pointer. This method has been proved to be feasible by testing practice. However, two file operations must be used, inefficient, and not available for DSO mode. Double-Edge Nursing Home
From this, the process of intercepting PHP to read files and loading into the cache is reconsidered, and it is hard to find the zend-scanner.c in the Zend engine. Start modification to this file. Lighting Engineering
Second, the realization method schematic
Using Libmcrypt as the encryption module, the Des method is now used for ECB mode encryption,
Here is the source code for file encryption:
C + + code
/* ECB.C-------------------cut here-----------*/
/* Encrypt for PHP source code version 0.99 Beta
We are using the Libmcrypt to encrypt codes
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------------------------------------*/
Because the ECB mode is block-length-determined chunk encryption, some empty characters are populated here. International Exhibition
Then, modify the PHP code in ZEND/ZEND-SCANNER.C as follows:
(My PHP version is 4.01PL2, Sunsparc/solaris 2.7, gcc 2.95;)
Add before File:
#define MCRYPT_BACKWARDS_COMPATIBLE 1
#include < mcrypt.h >
Then, comment out the definition of yy_input around 3510 lines.
Then, modify the Yy_get_next_buffer () function before and after approximately 5150 lines:
function header Plus definition:
void *tempbuf;
Char *key;
Char debugstr[255];
int td,keysize;
int x, y;
FILE *FP;
Then, comment out
Yy_input (&yy_current_buffer->yy_ch_buf[number_to_move]),
Yy_n_chars, Num_to_read);
This sentence.
Switch
Tempbuf=malloc (Num_to_read);
if ((Yy_n_chars=fread (Tempbuf,1,num_to_read,yyin))!=0) {
/*decode*/
#define PASSWORD "PHPphp111222"
#define DEBUG 0
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);
MDECRYPT_ECB (TD, Tempbuf, Yy_n_chars);
memcpy ((&yy_current_buffer->yy_ch_buf[number_to_move]), tempbuf,yy_n_chars);
if (Debug) {
Fp=fopen ("/tmp/logs", "WB");
Fwrite ("Nstartn", 7,1,FP);
Fwrite (TEMPBUF,1,YY_N_CHARS,FP);
Fwrite ("Nenditn", 7,1,FP);
Fclose (FP);
}
}
Free (TEMPBUF);
Then, compile PHP, the normal way to install, because I am not familiar with Libtool, so I chose the static mode, and configure when the--with-mcrypt, so I do not have to manually modify the makefile cable tray
III. Testing and Results
Compiled Php,apache, with ECB.C compiled encryptphp encrypted several files, respectively, < 1k,10k+, and 40k+, in processing 40K size file error, other files are normal. Plastic Flooring
This is because the ECB encryption method of the block determines the need to use fixed-length blocks, so, you have to ask what kind of stream encryption method to take into account the Zend each read 8192 bytes of cache processing mode. (The block lengths Zend per read on other platforms may vary)
The above introduces the PHP site source code modification Zend Engine to implement the principle and practice of PHP source code encryption, including the PHP site source content, I hope that the PHP tutorial interested in a friend helpful.