Запутывать код 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
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 моей пересмотренной версии:
Там теперь пакет 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!")
. Я обновлю, когда он будет завершен.
- Найдите все имена переменных, просмотрев сигнатуры методов и левые части назначений, а также все псевдонимы импорта.
- Поместите в карантин некоторые вещи, которые я не хочу изменять.
- Замените оставшиеся имена бессмысленными токенами.
- Снимите с карантина то, что я поместил на карантин.
Получается такой код
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 - новый, простой и эффективный инструмент для крупномасштабных ваз с кодом
чтобы узнать, как его использовать, перейдите по ссылке ниже (всего минутное видео, это не может быть проще)
Попробуйте вставить свой код 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)
Теперь вы должны были найти забавный способ защитить свой код. Но будьте осторожны, потому что это работает только для людей, которые менее умны, чем вы! (и я не пытаюсь быть оскорбительным, любой, кто достаточно умен, чтобы понять, что ты сделал, может изменить это).