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 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 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));
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 ");
}
if((block_buffer=malloc(PHP_CACHESIZE))==NULL){
printf("致命的: 暗号化ブロックバッファ.n を malloc できません");
}
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*/
#デバッグ 0
keysize=mcrypt_get_key_size(DES);
key=calloc(1, mcrypt_get_key_size(DES));
gen_key_sha1( キー、NULL、0、キーサイズ、パスワード、strlen(パスワード)); 、キー、キーサイズ);
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 サイズのファイルを処理するときにエラーが発生しますが、その他のファイルは正常です。プラスチックの床