The principle and practice of modifying Zend engine to implement PHP source code encryption

Source: Internet
Author: User
Tags define definition php file php and php code strlen version zend
The source code for the encrypted PHP file is plaintext, which is not appropriate for some commercial purposes.
So consider using encryption to protect the source code.

It's really impatient to wait for Zend out of the compiler, and compilation and encryption are inherently not the same thing. Do it yourself and start revising it.

First, the basic principle

Consider intercepting the interface that PHP reads from the source file. In the beginning, 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 apache,make install in a static way), Intercepts the file pointer in the send_php () function, using the temporary file, and decrypting and replacing the file pointer. This method has been proved to be feasible by testing and practice. However, must use two times file operation, inefficient, and for the DSO method can not be used.
Thus, the process of intercepting PHP to read the file and loading it into the cache is reconsidered, and it is found that ZEND-SCANNER.C is doing this in the Zend engine. Start modifying this file.

Second, the realization method signals

Using Libmcrypt as the encryption module, the Des method is now used for ECB mode encryption,

The following is the source code for the file encryption:

/* ECB.C-------------------cut here-----------* *
/* Encrypt for PHP source code version 0.99 Beta
We are using Libmcrypt to encrypt codes, please
Install it.
Compile command line:
Gcc-o6-lmcrypt-lm-o encryptphp ECB.C
Please set ld_library_path before to 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 model is block-length-determined block 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;)

File before adding:

#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 around 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.
To

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 and install it in the normal way, because I'm not familiar with Libtool, so I chose the static method and joined the--with-mcrypt in configure, so I didn't have to manually modify makefile

III. Testing and Results

After compiling the Php,apache, ECB.C compiled the encryptphp to encrypt several files, respectively < 1k,10k+, and 40k+, when processing 40K size file error, other files are normal.
This is because the ECB encryption of the block determines the need to use fixed-length blocks, so let's all have a look at what kind of streaming encryption can take into account the Zend each read 8192 bytes of cache processing mode. (Zend per read block length may vary on other platforms)

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 bad, please forgive me. This is just a schematic.
Thanks for the help of old Mi Fei knives.
The source code complies with GNU, and it should be noted that some of the encryption methods provided by Libmcrypt are not free.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.