ホームページ  >  記事  >  php教程  >  Zend エンジンを変更して PHP ソース コード暗号化を実装する原則と実践

Zend エンジンを変更して PHP ソース コード暗号化を実装する原則と実践

黄舟
黄舟オリジナル
2016-12-14 11:46:581153ブラウズ

1. 基本原則
PHP がソース ファイルを読み取るためのインターフェイスをインターセプトすることを検討します。最初は、Apache と PHP の間のインターフェイスを扱うことを考えました。Apache の src/modules/php4/mod_php4.c (これは、PHP が静的に Apache にコンパイルして install するファイルです) を参照し、send_php() でファイル ポインタがインターセプトされます。関数内では一時ファイルの方法を使用しており、復号化後にファイルポインタが置き換えられます。この方法はテストされ、実行可能であることが証明されています。ただし、2 つのファイル操作を使用する必要があるため、非効率的であり、DSO には使用できません。 Shuangyuan Nursing Home
そこで、PHP の読み取りファイルをインターセプトしてキャッシュにロードするプロセスを再検討したところ、zend-scanner.c が Zend エンジンでこれを実行していることがわかりました。このファイルの変更を開始します。照明プロジェクト

2. 実装方法

暗号化モジュールとして libmcrypt を使用し、現在 DES メソッド ECB モード暗号化を使用しています。

以下はファイル暗号化のソース コードです:

C++ コード
/* ecb.c-- - -----ここをカット----------*/
/* php ソース コード バージョン 0.99 ベータ版の暗号化
暗号化には libmcrypt を使用していますコードを
最初にインストールしてください
コマンドラインをコンパイルしてください:
gcc -O6 -lmcrypt -lm -o encryptphp ecb.c
GNU copyleft、wangsu 、 miweicong によって設計されました */

#define MCRYPT_BACKWARDS_COMPATIBLE 1

#define PHP_CACHESIZE >
#include < math.h > ; sys/types.h >
#include < fcntl.h >


main(int argc, char** argv) i ,j,inputfilesize,filelength;
charファイル名[12];
int readfd;
void *block_buffer;

int decode=0;

int realbufsize=0;
struct stat *filestat;

if(argc == 3) {
strcpy(password,argv[1]); ;
} else if(argc == 4 && !strcmp(argv[1],"-d")){
strcpy(filename,argv[3]); = 1;
printf("デコードモードに入ります...n");
printf("使用法: encryptphp [-d] パスワードファイル名");
}

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

gen_key_sha1( key, NULL, 0, keysize, パスワード, strlen(password));

td=init_mcrypt_ecb(DES, key, keysize);


if((readfd=open(filename,O_RDONLY,S_IRUSR|S_IWUSR|S_IRGRP))==-1){
printf("致命的: ファイルを開けて読み取ることができません")
exit(3);

filestat=malloc(sizeof(stat));

fstat(readfd,filestat);
inputfilesize=filestat- >st_size;
filelength=inputfilesize; inputfilesize =((int)(floor(inputfilesize/PHP_CACHESIZE))+1)*PHP_CACHESIZE;

if((file_buffer=malloc(inputfilesize))==NULL){
printf("致命的: ファイル バッファーを malloc できません。 n ");

exit(2);

}
if((block_buffer=malloc(PHP_CACHESIZE))==NULL){
printf("致命的: 暗号化ブロックバッファ.n を malloc できません");

exit(2) ) ;

}

j=0;

while(realbufsize=read (readfd,block_buffer, PHP_CACHESIZE)){
if(!decode){
if(realbufsize< PHP_CACHESIZE); ( 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);
}

close(readfd);

if((ifp=fopen(filename,"wb")); = NULL){
printf("致命的: ファイル アクセス エラー。n");
exit(3)
fwrite ( file_buffer, inputfilesize, 1, ifp); ;
free(filestat);
fclose(ifp);

return 0;

}
/*--- ecb.c の終わり- ------------------------*/
ECB モードはブロック長が決められたブロック暗号化であるため、ここにはいくつかの null 文字が埋められます。国際展示会

次に、php コード内の Zend/zend-scanner.c を次のように変更します:

(私の php バージョンは 4.01pl2、SUNsparc/solaris 2.7、gcc 2.95;)

ファイルの前に追加します:

#define MCRYPT_BACKWARDS_COMPATIBLE 1
#include < mcrypt.h >

次に、3510行目あたりのYY_INPUTの定義をコメントアウトします。

次に、 yy_get_next_buffer() 関数を 5150 行目あたりに変更します。
void *tempbuf;
char debugstr[255];
int x,y; という定義を追加します。 ;
FILE *fp;
次に、文
YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]),
yy_n_chars, num_to_read ); をコメントアウトします。
次のように変更します:

tempbuf=malloc(num_to_read);
if((yy_n_chars=fread(tempbuf,1,num_to_read,yyin))!=0){
/*decode*/

#define パスワード "PHPphp111222"

#デバッグ 0

keysize=mcrypt_get_key_size(DES);
key=calloc(1, mcrypt_get_key_size(DES));
gen_key_sha1( キー、NULL、0、キーサイズ、パスワード、strlen(パスワード)); 、キー、キーサイズ);

mdecrypt_ecb(td, 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);

次に、libtool に慣れていないため、静的メソッドを選択し、- を追加しました。 mcrypt を使用すると、Makefile ケーブル トレイを手動で変更する必要がなくなります

3. テストと結果

php と apache をコンパイルした後、ecb.c によってコンパイルされた encryptphp を使用して、1K 未満のいくつかのファイルを暗号化しました。 10K+ および 40K+ では、40K サイズのファイルを処理するときにエラーが発生しますが、その他のファイルは正常です。プラスチックの床

これは、ブロックの ECB 暗号化方式により、固定長ブロックを使用する必要があると判断されるためです。 したがって、8192 バイトを読み取る zend のキャッシュ処理方式を考慮して、どのストリーム暗号化方式を使用できるかについてアドバイスをお願いします。毎回。 (他のプラットフォームでは、zend によって毎回読み取られるブロック長が異なる場合があります)

その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) にご注意ください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。