混淆Python代码?

问题描述 投票:39回答:18

我正在寻找如何隐藏我的Python源代码。

print "hello World !" 

我如何编码这个例子,以便它不是人类可读的?我被告知使用base64,但我不知道如何。

python
18个回答
57
投票

这只是一个有限的第一级混淆解决方案,但它是内置的: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模块)。


3
投票

正如其他答案所述,实际上并没有任何好处。 Base64可以解码。字节码可以反编译。 Python最初只是被解释,并且大多数解释语言试图加速机器解释而不是使人类解释变得困难。

Python被认为是可读和可共享的,而不是混淆的。关于如何格式化代码的语言决策是为了提高不同作者的可读性。

混淆python代码并不真正与语言相匹配。重新评估混淆代码的原因。


3
投票

用Cython

似乎goto的答案是Cython。我真的很惊讶没人提到这个吗?这是主页:py2exe

简而言之,这会将您的python转换为C并对其进行编译,从而使其受到任何“正常”编译的可分发C程序的保护。

但是有一些限制。我自己并没有深入探讨它们,因为当我开始阅读它们时,我为了自己的目的放弃了这个想法。但它可能仍适用于你的。从本质上讲,你不能充分利用Python,它提供了动态的超棒。跳出来的一个主要问题是,关键字参数不可用:(你必须只使用位置参数编写函数调用。我没有证实这一点,但我怀疑你可以使用条件导入,或者说evals。我是不确定如何处理多态?

无论如何,如果你事后没有试图混淆庞大的代码库,或者理想情况下如果你开始使用Cython,这是一个非常值得注意的选择。


2
投票

试试这个python混淆器:

pyob.oxyry.com packer or compression utility

Python Source Obfuscation using ASTs

将翻译为

https://cython.org/

1
投票

There are 2 ways to obfuscate python scripts

  • 混淆每个代码对象的字节代码
  • 混淆python模块的整个代码对象

Obfuscate Python Scripts

  • 将python源文件编译为代码对象 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
  • 创建包装脚本“xxx.py”,$ {obfuscated_code}代表上一步生成的字符串常量。 char * filename = "xxx.py"; char * source = read_file( filename ); PyObject *co = Py_CompileString( source, filename, Py_file_input );

Run or Import Obfuscated Python Scripts

导入或运行此包装脚本时,第一个语句是调用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个参数:模块名称和模糊代码

  • 恢复混淆的代码
  • 按原始代码创建代码对象
  • 导入原始模块(这将导致Traceback中的重复帧)

Run or Import Obfuscated Bytecode

导入模块后,当第一次调用此模块中的任何代码对象时,我们知道上面描述的包装字节码

  • 第一个操作是JUMP_ABSOLUTE,它将跳转到偏移量n
  • 在偏移量n处,指令是调用PyCFunction。此函数将在偏移3和n之间恢复那些混淆的字节码,并将原始字节码放在偏移0处
  • 在函数调用之后,最后一条指令将跳转到偏移量0.现在执行真正的字节码。

请参阅char *original_code = marshal.dumps( co ); char *obfuscated_code = obfuscate_algorithm( original_code );


1
投票

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:

Pyarmor


0
投票

我会以教学的方式写下我的答案......

首先输入你的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

现在你应该找到一种有趣的方法来保护你的代码。但要注意,因为这只适用于那些不如你聪明的人! (而且我不是要冒犯,任何聪明到理解你所做的事的人都可以扭转它)。


0
投票

有多种方法可以混淆代码。这只是一个例子:

this.py

0
投票

尝试将您的hello world python代码粘贴到以下站点:

eval

它将为您生成一个复杂的加密和混淆,但功能齐全的脚本。看看你是否可以破解脚本并揭示实际代码。或者看看它提供的复杂程度是否满足您的安心需求。

通过此站点为您生成的加密脚本应该适用于安装了python的任何Unix系统。

如果您想以另一种方式加密,我强烈建议您编写自己的加密/混淆算法(如果安全性对您很重要)。这样,除了你,没有人能弄清楚它是如何工作的。但是,为了真正发挥作用,你必须花费大量的时间来确保它没有任何漏洞,那些有很多时间在手上的人可以利用它。并确保使用Unix系统已经很自然的工具...即openssl或base64。这样,您的加密脚本更具可移植性。


0
投票

执行此操作的最佳方法是首先生成一个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文件。 你完成了


34
投票

所以它不是人类可读的?

我的意思是所有的文件都是编码的!!当你打开它时你什么都听不懂..!那就是我想要的

作为最大值,您可以将源代码编译为字节码,然后只分发字节码。但即使这是可逆的。字节码可以被反编译成半可读源。

对于任何人来说,Base64都很容易解码,所以它不能作为实际保护,只能从完全的PC文盲中“隐藏”来源。此外,如果您计划以任何方式实际运行该代码,您必须将解码器包含在脚本中(或您的发行版中的另一个脚本,需要由合法用户运行),这会立即泄露您的编码/加密。

混淆技术通常涉及注释/文档剥离,名称修改,垃圾代码插入等,因此即使您反编译字节码,您也不会获得非常可读的来源。但是它们仍然是Python的源代码,Python并不擅长变得难以理解。

如果您绝对需要保护某些功能,我建议使用编译语言,如C或C ++,编译和分发.so / .dll,然后使用Python绑定到受保护的代码。


23
投票

您可以使用base64 module对字符串进行编码以停止shoulder surfing,但如果他们有权访问您的文件,则不会阻止某人找到您的代码。

然后,您可以使用compile() functioneval() 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'))

12
投票

您可以嵌入代码并从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
$

9
投票

也许你可以试试pyconcrete

加密.pyc.pye并在导入时解密

通过库OpenAES加密和解密

用法

Full encrypted

  • 将你所有的.py转换为*.pye $ pyconcrete-admin.py compile --source={your py script} --pye $ pyconcrete-admin.py compile --source={your py module dir} --pye
  • 删除qazxsw poi qazxsw poi或将qazxsw poi复制到另一个文件夹
  • main.py加密为main.pye,它不能被正常的*.py执行。您必须使用*.pyc来处理main.pye脚本。 *.pye(exe)将安装在您的系统路径中(例如:/ usr / local / bin) python

Partial encrypted (pyconcrete as lib)

  • 下载pyconcrete源并通过setup.py安装 pyconcrete
  • 在主脚本中导入pyconcrete
  • 推荐项目布局 pyconcrete

8
投票

好吧,如果你想制作一个半混淆的代码,你可以像这样编写代码:

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


8
投票

我会像这样掩盖代码:

16777215

Cleartext:

ffffff

Encoded:

Top 11 Tips to Develop Unmaintainable Code

4
投票

也许你应该考虑使用简单的像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以增加更多混淆。如果这些都不是一个选项,您至少可以将脚本编译为字节码,因此不能立即读取。请记住,这些方法只会减慢试图调试或反编译程序的人的速度。


4
投票

我最近偶然发现了这篇博文:PyInstaller,其中作者使用内置AST模块讨论python源文件混淆。已编译的二进制文件将用于HitB CTF,因此具有严格的混淆要求。

由于您可以访问单个AST节点,因此使用此方法可以对源文件执行任意修改。根据您执行的转换,生成的二进制文件可能/可能与非模糊源完全不同。

© www.soinside.com 2019 - 2024. All rights reserved.