我正在寻找如何隐藏我的Python源代码。
print "hello World !"
我如何编码这个例子,以便它不是人类可读的?我被告知使用base64,但我不知道如何。
这只是一个有限的第一级混淆解决方案,但它是内置的: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被认为是可读和可共享的,而不是混淆的。关于如何格式化代码的语言决策是为了提高不同作者的可读性。
混淆python代码并不真正与语言相匹配。重新评估混淆代码的原因。
用Cython
似乎goto的答案是Cython。我真的很惊讶没人提到这个吗?这是主页:py2exe
简而言之,这会将您的python转换为C并对其进行编译,从而使其受到任何“正常”编译的可分发C程序的保护。
但是有一些限制。我自己并没有深入探讨它们,因为当我开始阅读它们时,我为了自己的目的放弃了这个想法。但它可能仍适用于你的。从本质上讲,你不能充分利用Python,它提供了动态的超棒。跳出来的一个主要问题是,关键字参数不可用:(你必须只使用位置参数编写函数调用。我没有证实这一点,但我怀疑你可以使用条件导入,或者说evals。我是不确定如何处理多态?
无论如何,如果你事后没有试图混淆庞大的代码库,或者理想情况下如果你开始使用Cython,这是一个非常值得注意的选择。
试试这个python混淆器:
pyob.oxyry.com packer or compression utility
Python Source Obfuscation using ASTs
将翻译为
https://cython.org/
__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
char * filename = "xxx.py";
char * source = read_file( filename );
PyObject *co = Py_CompileString( source, filename, Py_file_input );
导入或运行此包装脚本时,第一个语句是调用Function:
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
此函数接受2个参数:模块名称和模糊代码
导入模块后,当第一次调用此模块中的任何代码对象时,我们知道上面描述的包装字节码
请参阅char *original_code = marshal.dumps( co );
char *obfuscated_code = obfuscate_algorithm( original_code );
OPY
__pyarmor__(__name__, b'${obfuscated_code}')
Opy将免费模糊您广泛的,真实世界的多模块Python源代码!并且您通过编辑配置文件为每个项目选择要混淆和不混淆的内容:
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 ); }
与发布的其他一些选项不同,这适用于Python 2和3!它也是免费/开源的,它不是一个在线的工具(除非你支付),就像其他一些工具一样。
我承认自己仍在评估这个问题,但所有初步测试都完美无缺。看来这正是我想要的!
正式版本作为独立实用程序运行,最初的设计是将脚本放入要混淆的目录的根目录,以及配置文件以定义要使用的详细信息/选项。我不喜欢这个计划,所以我从项目中添加了一个fork,允许您从库中导入和使用该工具。这样,您可以将其直接转换为更具包容性的打包脚本。 (你当然可以用bash / batch包装多个py脚本,但我认为纯python解决方案是理想的)。我要求将我的fork合并到原始作品中,但万一从未发生过,这是我修改版本的URL:
我会以教学的方式写下我的答案......
首先输入你的Python解释器:
https://github.com/QQuick/Opy
然后,去查看Python发行版中Lib目录中的文件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.
,并尝试了解它的作用。
之后,请查看文档中的https://github.com/BuvinJT/Opy函数:
import this
现在你应该找到一种有趣的方法来保护你的代码。但要注意,因为这只适用于那些不如你聪明的人! (而且我不是要冒犯,任何聪明到理解你所做的事的人都可以扭转它)。
有多种方法可以混淆代码。这只是一个例子:
this.py
尝试将您的hello world python代码粘贴到以下站点:
eval
它将为您生成一个复杂的加密和混淆,但功能齐全的脚本。看看你是否可以破解脚本并揭示实际代码。或者看看它提供的复杂程度是否满足您的安心需求。
通过此站点为您生成的加密脚本应该适用于安装了python的任何Unix系统。
如果您想以另一种方式加密,我强烈建议您编写自己的加密/混淆算法(如果安全性对您很重要)。这样,除了你,没有人能弄清楚它是如何工作的。但是,为了真正发挥作用,你必须花费大量的时间来确保它没有任何漏洞,那些有很多时间在手上的人可以利用它。并确保使用Unix系统已经很自然的工具...即openssl或base64。这样,您的加密脚本更具可移植性。
执行此操作的最佳方法是首先生成一个c文件然后 用tcc编译它到a。 Pyd文件 注意:它只是一个Windows修复程序 要求 1.tcc(可以从
help(eval)
下载) 2.pyobfuscate(可以从(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 _, __, ___, ____, _____, ______, _______, ________: _ ) ) )
下载) 3.Cython 要安装这个写
http://enscryption.com/encrypt-and-obfuscate-scripts.html
要混淆.py文件,请使用pyobfuscate。 在cmd中执行此操作
here
现在继续下一步 要生成.c文件,请按照步骤操作 1.在.py文件中添加init函数。
2.在cmd上执行以下命令,替换参数
here
3.现在下载tcc。 4.Copy python包含到tcc包含。 执行以下命令
pip install cython
5.如果你有一个.pyd文件,你可以将其导入你的应用程序。 6.pyd文件很难进行逆向工程。 7.您可以制作所有重要功能的pyd文件,然后将其导入您的应用程序。 8.只需导入pyd文件并制作你的应用程序的.exe文件。 你完成了
所以它不是人类可读的?
我的意思是所有的文件都是编码的!!当你打开它时你什么都听不懂..!那就是我想要的
作为最大值,您可以将源代码编译为字节码,然后只分发字节码。但即使这是可逆的。字节码可以被反编译成半可读源。
对于任何人来说,Base64都很容易解码,所以它不能作为实际保护,只能从完全的PC文盲中“隐藏”来源。此外,如果您计划以任何方式实际运行该代码,您必须将解码器包含在脚本中(或您的发行版中的另一个脚本,需要由合法用户运行),这会立即泄露您的编码/加密。
混淆技术通常涉及注释/文档剥离,名称修改,垃圾代码插入等,因此即使您反编译字节码,您也不会获得非常可读的来源。但是它们仍然是Python的源代码,Python并不擅长变得难以理解。
如果您绝对需要保护某些功能,我建议使用编译语言,如C或C ++,编译和分发.so / .dll,然后使用Python绑定到受保护的代码。
您可以使用base64
module对字符串进行编码以停止shoulder surfing,但如果他们有权访问您的文件,则不会阻止某人找到您的代码。
然后,您可以使用compile()
function和eval()
function在解码后执行代码。
>>> 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()
,它可能包含编码脚本作为triple quotes中包含的字符串文字。所以它看起来像这样:
import base64
myscript = """IyBUaGlzIGlzIGEgc2FtcGxlIFB5d
GhvbiBzY3JpcHQKcHJpbnQgIkhlbG
xvIiwKcHJpbnQgIldvcmxkISIK"""
eval(compile(base64.b64decode(myscript),'<string>','exec'))
您可以嵌入代码并从C / C ++程序编译/运行。 Embedding Python in Another Application
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
在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.朋友:
print('Hello World !')
运行python脚本
$ time python hello_world.py
Hello World !
real 0m0.014s
user 0m0.008s
sys 0m0.004s
但是,可以在编译的.c文件中找到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)");
...
e.g:
创建代码的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
$
也许你可以试试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
来处理main.pye脚本。 *.pye
(exe)将安装在您的系统路径中(例如:/ usr / local / bin)
python
pyconcrete
pyconcrete
好吧,如果你想制作一个半混淆的代码,你可以像这样编写代码:
pyconcrete main.pye
src/*.pye # your libs
并制作这样的文件(使用上面的代码):
$ python setup.py install \
--install-lib={your project path} \
--install-scripts={where you want to execute pyconcrete-admin.py and pyconcrete(exe)}
文件“something.py”:
main.py # import pyconcrete and your lib
pyconcrete/* # put pyconcrete lib in project root, keep it as original files
src/*.pye # your libs
只需导入“something.py”并运行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()
,其中“code = '789CE352008282A2CCBC120DA592D4E212203B3FBD28315749930B215394581E9F9957500A5463A7A0A4A90900ADFB0FF9'
”表示“蝙蝠侠最喜欢的颜色”,值为run(something.code)
或“btmnsfavclr = 16777215
”或白色的小数形式。请记住混合不同风格的命名,以保持代码中那些讨厌的人。另外,请使用本网站上的提示:btmnsfavclr
。
也许你应该考虑使用简单的像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();
这样的源代码存储,因为这似乎是你的一个问题。您可以在USB密钥上创建加密文件,或者只加密整个卷(只要代码适合),这样您就可以在一天结束时随身携带密钥。
要编译,您可以使用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 volume以增加更多混淆。如果这些都不是一个选项,您至少可以将脚本编译为字节码,因此不能立即读取。请记住,这些方法只会减慢试图调试或反编译程序的人的速度。
我最近偶然发现了这篇博文:PyInstaller,其中作者使用内置AST模块讨论python源文件混淆。已编译的二进制文件将用于HitB CTF,因此具有严格的混淆要求。
由于您可以访问单个AST节点,因此使用此方法可以对源文件执行任意修改。根据您执行的转换,生成的二进制文件可能/可能与非模糊源完全不同。