1. 基本原則
PHP がソース ファイルを読み取るためにインターフェースをインターセプトすることを検討してください。最初は、Apache と PHP の間のインターフェイスを扱うことを考えました。Send_php() 内の Apache の src/modules/php4/mod_php4.c (これは、PHP が静的に Apache にコンパイルされ、make install された後のファイルです) を参照してください。一時ファイルの方法を使用して関数内でインターセプトされ、復号化後にファイル ポインタが置き換えられます。この方法はテストされ、実行可能であることが証明されています。ただし、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、miwe icong によって設計されました */
# MCRYPT_BACKWARDS_COMPATIBLE 1
#define PHP_CACHESIZE 8192
#include < stdlib.h >
# include < sys/types.h >
#include < char** argv
int; ,j,inputfilesize,filelength;
charファイル名[12];
char *keysize;
int realbufsize=0;
struct stat *filestat;
if(argc == 3) {
strcpy(filename,argv [2]) ; else if(argc = = 4 && !strcmp(argv[1],"-d")){
strcpy(パスワード,argv[3]);
decode =1;デコードモード ... n");
} else {
printf("使用法: encryptphp [-d] パスワード ファイル名");
exit(1);
}
keysize= mcrypt_get_key_size (des);
Key = Calloc (1, mcrypt_key_size (des)); td = Init_mCrypt_ECB (des, キー, キーサイズ);
printf("致命的: 読み取るファイルを開けません");
filestat=malloc(sizeof(stat));
inputfilesize=filestat- >st_size;
printf("ファイルサイズは %d n",inputfilesize);
inputfilesize=((int)(floor(inputfilesize/PHP_CACHESIZE))+1)*PHP_buffer; =malloc(inputfilesize))==NULL){
printf("致命的: ファイル バッファ .n を malloc できません");
}
if((block_buffer=malloc(PHP_CACHESIZE)) ){
printf("致命的: 暗号化ブロック バッファ.n を malloc できません");
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");
終了(3);
}
fwrite ( file_buffer, inputfilesize, 1, ifp);
free(block_buffer);
free(file_buffer);
無料(ファイル統計);
fclose(ifp);
printf("n");
0 を返す;
}
/*--- ecb.c の終わり -------------------------------------- */
ECB モードはブロック長が決定されたブロックであるため、ここにいくつかの空文字が入力されています。国际展示会
その後、php代打中 Zend/zend-scanner.c を修正します:
(我的php バージョンは 4.01 pl2, SUNsparc/solaris 2.7, gcc 2.95;)
文件前追加:
#define MCRYPT_BACKWARDS_COMPATIBLE 1
#include < mcrypt.h >
その後、約 3510 行前後の YY_INPUT の定義を変更します。
char *キー;
char debugstr[255];
int td,キーサイズ;
int x,y;
ファイル *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 password "PHPphp111222"
#define debug 0
keysize=mcrypt_get_key_size(DES);
key=calloc(1, mcrypt_get_key_size(DES));
gen_key_sha1( キー, NULL, 0, キーサイズ, パスワード, strlen(パスワード));
td=init_mcrypt_ecb(DES, キー, キーサイズ);
mdecrypt_ecb(td, tempbuf, yy_n_chars);
memcpy((&yy_current_buffer- >yy_ch_buf[移動する番号]),tempbuf,yy_n_chars);
if(デバッグ){
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);
その後、编译php、按通常の方法ですぐにインストールできます、私がlibtool不熟熟のため、静的方法を選択します、構成時に追加しました--with-mcrypt、これは手動で修正されませんMakefile 电缆桥架
三、测试及结果
编译php,apache后,用ecb.c编译出来的encryptphp加密了几个文件,分爫為< 1K、10K+、および 40K+、40K サイズのファイルを処理するときに問題が発生するのは、いずれのファイルも正常です。圧縮方式は、zend ごとに 8192 文字を取得する保存処理方式と併用できます。 (他のプラットフォームでは、zend ごとに取得されるブロックの長さは異なる可能性があります)
http://www.bkjia.com/PHPjc/318873.html
www.bkjia.com
true
http://www.bkjia.com/PHPjc/318873.html