Обфускация данных программы Python
В данном руководстве мы узнаем, как “запутать” программу на Python. Иногда мы можем столкнуться со сценарием, когда по определенным причинам мы должны доставить код напрямую клиенту. Однако мы потеряем контроль над кодом, выполнив такую функцию.
В таких случаях мы можем зашифровать скрипт, чтобы защитить его, сохранить контроль и включить несколько резервных условий для управления зависимостью, как если бы мы доставляли код для использования только на определенное время.
Для решения данной задачи мы будем использовать библиотеку pyarmor python, реализующую возможность обфускации данных любого кода программы Python.
Создание базовой функции
Мы начнем с создания нового программного файла Python, чтобы реализовать обфускацию в коде Python. В файле мы определим функцию вывода и зашифруем ее позже.
Давайте рассмотрим следующий фрагмент кода для функции вывода.
# importing the required modules import os import json import sys from datetime import datetime # defining an inference function def infer(person_name = "", tag = True): ''' if the present year is 2021, then inference function will execute properly, else it fails. Here the attribute variable contains the string version of the date in MM-DD-YYYY format ''' print("Hello " + person_name + ", the inference function has been initiated successfully") atr = str(datetime.now().strftime('%m-%d-%Y')) resp = "Your license has been expired, please contact us." expiration_year = int(2023) try: assert int(atr.split('-')[-1]) == expiration_year, resp except AssertionError as e: print(resp) sys.exit() # if the above assertion is True, it will reach until this point, # otherwise it will stop in the previous line. if tag: print("Inference function has been done properly!") return True else: return False if __name__ == "__main__": _ = infer(person_name = "Peter Parker") ''' Function outputs, Case 1: if expiration_year = int(2021) Hello Peter Parker, the inference function has been intiated successfully Inference function has been done properly! [Finished in 0.2s] Case 2: if expiration_year = int(2022) Hello Peter Parker, the inference function has been intiated successfully Inference function has been done properly! [Finished in 0.2s] Case 3: if expiration_year = int(2023) Hello Peter Parker, the inference function has been intiated successfully You license has been expired, please contact us. [Finished in 0.2s] '''
Hello Peter Parker, the inference function has been initiated successfully Your license has been expired, please contact us.
В приведенном выше фрагменте кода мы импортировали некоторые необходимые модули. Затем мы определили функцию вывода как infer(), которая принимает два параметра – person_name и tag = True. Затем мы распечатали инструкцию для пользователя, запускающего функцию вывода.
Позже мы определили переменную как atr, которая хранит текущую дату и строковую переменную как resp. Мы также присвоили 2023 году еще одну переменную expiration_year. Затем мы использовали метод try-exception для обработки любого исключения, если оно возникло.
Наконец, мы использовали условные операторы if-else для вывода оператора в соответствии с ситуацией. А также мы назначили __name__ на «__main__» для выполнения функции вывода.
Теперь давайте сохраним этот файл Python в папке.
Шифрование файла с помощью pyarmor
Процесс шифрования файла с помощью pyarmor делится на два этапа:
Шаг 1. Установка пакета pyarmor.
Мы можем установить пакет pyarmor с помощью установщика pip, как показано ниже.
Шаг 2. Шифрование файла python.
Мы можем зашифровать файл, введя следующую команду в командной строке.
$ pyarmor obfuscate --restrict=0
Теперь давайте реализуем указанную выше команду в файле func.py.
$ pyarmor obfuscate --restrict=0 func.py
Теперь, если мы откроем папку, состоящую из исходного файла func.py, мы увидим новую подпапку, созданную как dist.
В папке dist мы найдем другую папку pytransform и зашифрованный файл func.py.
Теперь давайте посмотрим на содержимое этого файла.
Файл: func.py (зашифрованный)
from pytransform import pyarmor_runtime pyarmor_runtime() __pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f\x52\x00\. ', 2)
Импорт функции вывода
Как только мы доберемся до этого раздела, давайте попробуем импортировать этот зашифрованный func.py в новый файл python, известный как new.py, который мы создали в папке dist.
Обязательные ключи, которые содержит pyarmor, позволяют нам расшифровать func.py во время выполнения. Папка pytransform обуславливает их наличие; следовательно, предполагает создание кода, нечитаемого для других глаз.
Однако, если мы хотим внести некоторые изменения в фактический скрипт func.py, мы должны начать с шага 1 и продолжить, следуя тем же шагам.
Давайте рассмотрим следующий фрагмент кода, который мы должны ввести в файл new.py.
# importing the inference function definition inside the func.py file from func import infer _ = infer(person_name = "Tony Stark")
Hello Tony Stark, the inference function has been initiated successfully Your license has been expired, please contact us.
В приведенном выше фрагменте кода мы импортировали функцию вывода func.py в новый файл python, который мы создали как new.py. Затем мы выполнили эту функцию с той же конфигурацией, что и func.py.
PyArmor: как запутать код, чтобы защитить программное обеспечение
Все еще не шифруете свой скрипт? Тогда самое время изучить обфускацию. Сегодня познакомлю с полезной библиотекой PyArmor, расскажу о двух методах работы модуля и на собственном примере покажу, как запутать код от нежелательного просмотра третьими лицами.
В повседневной работе существуют ситуации, когда по очевидным причинам необходимо предоставить скрипты заказчику, но, пересылая собственные разработки, в полном объеме можно потерять контроль над ними, включая авторские права на реализованные коды.
В таких случаях целесообразно защитить собственные коды, зашифровав их (защитить/сохранить/добавить условия для управления зависимостями внутри кода), точно также, как если бы стояла задача предоставления кода для пользования клиенту в течение какого-либо определенного периода времени.
Разработчики скриптов знают, что код на Python поддерживает анализ байт-кода, позволяющий ускорять работу интерпретатора и сам код на Python очень сложно защитить от нежелательного просмотра третьими лицами. Даже новички в разработке скриптов на Python могут заполучить исходный скрипт .py из файла .exe.
Для этого случая на Python существует очень полезная библиотека pyarmor с помощью которой можно воспользоваться всеми вышеизложенными функциями защиты скрипта от нежелательного взлома и метод, который позволяет защитить код называется обфускация.
Библиотека PyArmor имеет несколько вариантов работы – через консоль, а также с использованием localhost GUI – графического пользовательского интерфейса.
Установка и использование библиотеки pyarmor
В консоли необходимо выполнить следующую команду, чтобы установить модуль:
Для того чтобы начать работу с графическим интерфейсом библиотеки необходимо сперва его установить, выполнив следующую команду:
Библиотеки успешно установлены, теперь можно приступить непосредственно к самому шифрованию скрипта.
В первую очередь необходимо создать отдельную папку, в которой будет храниться скрипт с кодом «my_script.py».
В качестве примера скрипта возьму самый простейший скрипт с математическими функциями и с определением функции вывода (функция вывода довольно проста и не нуждается в каких-либо пояснениях):
def math_primer1(x, y): return x + y * x * y def math_primer2(x, y): return x * y ** (x + y) if __name__ == «__main__»: result1 = math_primer2(2, 3) result2 = math_primer1(1, 2) print(result1, result2)
Теперь зашифрую этот код, выполнив в консоли несколько команд.
Для начала необходимо изменить путь до директории в которой лежит файл через:
Затем необходимо выполнить команду обфускации:
Как обезопасить исходники своего python-приложения
Рано или поздно все python-разработчики стают перед выбором: отдать заказчику приложение в исходниках или скрыть их. И вот во втором случае у многих (особенно недавно знакомых с этим прелестным языком) начинаются проблемы: поиск по гуглу, как правило, ничего не дает, идей никаких (или все бредовые).
И что же делать в таком случае?
Первой мыслью было отдавать pyc-файлы. Тогда я ещё не вникал в то, что это такое на самом деле. После нескольких часов проведённых в поисках ответов чем это грозит был сделан единственно возможный вывод: вариант не пройдет. Для python < 2.7 «декомпиляторов» полно бесплатных, а 2.7 и выше за сравнительно небольшие деньги обещают выдать в виде исходных кодов. Да ещё и эта тулза, с которой я за считанные мгновения получил свой код один-в-один.
Вариант сборки в бинарник показался достаточно заманчивым. Вот только, как оказалось, все сборщики (ниже я приведу пример cx_Freeze) фактически только и делают что пакуют .pyc в архив, то есть абсолютно не защищают исходные коды.
Предложим у нас есть проект проект с такой структурой (это всего лиш пример):
- В файле main.py у нас должен быть фактически только вызов главного модуля, если же там что-то большее — желательно оформить это в отдельный модуль
- Файлы __init__.py желательно чтоб были вообще пустые.
- $ sudo apt-get install cython
- Создаем в корне проекта файл compile.py:
from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [ Extension("TestModule.Config", ["TestModule/Config.py"]), Extension("ui.mainwindow", ["ui/mainwindow.py"]), Extension("ui.loginwindow", ["ui/loginwindow.py"]), ] setup( name = 'Test App', cmdclass = , ext_modules = ext_modules )
- $ sudo apt-get install cx-freeze
- В корне проекта создаем файл pack.py:
from cx_Freeze import setup, Executable setup( name = "Test App", version = "0.1", description = "test", executables = [Executable("main.py")])
После проверки можно отдавать пакет заказчику.
P.S. Надеюсь кому-то это простое how-to сэкономит столько же времени, сколько могло бы сэкономить мне.