我正在寻找如何隐藏我的Python源代码。
print "Hello World!"
如何编码此示例,以使它不易阅读?有人告诉我使用base64,但不知道如何使用。
Answers:
这只是一个有限的第一层混淆解决方案,但是它是内置的: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对任何人来说都是微不足道的解码,因此它不能用作实际的保护,只会“隐藏”来自完整PC使用者的资源。此外,如果您打算以任何方式实际运行该代码,则必须将解码器直接包含在脚本中(或分发中的另一个脚本,该脚本必须由合法用户运行),这将立即放弃您的代码。编码/加密。
混淆技术通常涉及注释/文档的剥离,名称处理,垃圾代码插入等,因此,即使您反编译字节码,您也不会获得非常可读的源代码。但是它们仍然是Python的来源,Python并不擅长成为难以理解的混乱。
如果您绝对需要保护某些功能,建议您使用C或C ++等编译语言,编译并分发.so / .dll,然后使用Python绑定到受保护的代码。
您可以使用该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'))
您可以将代码嵌入C / C ++,然后将 Python嵌入另一个应用程序
嵌入式
#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
在Centos / Redhat / Fedora中
$ 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 !')
运行脚本
$ time python hello_world.py
Hello World !
real 0m0.014s
user 0m0.008s
sys 0m0.004s
但是在编译文件中可能会找到一些python代码字符串
$ 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)");
...
例如:
创建代码的基数为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
$
这个专案(pyarmor)也可能有帮助:
赛顿
看来,答案是Cython。我真的很惊讶,没有人提到这个吗?这是主页:https : //cython.org
简而言之,这会将您的python转换为C并进行编译,从而使其与任何“常规”编译后的可分发C程序一样受到良好的保护。
虽然有限制。我本人并没有深入探讨它们,因为当我开始阅读它们时,我出于自己的目的放弃了这个想法。但是它可能仍然对您有用。本质上,您无法充分利用Python所提供的动态功能。引起我注意的一个主要问题是,关键字参数不可用:(您必须仅使用位置参数编写函数调用。我没有确认这一点,但是我怀疑您可以使用条件导入或eval。不确定如何处理多态...
无论如何,如果您不想在事实发生后混淆庞大的代码库,或者理想情况下,如果首先考虑使用Cython,那么这是一个非常值得注意的选择。
eval,多态性。肯定有一些不兼容(主要是与内省有关),但是您提到的所有内容都应该起作用(并且也应该在2018
也许你可以尝试pyconcrete
加密.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,不能由normal执行python。您必须使用pyconcrete处理主.pye脚本。
pyconcrete(exe)将安装在您的系统路径中(例如:/ usr / local / bin)
pyconcrete main.pye
src/*.pye # your libs
下载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 base64
import zlib
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()
文件“ something.py”:
code = '789CE352008282A2CCBC120DA592D4E212203B3FBD28315749930B215394581E9F9957500A5463A7A0A4A90900ADFB0FF9'
只需导入“ something.py”并运行run(something.code)即可运行文件中的代码。
一个诀窍是使代码难以设计阅读:永远不要记录任何东西,如果必须的话,只给出函数的输出,而不是函数的输出。以非常宽泛的变量名,电影参考或相反的示例为例:btmnsfavclr = 16777215其中,“ btmnsfavclr”表示“蝙蝠侠的最爱颜色”,值是16777215或十进制形式的“ ffffff”或白色。记住要混合使用不同的命名方式,以使代码中的那些讨厌的人感到厌烦。另外,请使用此站点上的技巧:开发不可维护代码的11大技巧。
查看以下用于混淆和最小化python代码的工具:
使用--obfuscate和--gzip运行时,来自pyminifier的示例.py输出:
$ 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行的原始输入脚本如图这里。
我会屏蔽这样的代码:
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);
也许您应该考虑使用诸如truecrypt卷之类的简单内容进行源代码存储,因为这似乎是您的关注点。您可以在USB密钥上创建加密文件,也可以仅加密整个卷(前提是代码适合),因此您可以在一天结束时随身携带密钥。
为了进行编译,您可以使用PyInstaller或py2exe之类的东西来创建独立的可执行文件。如果您真的想加倍努力,请查看打包程序或压缩实用程序,以增加更多的混淆。如果这些都不是选项,则您至少可以将脚本编译为字节码,以使其无法立即读取。请记住,这些方法只会使尝试调试或反编译程序的人员放慢速度。
py
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都适用!它也是免费的/开源的,它不是像其中一些其他工具那样仅用于在线的工具(除非您付费)。
我承认我自己仍在对此进行评估,但是对其进行的所有初始测试都可以正常工作。看来这正是我想要的!
正式版本可作为独立实用程序运行,其最初的预期设计是将脚本放入要混淆的目录的根目录,以及用于定义要使用的详细信息/选项的配置文件。我不喜欢那个计划,所以我从项目中添加了一个fork,让您可以从库中导入和使用该工具。这样,您可以将其直接滚动到更具包容性的打包脚本中。(您当然可以在bash / batch中包装多个py脚本,但是我认为纯Python解决方案是理想的)。我要求将fork合并到原始作品中,但是如果万一从未发生,这是我修订版的网址:
最好的方法是首先生成一个.c文件,然后使用tcc将其编译为.pyd文件。
注意:仅Windows要求
安装:
sudo pip install -U cython
要混淆您的.py文件,请执行以下操作:
pyobfuscate.py myfile.py >obfuscated.py
要生成一个.c文件,
可选init<filename>()向您的.py文件添加功能
cython --embed file.py
cp Python.h tcc\include
tcc file.c -o file.pyd -shared -I\path\to\Python\include -L\path\to\Python\lib
将.pyd文件导入app.exe
试试这个python混淆器:
pyob.oxyry.com pyob.oxyry.c
__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
混淆代码有多种方法。这只是一个例子:
(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 _, __, ___, ____, _____, ______, _______, ________: _
)
)
)
将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}')
导入或运行此包装器脚本时,第一条语句是调用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个参数:模块名称和混淆代码,然后
导入模块后,第一次调用该模块中的任何代码对象时,根据上一节中描述的包装字节码,我们知道
第一个操作JUMP_ABSOLUTE跳到偏移n
在偏移量n处,该指令将调用PyCFunction。此函数将在偏移量3和n之间恢复那些混淆的字节码,并将原始字节码放在偏移量0处
函数调用后,最后一条指令跳回到偏移量0。现在执行实际字节码
请参阅Pyarmor
我知道这是一个老问题。只想添加我有趣的,模糊的“ 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;)
使用不同的号码系统
在第10行添加“第2行”或在while循环中返回“ 0”等令人困惑的注释。
采用 __builtins__
使用getattr和setattr
尝试将您的hello world python代码粘贴到以下站点:
http://enscryption.com/encrypt-and-obfuscate-scripts.html
它将为您生成一个复杂的加密和混淆但功能齐全的脚本。查看您是否可以破解脚本并显示实际代码。或查看它提供的复杂程度是否满足您的安心需求。
通过此站点为您生成的加密脚本应该可以在安装了python的任何Unix系统上使用。
如果您想用另一种方式加密,我强烈建议您编写自己的加密/模糊化算法(如果安全性对您来说很重要)。这样,除了您,没人能知道它是如何工作的。但是,要使此方法真正起作用,您必须花费大量时间在上面,以确保没有很多漏洞可以供那些拥有大量时间的人利用。并确保您使用Unix系统已经很自然的工具...即openssl或base64。这样,您的加密脚本将更易于移植。
python myfile.py但可以对myfile.py进行编码的文件?