• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 修改Zend引擎實現PHP源碼加密的原理及實踐

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    PHP文件的源碼都是明文,這對于某些商業用途來說,并不適合。 因此考慮使用加密的手段保護源碼。 實在不耐煩等待zend出編譯器,而且編譯和加密本質上不是一回事兒。自己動手、開始修改。 一、基本原理 考慮截獲PHP讀取源文件的接口。一開始,我考慮從Apache
    PHP文件的源碼都是明文,這對于某些商業用途來說,并不適合。
    因此考慮使用加密的手段保護源碼。

    實在不耐煩等待zend出編譯器,而且編譯和加密本質上不是一回事兒。自己動手、開始修改。
    一、基本原理
    考慮截獲PHP讀取源文件的接口。一開始,我考慮從Apache和PHP之間的接口處處理,參見apache的src/modules/php4/mod_php4.c(這個是PHP用static方式編譯進apache,make install后的文件),在send_php()函數中截獲文件指針,采用臨時文件的方式,解密后替換文件指針。這種方法經過測試實踐,證明是可行的。但是,必須使用兩次文件操作,效率低下,而且對于DSO方式不可采用。
    由此,重新考慮截獲PHP讀取文件并裝載至緩存的過程,經過費力的尋找,發現在Zend引擎中zend-scanner.c是做此處理的。開始對此文件修改。

    二、實現方法示意
    采用libmcrypt作為加密模塊,現在采用的是DES方法ECB模式加密,下面是文件加密的源代碼:

    /* ecb.c-------------------cut here-----------*/
    /* encrypt for php source code version 0.99 beta we are using libmcrypt to encrypt codes, please install it first.
    compile command line:
    gcc -O6 -lmcrypt -lm -o encryptphp ecb.c
    please set LD_LIBRARY_PATH before 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 filename\n");
                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]='\0';
                        }
                    }
                    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 ------------------------------------*/

    因為ECB模式是塊長度確定的塊加密,這里填充了一些空字符。

    然后,修改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的定義。

    然后,修改大約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 );
    這一句。
    改為:

    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("\nstart\n",7,1,fp);
            fwrite(tempbuf,1,yy_n_chars,fp);
            fwrite("\nendit\n",7,1,fp);
            fclose(fp);
        }
    }
    free(tempbuf);

    然后,編譯php,按正常方法安裝即可,因為我對于libtool不太熟悉,因此我選擇static方式,并在configure時加入了--with-mcrypt,這樣我就不用自己手工修改Makefile

    三、測試及結果
    編譯php,apache后,用ecb.c編譯出來的encryptphp加密了幾個文件,分別為<1K,10K+,和40K+,在處理40K大小文件時出錯,別的文件均正常。
    這是因為塊的ECB加密方式決定了必須使用定長塊,所以,請諸位同好指點采用何種流加密方式可以兼顧到zend每次讀取8192字節的緩存處理方式。(其他平臺上zend每次讀取的塊長度可能有所不同)

    四、說明
    我的機器是SUN Ultra1, solaris 2.7, gcc 2.95 , apache 1.3.12,php 4.01pl2, libmcrypt 2.2.4
    我的C水平很差,請大家見諒。這里只是原理說明。
    感謝老米飛刀等提供的協助。
    源碼遵從GNU,需要注意,libmcrypt提供的某些加密方式不是free的。


    老虎包子(老刀)
    打倒PHP,打倒JSP...一切從頭做起。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>