1. 기본 원칙
소스 파일을 읽기 위해 PHP 인터페이스를 가로채는 것을 고려해보세요. 처음에는 Apache와 PHP 사이의 인터페이스를 다루는 것을 고려했습니다. apache의 src/modules/php4/mod_php4.c(PHP가 정적으로 apache로 컴파일하여 설치하는 파일입니다.), send_php()에서 파일 포인터가 차단됩니다. 함수에서는 임시 파일 방식을 사용하며, 복호화 후 파일 포인터를 교체합니다. 이 방법은 테스트를 거쳐 실행 가능한 것으로 입증되었습니다. 그러나 두 개의 파일 작업을 사용해야 하므로 비효율적이며 DSO 방식을 사용할 수 없습니다. Shuangyuan Nursing Home
그래서 PHP가 파일을 읽는 것을 가로채서 캐시에 로드하는 과정을 다시 생각해 보았는데, 열심히 검색한 끝에 Zend 엔진의 zend-scanner.c가 이를 수행한다는 것을 발견했습니다. 이 파일 수정을 시작하세요. 조명 프로젝트
2. 구현 방법
libmcrypt를 암호화 모듈로 사용하고, 이제 DES 방식의 ECB 모드 암호화를 사용합니다.
다음은 파일 암호화 소스 코드입니다. :
C++ 코드
/* ecb.c------여기에서 잘라내기---------* /
/* PHP 소스 코드 버전 0.99 베타용 암호화
우리는 libmcrypt를 사용하여 코드를 암호화하고 있습니다.
먼저 이를 설치
컴파일 명령줄:
gcc -O6 -lmcrypt -lm -o encryptphp ecb.c
사용하기 전에 LD_LIBRARY_PATH를 설정하세요.
GNU copyleft, designs by wangsu , miweicong */
#define MCRYPT_BACKWARDS_COMPATIBLE 1
#define PHP_CACHESIZE 8192
#include
#include
#include
#include sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
main(int argc** argv)
{
char 파일 이름[255]
char 비밀번호[12]; >int readfd;
void *block_buffer;
int keysize;
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]) ;
printf("디코드 모드 시작 중...n");
} else {
printf("사용법: encryptphp [-d] 비밀번호 파일 이름"); >exit (1);
}
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, 키, 키 크기);
if((readfd=open(filename,O_RDONLY,S_IRUSR|S_IWUSR| S_IRGRP) )==-1){
exit(3)
}
fstat(readfd,filestat);
printf("filesize는 %d n입니다.",inputfilesize); ;
inputfilesize=((int)(floor(inputfilesize/PHP_CACHESIZE)))+1)*PHP_CACHESIZE;
printf("치명적: 파일 buffer.n을 실행할 수 없습니다.");
exit(2)}
if((block_buffer=malloc(PHP_CACHESIZE))==NULL){
printf( "치명적: 블록 버퍼를 암호화할 수 없습니다.");
exit(2)
printf(".");
if(!decode){
if(realbufsizefor(i=realbufsize;i((char *)block_buffer)[i]=' ';
}
}
mcrypt_ecb (td, block_buffer, PHP_CACHESIZE)
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("치명적: 파일 액세스 오류.n")
exit(3);
fwrite( file_buffer, inputfilesize, 1, ifp);
free(block_buffer)
free(file_buffer)
fclose(ifp); 🎜>printf ("n");
/*--- ecb.c의 끝 ------------ --- ---------*/
ECB 모드는 블록 길이가 정해진 블록 암호화이기 때문에 여기에는 일부 null 문자가 채워집니다. 국제 전시회
그런 다음 PHP 코드에서 Zend/zend-scanner.c를 다음과 같이 수정합니다.
파일 앞에 추가:
#define MCRYPT_BACKWARDS_COMPATIBLE 1
#include < mcrypt.h >
그런 다음 3510행 주위에 YY_INPUT 정의를 주석 처리합니다.
그런 다음 5150행 주위에서 yy_get_next_buffer() 함수를 수정합니다.
함수 헤더에 정의를 추가합니다.
void *tempbuf;
char *key;
char debugstr[255]; >int td,keysize;
int x,y;
FILE *fp;
그런 다음 주석 처리하세요
YY_INPUT( (&yy_current_buffer- >yy_ch_buf[number_to_move]),
yy_n_chars, num_to_read );
이 문장입니다.
변경됨:
if((yy_n_chars=fread(tempbuf,1,num_to_read,yyin))!=0){
/*decode* /
#define 비밀번호 "PHPphp111222"
#define 디버그 0
key=calloc(1, mcrypt_get_key_size(DES))
gen_key_sha1( key, NULL, 0, keysize, 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);
그런 다음 일반적인 방법에 따라 php를 컴파일하고 설치합니다. libtool에 익숙하지 않기 때문에 구성 시 --를 추가했습니다. -mcrypt이므로 Makefile 케이블 트레이를 수동으로 수정할 필요가 없습니다
더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!