我正在寻找如何隐藏我的Python源代码.
print "Hello World!"
我如何编码这个例子,以便它不是人类可读的?我被告知使用base64,但我不知道如何.
这只是一个有限的第一级混淆解决方案,但它是内置的:Python有一个字节码编译器:
python -OO -m py_compile
生成一个.pyo
包含字节码的文件,以及删除文档字符串的.pyo
文件等.您可以使用.py
扩展名重命名该文件,并python
像程序一样运行但不包含源代码.
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,'','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),'','exec'))
您可以嵌入代码并从C/C++程序编译/运行. 在另一个应用程序中嵌入Python
embedded.c
#includeint 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 !')
运行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)"); ...
例如:
创建代码的base 64字符串
$ base64 hello_world.py cHJpbnQoJ0hlbGxvIFdvcmxkICEnKQoK
embedded_base64.c
#includeint 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 $
好吧,如果你想制作一个半混淆的代码,你可以像这样编写代码:
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
"或"的十进制形式.请记住混合不同风格的命名,以保持代码中那些讨厌的人.此外,使用本网站上的提示:开发不可维护代码的十大提示.
也许你可以试试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加密为主 .pye,无法正常执行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
我会像这样掩盖代码:
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之类的东西来创建独立的可执行文件。如果您真的想加倍努力,请查看打包程序或压缩实用程序,以增加更多的混淆。如果这些都不是选项,那么您至少可以将脚本编译为字节码,以使其无法立即读取。请记住,这些方法只会减慢尝试调试或反编译程序的人员的速度。
我最近偶然发现了此博文:使用AST进行Python源混淆,作者在其中讨论了使用内置AST模块进行python源文件混淆。编译后的二进制文件将用于HitB CTF,因此具有严格的混淆要求。
由于您可以访问单个AST节点,因此使用此方法可以对源文件执行任意修改。根据您执行的转换,所生成的二进制文件可能/可能不会与未混淆的源代码完全不同。