PHP File source code is clear, which for some commercial purposes, not suitable.
So consider using encryption to protect the source code.
It's really impatient to wait for Zend out of the compiler, and compiling and encrypting is essentially not the same thing. Do it yourself and start revising.
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.
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.
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:
/* 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.
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 makefile
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.
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)
Iv. description
My machine is Sun Ultra1, Solaris 2.7, GCC 2.95, Apache 1.3.12,
PHP 4.01pl2, Libmcrypt 2.2.4
My c level is very poor, please forgive us. This is just a schematic explanation.
Thanks to old Miffy knives and other assistance provided.
The source complies with GNU, and it is important to note that some of the encryption methods provided by Libmcrypt are not free.