Запутывать код Python?

Я ищу, как скрыть мой исходный код Python.

print "hello World !" 

Как я могу закодировать этот пример, чтобы он не читался человеком? Мне сказали использовать base64, но я не уверен, как.

26 ответов

Это только ограниченное решение обфускации первого уровня, но оно встроено: в Python есть компилятор для байт-кода:

python -OO -m py_compile <your program.py>

производит .pyo файл, содержащий байт-код, где удаляются строки документации и т. д. Вы можете переименовать .pyo файл с .py расширение и python <your program.py> работает как ваша программа, но не содержит вашего исходного кода.

PS: "ограниченный" уровень запутывания, который вы получаете, таков, что можно восстановить код (с некоторыми именами переменных, но без комментариев и строк документации). Смотрите первый комментарий, как это сделать. Однако в некоторых случаях этот уровень запутывания может считаться достаточным.

PPS: если ваша программа импортирует модули, запутанные таким образом, вам нужно переименовать их с помощью .pyc вместо суффикса (я не уверен, что это не сломается однажды), или вы можете работать с .pyo и запустить их с python -O ….pyo (импорт должен работать). Это позволит Python найти ваши модули (в противном случае Python ищет .py модули).

чтобы он не читался человеком?

я имею в виду весь файл закодирован!! когда вы открываете его, вы ничего не можете понять..! это то, что я хочу

Как максимум, вы можете скомпилировать ваши источники в байт-код, а затем распространять только байт-код. Но даже это обратимо. Байт-код может быть декомпилирован в получитаемые источники.

Base64 является тривиальным для любого пользователя, поэтому он не может служить реальной защитой и "скрывает" источники только от полностью неграмотных ПК. Более того, если вы планируете на самом деле запускать этот код любым способом, вам нужно будет включить декодер прямо в скрипт (или другой скрипт в вашем дистрибутиве, который должен был бы выполняться законным пользователем), и это сразу же выдаст ваш кодирование / шифрование.

Методы запутывания обычно включают удаление комментариев / документов, искажение имен, вставку мусорного кода и т. Д., Так что даже если вы декомпилируете байт-код, вы получите не очень читаемые источники. Но они, тем не менее, будут источниками Python, и Python не умеет превращаться в нечитаемый беспорядок.

Если вам абсолютно необходимо защитить некоторые функциональные возможности, я бы предложил использовать скомпилированные языки, такие как C или C++, компилировать и распространять.so/.dll, а затем использовать привязки Python к защищенному коду.

Вы можете встраивать свой код и компилировать / запускать из программы на C/C++. Встраивание Python в другое приложение

embedded.c

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("print('Hello world !')");
  Py_Finalize();
  return 0;
}

В Ubuntu, Debian

$ sudo apt-get install python-dev

В сентос, редхат, федора

$ sudo yum install python-devel

компилировать с

$ gcc -o embedded -fPIC -I/usr/include/python2.7 -lpython2.7 ./embedded.c

бежать с

$ chmod u+x ./embedded
$ time ./embedded
Hello world !

real  0m0.014s
user  0m0.008s
sys 0m0.004s

hello_world.py:

print('Hello World !')

запустить скрипт Python

$ time python hello_world.py
Hello World !

real  0m0.014s
user  0m0.008s
sys 0m0.004s

тем не менее, некоторые строки кода Python могут быть найдены в скомпилированном файле.c

$ grep "Hello" ./embedded
Binary file ./embedded matches

$ grep "Hello World" ./embedded
$

Если вам нужна дополнительная безопасность, вы можете использовать base64 в своем коде

...
PyRun_SimpleString("import base64\n"
                  "base64_code = 'your python code in base64'\n"
                  "code = base64.b64decode(base64_code)\n"
                  "exec(code)");
...

например:

создайте строку base 64 вашего кода

$ base64 hello_world.py
cHJpbnQoJ0hlbGxvIFdvcmxkICEnKQoK

embedded_base64.c

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("import base64\n"
                    "base64_code = 'cHJpbnQoJ0hlbGxvIFdvcmxkICEnKQoK'\n"
                    "code = base64.b64decode(base64_code)\n"
                    "exec(code)\n");
  Py_Finalize();
  return 0;
}

все команды

$ gcc -o embedded_base64 -fPIC -I/usr/include/python2.7 -lpython2.7 ./embedded_base64.c
$ chmod u+x ./embedded_base64

$ time ./embedded_base64
Hello World !

real  0m0.014s
user  0m0.008s
sys 0m0.004s

$ grep "Hello" ./embedded_base64
$

Вы можете использовать base64 модуль для кодирования строк, чтобы остановить серфинг через плечо, но он не остановит тех, кто находит ваш код, если у него есть доступ к вашим файлам.

Затем вы можете использовать compile() функция и eval() функция для выполнения вашего кода, как только вы его расшифровали.

>>> import base64
>>> mycode = "print 'Hello World!'"
>>> secret = base64.b64encode(mycode)
>>> secret
'cHJpbnQgJ2hlbGxvIFdvcmxkICEn'
>>> mydecode = base64.b64decode(secret)
>>> eval(compile(mydecode,'<string>','exec'))
Hello World!

Так что если у вас есть 30 строк кода, вы, вероятно, захотите зашифровать его, выполнив что-то вроде этого:

>>> f = open('myscript.py')
>>> encoded = base64.b64encode(f.read())

Затем вам нужно написать второй скрипт, который выполняет compile() а также eval() который, вероятно, будет включать закодированный скрипт в виде строкового литерала, заключенного в тройные кавычки. Так это будет выглядеть примерно так:

import base64
myscript = """IyBUaGlzIGlzIGEgc2FtcGxlIFB5d
              GhvbiBzY3JpcHQKcHJpbnQgIkhlbG
              xvIiwKcHJpbnQgIldvcmxkISIK"""
eval(compile(base64.b64decode(myscript),'<string>','exec'))

Cython

Похоже, что goto ответит за это Cython. Я действительно удивлен, что никто еще не упомянул это? Вот домашняя страница: https://cython.org/

В двух словах, это превращает ваш питон в C и компилирует его, таким образом делая его так же хорошо защищенным, как любая "обычная" скомпилированная распространяемая C-программа.

Хотя есть ограничения. Я сам не изучил их подробно, потому что, начав читать о них, я отбросил эту идею для своих собственных целей. Но это все еще может работать для вас. По сути, вы не можете использовать Python в полной мере, с динамической удивительностью, которую он предлагает. Одна из главных проблем, которая возникла у меня, заключалась в том, что параметры ключевых слов нельзя использовать:(Вы должны писать вызовы функций, используя только позиционные параметры. Я не подтвердил это, но сомневаюсь, что вы можете использовать условный импорт или evals. не уверен, как полиморфизм обрабатывается...

В любом случае, если вы не пытаетесь запутать огромную базу кода после факта, или в идеале, если у вас есть намерение использовать Cython для начала, это очень заметный вариант.

Ознакомьтесь с этими инструментами для обфускации и минификации кода Python:

  • pyarmor, https://pypi.org/project/pyarmor/ - полная обфускация с шестнадцатеричным кодированием; по-видимому, не допускает частичного обфускации только имен переменных / функций
  • python-minifier, https://pypi.org/project/python-minifier/ - минимизирует код и скрывает имена функций / переменных (хотя и не так сильно, как pyminifier ниже)
  • pyminifier, https://pypi.org/project/pyminifier/ - хорошо справляется с запутыванием имен функций, переменных, литералов; может также выполнять шестнадцатеричное кодирование (сжатие) аналогично пиармору. Проблема: после обфускации код может содержать синтаксические ошибки и не запускаться.

Пример вывода.py из pyminifier при запуске с --obfuscate и --gzip:

$ pyminifier --obfuscate --gzip /tmp/tumult.py

#!/usr/bin/env python3
import zlib, base64
exec(zlib.decompress(base64.b64decode('eJx1kcFOwzAMhu95ClMO66apu0/KAQEbE5eJC+IUpa27haVJ5Ljb+vakLYJx4JAoiT/7/+3c3626SKvSuBW6M4Sej96Jq9y1wRM/E3kSexnIOBZObrSNKI7Sl59YsWDq1wLMiEKNrenoYCqB1woDwzXF9nn2rskZd1jDh+9mhOD8DVvAQ8WdtrZfwg74aNwp7ZpnMXHUaltk878ybR/ZNKbSjP8JPWk6wdn72ntodQ8lQucIrdGlxaHgq3QgKqtjhCY/zlN6jQ0oZZxhpfKItlkuNB3icrE4XYbDwEBICRP6NjG1rri3YyzK356CtsGwZuNd/o0kYitvrBd18qgmj3kcwoTckYPtJPAyCVzSKPCMNErs85+rMINdp1tUSspMqVYbp1Q2DWKTJpcGURRDr9DIJs8wJFlKq+qzZRaQ4lAnVRuJgjFynj36Ol7SX/iQXr8ANfezCw==')))
# Created by pyminifier.py (https://github.com/liftoff/pyminifier)

Этот вывод соответствует исходному сценарию ввода из 40 строк, как показано здесь.

Нуйтка

Я бы очень рекомендовал Nuitka, а не Cython. Nuitka также компилирует Python в собственный код платформы, обеспечивая такой же уровень обфускации, как и скомпилированный код C.

      python -m pip install nuitka
python -m nuitka --follow-imports --include-package urllib3.util.ssl_ myprogram.py
./myprogram.bin
  • --follow-imports отлично справляется с включением всех импортированных модулей.
  • --include-package если некоторые операции импорта скрыты и отсутствуют при запуске скомпилированной программы, может быть полезно передать дополнительные пакеты.

Я также использовал здесь ссылку, но pytransform.so или же pytransform.dll общий объект, который является ядром pyarmor является закрытым исходным кодом, который был блокировщиком в моем проекте.

Может быть, вы можете примерить пиконкрет

шифровать .pyc в .pye и расшифровывать при импорте

шифровать и дешифровать библиотекой OpenAES

использование

Полное шифрование

  • преобразовать все ваши .py в *.pye

    $ pyconcrete-admin.py compile --source={your py script}  --pye
    $ pyconcrete-admin.py compile --source={your py module dir} --pye
    
  • Удалить *.py*.pyc или скопировать *.pye в другую папку

  • main.py, зашифрованный как main.pye, не может быть выполнен обычным python, Вы должны использовать pyconcrete обработать основной скрипт.pye. pyconcrete(exe) будет установлен в вашем системном пути (например: /usr/local/bin)

    pyconcrete main.pye
    src/*.pye  # your libs
    

Частично зашифрован (pyconcrete как lib)

  • скачать исходный код pyconcrete и установить с помощью setup.py

    $ python setup.py install \
      --install-lib={your project path} \
      --install-scripts={where you want to execute pyconcrete-admin.py and pyconcrete(exe)}
    
  • импортировать pyconcrete в ваш основной скрипт

  • план проекта рекомендации

    main.py       # import pyconcrete and your lib
    pyconcrete/*  # put pyconcrete lib in project root, keep it as original files
    src/*.pye     # your libs
    

Хорошо, если вы хотите сделать полуобфускированный код, вы делаете код следующим образом:

import zlib, base64
def run(code):
    exec(zlib.decompress(base64.b16decode(code)))
def enc(code):
    return base64.b16encode(zlib.compress(code))

и создайте такой файл (используя приведенный выше код):

f = open('something.py','w')
f.write("code=" + enc("""
print("test program")
print(raw_input("> "))"""))
f.close()

файл "thing.py":

code = '789CE352008282A2CCBC120DA592D4E212203B3FBD28315749930B215394581E9F9957500A5463A7A0A4A90900ADFB0FF9'

просто импортируйте "thing.py "и запустите run(something.code) запустить код в файле.

Одна хитрость заключается в том, чтобы сделать код трудным для чтения при разработке: никогда не документируйте ничего, если нужно, просто дайте вывод функции, а не то, как она работает. Сделайте имена переменных очень широкими, например ссылки на фильмы или противоположности: btmnsfavclr = 16777215 в то время как "btmnsfavclr"означает" любимый цвет Бэтмена "и значение 16777215 или десятичная формаffffff"или белый. Не забывайте смешивать разные стили именования, чтобы сохранить этих противных людей в вашем коде. Также воспользуйтесь советами на этом сайте: Лучшие 11 советов по разработке не поддерживаемого кода.

Есть несколько способов запутать код. Вот только один пример:

(lambda _, __, ___, ____, _____, ______, _______, ________:
    getattr(
        __import__(True.__class__.__name__[_] + [].__class__.__name__[__]),
        ().__class__.__eq__.__class__.__name__[:__] +
        ().__iter__().__class__.__name__[_____:________]
    )(
        _, (lambda _, __, ___: _(_, __, ___))(
            lambda _, __, ___:
                chr(___ % __) + _(_, __, ___ // __) if ___ else
                (lambda: _).func_code.co_lnotab,
            _ << ________,
            (((_____ << ____) + _) << ((___ << _____) - ___)) + (((((___ << __)
            - _) << ___) + _) << ((_____ << ____) + (_ << _))) + (((_______ <<
            __) - _) << (((((_ << ___) + _)) << ___) + (_ << _))) + (((_______
            << ___) + _) << ((_ << ______) + _)) + (((_______ << ____) - _) <<
            ((_______ << ___))) + (((_ << ____) - _) << ((((___ << __) + _) <<
            __) - _)) - (_______ << ((((___ << __) - _) << __) + _)) + (_______
            << (((((_ << ___) + _)) << __))) - ((((((_ << ___) + _)) << __) +
            _) << ((((___ << __) + _) << _))) + (((_______ << __) - _) <<
            (((((_ << ___) + _)) << _))) + (((___ << ___) + _) << ((_____ <<
            _))) + (_____ << ______) + (_ << ___)
        )
    )
)(
    *(lambda _, __, ___: _(_, __, ___))(
        (lambda _, __, ___:
            [__(___[(lambda: _).func_code.co_nlocals])] +
            _(_, __, ___[(lambda _: _).func_code.co_nlocals:]) if ___ else []
        ),
        lambda _: _.func_code.co_argcount,
        (
            lambda _: _,
            lambda _, __: _,
            lambda _, __, ___: _,
            lambda _, __, ___, ____: _,
            lambda _, __, ___, ____, _____: _,
            lambda _, __, ___, ____, _____, ______: _,
            lambda _, __, ___, ____, _____, ______, _______: _,
            lambda _, __, ___, ____, _____, ______, _______, ________: _
        )
    )
)

Я знаю, что это старый вопрос. Просто хочу добавить свое смешное запутанное "Hello world!" в Python 3 и несколько советов;)

      #//'written in c++'

#include <iostream.h>
#define true false
import os
n = int(input())
_STACK_CALS=  [ ];
_i_CountCals__= (0x00)
while os.urandom(0x00 >> 0x01) or (1 & True):
  _i_CountCals__+= 0o0;break;# call shell command echo "hello world" > text.txt
""#print'hello'
__cal__= getattr( __builtins__  ,'c_DATATYPE_hFILE_radnom'[ 0x00 ]+'.h'[-1]+'getRndint'[3].lower() )
_o0wiXSysRdrct   =eval (  __cal__(0x63) + __cal__(104) + 'r_RUN_CALLER'[0] );
_i1CLS_NATIVE=  getattr (__builtins__ ,__cal__(101)+__cal__(118  )+_o0wiXSysRdrct ( 0b1100001 )+'LINE 2'[0].lower( ))#line 2 kernel call
__executeMAIN_0x07453320abef  =_i1CLS_NATIVE ( 'map');
def _Main():
    raise 0x06;return 0 # exit program with exit code 0
def _0o7af():_i1CLS_NATIVE('_int'.replace('_', 'programMain'[:2]))(''.join(  __executeMAIN_0x07453320abef( _o0wiXSysRdrct ,_STACK_CALS)));return;_Main()
for _INCREAMENT in [0]*1024:
    _STACK_CALS= [0x000 >> 0x001 ,True&False&True&False ,'c++', 'h', 'e', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd']
   
#if
for _INCREAMENT in [0]*1024:
    _STACK_CALS= [40, 111, 41, 46, 46] * n
    
""""""#print'word'
while True:
    break;
_0o7af();
while os.urandom(0x00 >> 0xfa) or (1 & True): # print "Hello, world!"
  _i_CountCals__-= 0o0;break;
  while os.urandom(0x00 >> 0x01) or (1 & True):
      _i_CountCals__ += 0o0;
      break;

Это можно сделать вручную, мои советы:

  • использовать eval и / или exec с зашифрованными строками

  • использовать [ord(i) for i in s] / ''.join(map(chr, [list of chars goes here])) как простое шифрование / дешифрование

  • используйте непонятные имена переменных

  • сделать его нечитаемым

  • Не пишите только 1 или True, пишите 1&True&0x00000001 ;)

  • использовать разные системы счисления

  • добавьте запутанные комментарии, такие как «строка 2» в строке 10 или «он возвращает 0» в цикле while.

  • использовать __builtins__

  • использовать getattr а также setattr

Я бы замаскировал код так:

def MakeSC():
    c = raw_input(" Encode: ")
    sc = "\\x" + "\\x".join("{0:x}".format(ord(c)) for c in c)
    print "\n shellcode =('" + sc + "'); exec(shellcode)"; MakeSC();

Аут:

import os; os.system("whoami")

закодированные:

Payload = ('\x69\x6d\x70\x6f\x72\x74\x20\x6f\x73\x3b\x20\x6f\x73\x2e\x73\x79\x73\x74\x65\x6d\x28\x22\x77\x68\x6f\x61\x6d\x69\x22\x29'); exec(Payload);

Лучший способ сделать это - сначала создать файл ac, а затем
Скомпилируйте его с помощью tcc a. Пид файл
Требования
1.tcc(можно скачать здесь)
2.pyobfuscate (можно скачать отсюда) 3.Cython Для установки напишите

pip install cython

Чтобы запутать ваш.py файл, используйте pyobfuscate.
Выполняя это в cmd

pyobfuscate.py myfile.py > obfuscated.py

Теперь перейдите к следующему шагу
Чтобы создать файл.c, выполните следующие действия.
1. Добавьте функцию init в ваш файл.py.

2. Выполните команду ниже на cmd, заменив параметры

cython --embed <file.py>

3. Теперь скачайте tcc.
4. Копирование Python включает в себя TCC включает.
Выполните команду, показанную ниже

tcc <myfile>.c -o <pyd file name>.pyd -shared -I<python include> -L<python lib>

5. Таким образом, у вас есть файл.pyd, который вы можете импортировать в свое приложение.
6.Пид файла очень трудно перестроить.
7.Вы можете создать pyd-файл со всеми вашими важными функциями, а затем импортировать его в свое приложение.
8. Просто импортируйте файл pyd и создайте.exe вашего приложения.
9.Вы закончили

Реальность такова, что Python - это не тот язык, который нужно использовать, если вы хотите запутать код. Эта публикация имеет отличные обсуждения по этому вопросу.

Может быть, вам стоит подумать о том, чтобы использовать что-то простое, например, том truecrypt для хранения исходного кода, так как это кажется вашей заботой. Вы можете создать зашифрованный файл на USB-ключе или просто зашифровать весь том (при условии, что код подойдет), чтобы вы могли просто взять ключ с собой в конце дня.

Для компиляции вы можете использовать что-то вроде PyInstaller или py2exe для создания отдельного исполняемого файла. Если вы действительно хотите пройти лишнюю милю, посмотрите упаковщик или утилиту сжатия, чтобы добавить больше запутывания. Если ни одна из этих опций не является опцией, вы можете по крайней мере скомпилировать скрипт в байт-код, чтобы он не сразу читался. Имейте в виду, что эти методы просто замедляют попытки отладки или декомпиляции вашей программы.

Недавно я наткнулся на этот пост: Обфускация исходного кода Python с использованием AST, где автор рассказывает об обфускации исходного файла Python с использованием встроенного модуля AST. Скомпилированный двоичный файл должен был использоваться для HitB CTF и, как таковой, имел строгие требования запутывания.

Поскольку вы получаете доступ к отдельным узлам AST, использование этого подхода позволяет выполнять произвольные модификации исходного файла. В зависимости от того, какие преобразования вы выполняете, результирующий двоичный файл может / не может вести себя точно так же, как и не скрытый источник.

Попробуйте этот питон-обфускатор:

pyob.oxyry.com http://pyob.oxyry.com/

__all__ = ['foo']

a = 'a'
_b = 'b'

def foo():
    print(a)

def bar():
    print(_b)

def _baz():
    print(a + _b)

foo()
bar()
_baz()

будет переведен на

__all__ =['foo']#line:1
OO00OO0OO0O00O0OO ='a'#line:3
_O00OO0000OO0O0O0O ='b'#line:4
def foo ():#line:6
    print (OO00OO0OO0O00O0OO )#line:7
def O0000000OOOO00OO0 ():#line:9
    print (_O00OO0000OO0O0O0O )#line:10
def _OOO00000O000O0OOO ():#line:12
    print (OO00OO0OO0O00O0OO +_O00OO0000OO0O0O0O )#line:13
foo ()#line:15
O0000000OOOO00OO0 ()#line:16
_OOO00000O000O0OOO ()#line:17

OpY

https://github.com/QQuick/Opy

Opy запутает ваш обширный, реальный, многомодульный исходный код Python бесплатно! И ВЫ выбираете для каждого проекта, что скрывать, а что нет, редактируя файл конфигурации:

You can recursively exclude all identifiers of certain modules from obfuscation.
You can exclude human readable configuration files containing Python code.
You can use getattr, setattr, exec and eval by excluding the identifiers they use.
You can even obfuscate module file names and string literals.
You can run your obfuscated code from any platform.

В отличие от некоторых других опубликованных опций, это работает как для Python 2, так и для 3! Это также бесплатно / с открытым исходным кодом, и это не только онлайн-инструмент (если вы не платите), как некоторые другие там.

По общему признанию, я все еще оцениваю это сам, но все начальные тесты этого работали отлично. Похоже, это именно то, что я искал!

Официальная версия запускается как отдельная утилита, с первоначальным заданием, согласно которому вы помещаете скрипт в корень каталога, который вы хотите запутать, вместе с файлом конфигурации, чтобы определить детали / опции, которые вы хотите использовать. Я не был влюблен в этот план, поэтому я добавил ответвление из проекта, позволяющее вам импортировать и использовать инструмент из библиотеки. Таким образом, вы можете свернуть это непосредственно в более полный пакетный скрипт. (Конечно, вы можете обернуть несколько сценариев py в bash/batch, но я думаю, что чисто Python-решение идеально). Я попросил, чтобы мой форк был объединен с оригинальной работой, но в случае, если этого не произойдет, вот URL моей пересмотренной версии:

https://github.com/BuvinJT/Opy

Там теперь пакет pyminifier, который может быть полезным. Он запутывает, минимизирует и сжимает код Python.

Есть 2 способа запутать скрипты Python

  • Запутывать байтовый код каждого объекта кода
  • Запутать весь объект кода модуля python

Запутывать скрипты Python

  • Скомпилировать исходный файл python в объект кода

    char * filename = "xxx.py";
    char * source = read_file( filename );
    PyObject *co = Py_CompileString( source, filename, Py_file_input );
    
  • Повторите объект кода, оберните байт-код каждого объекта кода следующим форматом

    0   JUMP_ABSOLUTE            n = 3 + len(bytecode)    
    3
    ...
    ... Here it's obfuscated bytecode
    ...
    
    n   LOAD_GLOBAL              ? (__armor__)
    n+3 CALL_FUNCTION            0
    n+6 POP_TOP
    n+7 JUMP_ABSOLUTE            0
    
  • Сериализация объекта кода и его запутывание

    char *original_code = marshal.dumps( co );
    char *obfuscated_code = obfuscate_algorithm( original_code  );
    
  • Создайте скрипт-обертку "xxx.py", $ {obfuscated_code} обозначает строковую константу, сгенерированную на предыдущем шаге.

    __pyarmor__(__name__, b'${obfuscated_code}')
    

Запускать или импортировать запутанные скрипты Python

Когда импортируете или запускаете этот скрипт-обертку, первый оператор должен вызвать CFunction:

int __pyarmor__(char *name, unsigned char *obfuscated_code) 
{
  char *original_code = resotre_obfuscated_code( obfuscated_code );
  PyObject *co = marshal.loads( original_code );
  PyObject *mod = PyImport_ExecCodeModule( name, co );
}

Эта функция принимает 2 параметра: имя модуля и запутанный код, затем

  • Восстановить запутанный код
  • Создать объект кода по оригинальному коду
  • Импортировать оригинальный модуль (это приведет к дублированию кадра в Traceback)

Запустить или импортировать запутанный байт-код

После импорта модуля, когда любой объект кода в этом модуле вызывается впервые, из упакованного байт-кода, описанного в предыдущем разделе, мы знаем

  • Первая операция - JUMP_ABSOLUTE, она перейдет к смещению n

  • При смещении n инструкция должна вызвать функцию PyCFunction. Эта функция восстановит обфусцированный байт-код между смещением 3 и n и поместит исходный байт-код со смещением 0

  • После вызова функции последняя инструкция должна перейти к смещению 0. Теперь выполняется настоящий байт-код.

Обратитесь к Pyarmor

Как утверждают другие ответы, на самом деле просто нет ничего хорошего. Base64 может быть декодирован. Байт-код может быть декомпилирован. Изначально Python интерпретировался просто, и большинство интерпретируемых языков пытаются ускорить машинную интерпретацию больше, чем затрудняют интерпретацию человеком.

Python сделан для того, чтобы его можно было читать и делиться, а не запутывать. Языковые решения о том, как код должен быть отформатирован, должны были способствовать удобочитаемости разных авторов.

Запутывающий код на Python просто не согласуется с языком. Пересмотрите свои причины запутывания кода.

Это (как было опубликовано ранее) почти полностью бесполезно, но если вы действительно хотите, вы можете использовать альтернативное кодирование, например, ROT13.

Вот мой очень новаторский подход к тому, что я делаю в CircuitPython. Это неполный банкомат, но я подумал, что он может пригодиться. По общему признанию, он не делает ничего, чтобы запутать что-то настолько простое, как print("Hello World!"). Я обновлю, когда он будет завершен.

  1. Найдите все имена переменных, просмотрев сигнатуры методов и левые части назначений, а также все псевдонимы импорта.
  2. Поместите в карантин некоторые вещи, которые я не хочу изменять.
  3. Замените оставшиеся имена бессмысленными токенами.
  4. Снимите с карантина то, что я поместил на карантин.

Получается такой код

      degreeIncrement = 90
durationIncrement = 0.25
def GetEditGlyphParams(self, waveform, editIndex):
    segments = waveform.leftSegments
    waveformFunctionCount =  len(self.waveformFunctions)
    totalParameterCount = 0
    segmentIndex = 0
    while segmentIndex < len(segments):
        segment = segments[segmentIndex]
        segmentParameterCount = len(self.sineFunctions)
        if segment.type == "line":
            segmentParameterCount = len(self.lineFunctions)

... в такой код:

      a6 = 90 # degreeIncrement = 90
a7 = 0.25 # durationIncrement = 0.25
def a8(a9, a10, a11): # def GetEditGlyphParams(self, waveform, editIndex):
    a12 = a10.leftSegments # segments = waveform.leftSegments
    a13 =  len(a9.a5) # waveformFunctionCount =  len(self.waveformFunctions)
    a14 = 0 # totalParameterCount = 0
    a15 = 0 # segmentIndex = 0
    while a15 < len(a12): # while segmentIndex < len(segments):
        a16 = a12[a15] # segment = segments[segmentIndex]
        a17 = len(a9.a3) # segmentParameterCount = len(self.sineFunctions)
        if a16.a332 == "line": # if segment.type == "line":
            a17 = len(a9.a4) # segmentParameterCount = len(self.lineFunctions)

При необходимости комментарии можно опустить.

Вот код, который это делает:

      import sys, re
sourceFilePath = sys.argv[1]
targetFilePath = sys.argv[2]
print("uglify", sourceFilePath)

names = []
translations = []

class Analyser:
    def AnalyseLines(self, lines):
        for line in lines:
            self._AnalyseLine(line)
    def _AnalyseLine(self, line):
        parts = self._GetParts(line)
        if len(parts) > 1 and parts[0] == "import":
            self._AnalyseImport(parts)
        if len(parts) > 1 and parts[0] == "class":
            self._AnalyseClass(parts)
        if len(parts) > 1 and parts[1] == "=":
            self._AnalyseAssignment(parts)
        if len(parts) > 1 and parts[0] == "def":
            self._AnalyseDef(parts)
    def _GetParts(self, line):
        minusTabs = line.replace("\t", " ")
        minusDoubleSpace = minusTabs.replace("  ", " ")
        parts = minusDoubleSpace.split(" ")
        while "#" in parts:
            del parts[-1]
        while len(parts) > 0 and parts[0] == "":
            del parts[0]
        return parts
    def _AddName(self, name, elementType):
        if name == "":
            return
        nameToAppend = name # + " " + elementType
        if nameToAppend in names:
            return
        names.append(nameToAppend)
        translation = "a" + str(len(names))
        translations.append((name, translation))
    def _AnalyseImport(self, parts):
        if len(parts) == 4 and parts[0] == "import" and parts[2] == "as":
            self._AddName(parts[3], "import")
    def _AnalyseClass(self, parts):
        p1 = parts[1].split(":")
        p2 = p1[0].split("(")
        self._AddName(p2[0], "class")
    def _AnalyseAssignment(self, parts):
        mutableName = parts[0].split(".")[0]
        self._AddName(mutableName, "assignment")
    def _AnalyseDef(self, parts):
        methodNameParts = parts[1].split("(")
        if methodNameParts[0] == "__init__":
            return
        self._AddName(methodNameParts[0], "method")
        if len(methodNameParts) > 1:
            self._AddName(methodNameParts[1].replace(",", "").replace("):", ""), "param1")
        for part in parts[2:]:
            params = part.split(",")
            for param in params:
                if param != "":
                    self._AddName(param.replace(":", "").replace(")", ""), "paramN")

class Translator:
    def TranslateLines(self, content):
        oldLines = content.split("\n")
        content = content.replace('"', "_QUOTE_").replace("\\", "_BACKSLASH_")
        for (oldWord, newWord) in translations:
            content = re.sub(r"\b%s\b" % oldWord, newWord, content)
        content = content.replace("_QUOTE_", '"').replace("_BACKSLASH_", "\\")
        newLines = content.split("\n")
        for i in range(len(newLines) - 1):
            if newLines[i] != "":
                newLines[i] += " # " + oldLines[i].strip()
        return "\n".join(newLines)

analyser = Analyser()
sourceFile = open(sourceFilePath, 'r')
targetFile = open(targetFilePath, 'w')
content = sourceFile.read()
lines = content.split("\n")
print(len(lines), "lines, starting with", lines[0])
analyser.AnalyseLines(lines)
# print(names)
# print(translations)
translator = Translator()
newContent = translator.TranslateLines(content)
newLines = newContent.split("\n")
print("writing", len(newLines), " lines to", targetFilePath, "starting with", newLines[0])
targetFile.write(newContent)
sourceFile.close()
targetFile.close()

Просто используйте библиотеку pyarmor прямо сейчас, большинство решений уже давно устарело, Pyarmor - новый, простой и эффективный инструмент для крупномасштабных ваз с кодом

чтобы узнать, как его использовать, перейдите по ссылке ниже (всего минутное видео, это не может быть проще)

https://www.youtube.com/watch?v=94VxtGI-KqQ

Попробуйте вставить свой код Python hello world на следующий сайт:

http://enscryption.com/encrypt-and-obfuscate-scripts.html

Он создаст для вас сложный зашифрованный и полностью функциональный скрипт. Посмотрите, сможете ли вы взломать скрипт и раскрыть реальный код. Или посмотрите, удовлетворяет ли уровень сложности, который он обеспечивает, вашей потребности в душевном спокойствии.

Зашифрованный скрипт, созданный для вас через этот сайт, должен работать в любой системе Unix, на которой установлен python.

Если вы хотите зашифровать другим способом, я настоятельно рекомендую вам написать собственный алгоритм шифрования / обфускации (если безопасность так важна для вас). Таким образом, никто не может понять, как это работает, кроме вас. Но для того, чтобы это действительно сработало, вы должны потратить на это огромное количество времени, чтобы убедиться в отсутствии лазеек, которыми может воспользоваться тот, у кого много времени. И убедитесь, что вы используете инструменты, которые уже естественны для системы Unix... то есть openssl или base64. Таким образом, ваш зашифрованный скрипт станет более переносимым.

Я напишу свой ответ в дидактической манере...

Сначала введите в ваш интерпретатор Python:

import this

затем перейдите и посмотрите на файл this.py в вашем каталоге Lib в вашем дистрибутиве Python и попытайтесь понять, что он делает.

После этого взгляните на eval функция в документации:

help(eval)

Теперь вы должны были найти забавный способ защитить свой код. Но будьте осторожны, потому что это работает только для людей, которые менее умны, чем вы! (и я не пытаюсь быть оскорбительным, любой, кто достаточно умен, чтобы понять, что ты сделал, может изменить это).

Другие вопросы по тегам