python加密Django框架代码(通过修改Cpython解释器)

文章目录

前言

注意此博文代码仅限于在linux系统下使用,因为没有做windows的适配。
本文承接上篇博文链接: 加密python单文件代码(无import自造模块)
并在其上进行以下改进:
1.现在在import自造模块之前会对模块代码进行解密,并加载进内存。
2.去掉了Cpython解释器中默认的pyc文件缓存(即__pycache__目录)以减少通过pyc文件解密py文件的可能。
3.新增可以在目录中递归查找.py后缀文件的工具,以方便用户将指定目录下的所有py文件全部加密。
4.可以加密django框架代码,并保证代码的运行正常。

一、实现效果

1.加密之前文件树

python加密Django框架代码(通过修改Cpython解释器)
2.使用工具加密py文件
python加密Django框架代码(通过修改Cpython解释器)
3.加密后文件树
python加密Django框架代码(通过修改Cpython解释器)
注意其中的bw_code目录是加密后的文件,文件已经按原来项目的结构安排好了。

4.运行加密后的项目

python加密Django框架代码(通过修改Cpython解释器)
成功运行。
5.访问网页
python加密Django框架代码(通过修改Cpython解释器)

; 二、代码修改

1.加密工具代码

代码如下:

#include
#include
#include
#include
#include
#include
#include
#define FILEPATHLENGTH 1024

char *bw_dir_path_preffix = "/bw_code";

long fileRead(char fileName[FILEPATHLENGTH],char **buffer){

     FILE *fp = fopen(fileName,"rb");
     if(fp == NULL){
         printf("open file is failed");
         exit(1);
     }

     fseek(fp,0,SEEK_END);

     long fileSize = ftell(fp);

     fseek(fp,0,SEEK_SET);

     *buffer = (char*)malloc(fileSize);
     fread(*buffer,1,fileSize,fp);

     fclose(fp);
     return fileSize;
 }

void fileWrite(char fileName[FILEPATHLENGTH],char *buffer,long fileSize){

     FILE *fp = fopen(fileName,"wb");
     if(fp == NULL){
         printf("open file is failed");
         exit(1);
     }
     fwrite(buffer,1,fileSize,fp);
     fclose(fp);
 }

void encrypt_decode(char encryptFile[FILEPATHLENGTH],char encryptedFile[FILEPATHLENGTH],int key){
    char *buffer;
    long fileSize = fileRead(encryptFile,&buffer);

    for(int i = 0; i < fileSize; i++){
        buffer[i] = buffer[i]^key;
    }
    fileWrite(encryptedFile,buffer,fileSize);
}

char *get_file_ext(char *filename){
    int len = (int)strlen(filename);
    for(int i=len-1;i>=0;i--){
        if(filename[i]=='.'){
            return filename+i+1;
        }
    }
    return NULL;
}

int mkdirs(char *path)
{
    char str[512];
    strncpy(str, path, 512);
    int len=strlen(str);
    for(int i=0; i<len; i++ )
    {
        if( str[i]=='/' )
        {
            str[i] = '\0';
            if( access(str,0)!=0 )
            {
                mkdir( str, 0755 );
            }
            str[i]='/';
        }
    }
    if( len>0 && access(str,0)!=0 )
    {
        mkdir( str, 0755 );
    }
    struct stat s;
    stat(path,&s);
    if(S_ISDIR(s.st_mode) )return 0;
    return 1;
}

char *get_remain_path(char *base_path, char *dir_path){
    if(strlen(base_path)>=strlen(dir_path)){
        return NULL;
    }
    for(int i=0; i<strlen(base_path);i++){
        if(base_path[i]!=dir_path[i]){
            return &(dir_path[i]);
        }
    }
    return &(dir_path[strlen(base_path)]);
}

int encrypt(char * path, char *base_path , int recursive)
{
    DIR * p_dir;
    struct dirent * entry;
    size_t len;
    char * sub_path;

    p_dir = opendir(path);
    if (p_dir == NULL)
    {
        printf("Can not open %s/n", path);
        return -1;
    }
    while((entry = readdir(p_dir)) != NULL)
    {
        len = strlen(path) + strlen(entry->d_name) + 3;
        sub_path = calloc(len, 1);
        if (sub_path == NULL)
        {
            printf("out of memory/n");
            closedir(p_dir);
            return -1;
        }
        char code_dir_root[strlen(base_path)+strlen(bw_dir_path_preffix)+1];
        strcpy(code_dir_root, base_path);
        strcat(code_dir_root, bw_dir_path_preffix);
        mkdirs(code_dir_root);

        strcpy(sub_path, path);
        strcat(sub_path, "/");
        strcat(sub_path, entry->d_name);

        if (entry->d_type == DT_DIR && recursive != 0 && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
        {

            char *remain_path = get_remain_path(base_path, sub_path);
            if(remain_path!=NULL){

                char code_dir[strlen(base_path)+strlen(bw_dir_path_preffix)+strlen(remain_path)+1];
                strcpy(code_dir, base_path);
                strcat(code_dir, bw_dir_path_preffix);
                strcat(code_dir, remain_path);
                if(code_dir!=NULL){
                    mkdirs(code_dir);
                }
                encrypt(sub_path, base_path,recursive);
            }else{
                printf("remain_path is NULL\n");
                exit(1);
            }
        }
        if(entry->d_type == DT_REG){

            char *ext = get_file_ext(sub_path);
            if(ext!=NULL && strcmp(ext,"py")==0){
                char *remain_path = get_remain_path(base_path, sub_path);
                if(remain_path!=NULL){

                    char code_file[strlen(base_path)+strlen(bw_dir_path_preffix)+strlen(remain_path)+1];
                    strcpy(code_file, base_path);
                    strcat(code_file, bw_dir_path_preffix);
                    strcat(code_file, remain_path);

                    code_file[strlen(code_file)-1] = 'w';
                    code_file[strlen(code_file)-2] = 'b';
                    code_file[strlen(code_file)-3] = '.';
                    encrypt_decode(sub_path, code_file,12);
                }else{
                    printf("remain_path is NULL\n");
                    exit(1);
                }
            }
        }
        free(sub_path);
    }
    closedir(p_dir);
    return -1;
}

int main(int argv, char **argc){
    if(argv!=2){
        printf("Usage: enc [file_abs_path]");
        return -1;
    }
    encrypt(argc[1], argc[1], 12);
    return 0;
 }

编译即可使用,代码量稍多,刚开始写C代码还是不大习惯,如有纰漏欢迎指出。
注意现在只支持绝对路径。

2.Cpython代码修改

关于import导入的流程我可能会单独写一篇博文,现在只介绍部分关键代码,整个改完的解释器代码我已经上传github,链接https://github.com/MakeEarthBetter/cpythondiy/tree/master。注意分支是master,十分期望您的star❤。

一.添加自己文件后缀的import loader.

import时会遍历loaders,尝试找到对应后缀的文件,我们在这添加我们自己的bw文件

python加密Django框架代码(通过修改Cpython解释器)
Cpython默认的loaders为
python加密Django框架代码(通过修改Cpython解释器)
第二个是pyc文件,第三个是py文件

; 二.修改Cpython找到文件时的操作

python加密Django框架代码(通过修改Cpython解释器)
此处是Cpython加载文件代码的部分,在此处先将bw文件解码。

三. 删除解码后的文件

这里是加载代码处,由于此处为必经之路,在此处进行中间文件的删除。

python加密Django框架代码(通过修改Cpython解释器)

; 总结

由于修改的部分主要在Cpython代码处,而import的流程在瓷片博文又不想走一遍,所以就写到这吧。import流程请见下篇博文。代码请到github领取。

Original: https://blog.csdn.net/qq_42455809/article/details/126467196
Author: 工丨具丨人
Title: python加密Django框架代码(通过修改Cpython解释器)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/736857/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球