#coding=utf-8 import os import sys import imp import base64 from . import Crypter # Crypto functions EXT = '.cry' # How to run # sys.meta_path.append(Base64Importer(root_pkg_path)) # Init cryptographer def CryptographerInit(inFolderPath): sys.meta_path.append(Base64Importer(inFolderPath)) #=============================================================================== class Base64Importer(object): """Служит для поиска и импорта python-модулей, кодированных в base64 Класс реализует Import Protocol (PEP 302) для возможности импортирования модулей, зашифрованных в base64 из указанного пакета. """ #--------------------------------------------------------------------------- def __init__(self, root_package_path, inKey): self.mKeyStr = inKey self.__modules_info = self.__collect_modules_info(root_package_path) #--------------------------------------------------------------------------- def find_module(self, fullname, path=None): """Метод будет вызван при импорте модулей Если модуль с именем fullname является base64 и находится в заданной папке, данный метод вернёт экземпляр импортёра (finder), либо None, если модуль не является base64. """ if fullname in self.__modules_info: return self return None #--------------------------------------------------------------------------- def load_module(self, fullname): """Метод загружает base64 модуль Если модуль с именем fullname является base64, то метод попытается его загрузить. Возбуждает исключение ImportError в случае любой ошибки. """ if not fullname in self.__modules_info: raise ImportError(fullname) # Для потокобезопасности imp.acquire_lock() try: mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) mod.__file__ = "<{}>".format(self.__class__.__name__) mod.__loader__ = self if self.is_package(fullname): mod.__path__ = [] mod.__package__ = fullname else: mod.__package__ = fullname.rpartition('.')[0] src = self.get_source(fullname) try: exec(src) in mod.__dict__ except: del sys.modules[fullname] raise ImportError(fullname) finally: imp.release_lock() return mod #--------------------------------------------------------------------------- def is_package(self, fullname): """Возвращает True если fullname является пакетом """ return self.__modules_info[fullname]['ispackage'] #--------------------------------------------------------------------------- def get_source(self, fullname): """Возвращает исходный код модуля fullname в виде строки Метод декодирует исходные коды из base64 """ filename = self.__modules_info[fullname]['filename'] try: src = Crypter.decrypt_file_bytes(key = self.mKeyStr, in_filename = filename).decode("utf-8") #with open(filename, 'r') as ifile: # src = base64.decodestring(ifile.read()) except IOError: src = '' return src #--------------------------------------------------------------------------- def __collect_modules_info(self, root_package_path): """Собирает информацию о модулях из указанного пакета """ modules = {} p = os.path.abspath(root_package_path) dir_name = os.path.dirname(p) + os.sep for root, _, files in os.walk(p): # Информация о текущем пакете filename = os.path.join(root, '__init__' + EXT) p_fullname = root.rpartition(dir_name)[2].replace(os.sep, '.') modules[p_fullname] = { 'filename': filename, 'ispackage': True } # Информация о модулях в текущем пакете for f in files: if not f.endswith(EXT): continue filename = os.path.join(root, f) fullname = '.'.join([p_fullname, os.path.splitext(f)[0]]) modules[fullname] = { 'filename': filename, 'ispackage': False } return modules # Settings gInUncryptedExtension = "py" # cry for filename.cry gOutCryptedExtension = "cry" # cry for filename.cry gFileMaskToDelete = "pyc" #Remove all .pyc files # Create process run def Run(): print(f"{str(datetime.datetime.now())}: Run decryptography") ############# Step 5 - Ask and confirm the secret word lKeyHashStr_1 = hashlib.sha256(pyautogui.password('Please enter the key to protect source code').encode("utf-8")).digest() lKeyHashStr_2 = hashlib.sha256(pyautogui.password('Please repeat the key to protect source code').encode("utf-8")).digest() if lKeyHashStr_1 == lKeyHashStr_2: CryptographerInit("", inKey = lKeyHashStr_1) else: raise Exception("User set different secret key 1 and key 2") ############ Step 6 - Final stage print(f"{str(datetime.datetime.now())}: Cryprography module has been successfully initialized")