我已阅读在 Cython 中制作可执行文件和 BuvinJ 对如何有效地混淆 Python 代码的回答?并想测试编译后用 Cython 编译的源代码是否真的“不再存在”。确实流行使用 Cython 是一种保护 Python 源代码的方法,例如参见文章Protecting Python Sources With Cython。
让我们以这个简单的例子为例test.pyx:
import json, time # this will allow to see what happens when we import a library
print(json.dumps({'key': 'hello world'}))
time.sleep(3)
print(1/0) # division error!
Run Code Online (Sandbox Code Playgroud)
然后让我们使用 Cython:
cython test.pyx --embed
Run Code Online (Sandbox Code Playgroud)
这会产生一个test.c. 让我们编译它:
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
cl test.c /I C:\Python37\include /link C:\Python37\libs\python37.lib
Run Code Online (Sandbox Code Playgroud)
有用!它生成了一个 140KB 的test.exe可执行文件,不错!
但是在这个答案中如何有效地混淆 Python 代码?据说这个“编译”会隐藏源代码。这似乎不是真的,如果你运行test.exe,你会看到:
Traceback (most recent call last):
File "test.pyx", line 4, in init test
print(1/0) # division error! <-- the source code and even the comments are still there!
ZeroDivisionError: integer division or modulo by zero
Run Code Online (Sandbox Code Playgroud)
这表明人类可读形式的源代码仍然存在。
问题:有没有办法用 Cython 编译代码,这样“源代码不再公开”的说法是正确的?
注意:我正在寻找一种既不存在源代码也不存在字节码 (.pyc) 的解决方案(如果嵌入了字节码/.pyc,则使用uncompyle6恢复源代码很简单)
PS:我记得我几年前做过同样的观察,但我找不到了,经过深入研究后,这里是:是否可以反编译 .dll/.pyd 文件以提取 Python 源代码?
ead*_*ead 15
该代码位于 exe 旁边的原始 pyx 文件中。删除/不要使用您的 exe 分发此 pyx 文件。
当您查看生成的 C 代码时,您将了解为什么您的可执行文件会显示错误消息:
对于引发的错误,Cython 将发出类似于以下内容的代码:
__PYX_ERR(0, 11, __pyx_L3_error)
Run Code Online (Sandbox Code Playgroud)
其中__PYX_ERR是一个宏定义为:
#define __PYX_ERR(f_index, lineno, Ln_error) \
{ \
__pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \
}
Run Code Online (Sandbox Code Playgroud)
变量__pyx_f定义为
static const char *__pyx_f[] = {
"test.pyx",
"stringsource",
};
Run Code Online (Sandbox Code Playgroud)
基本上__pyx_f[0]告诉在哪里可以找到原始代码。现在,当引发异常时,(嵌入式)Python 解释器会查找您的原始 pyx 文件并找到相应的代码(可以在__Pyx_AddTraceback其中查找在引发错误时调用的代码)。
一旦这个 pyx 文件不存在,原始源代码将不再为 Python 解释器/其他任何人所知。但是,错误跟踪仍将显示函数名称和行号,但不再显示任何代码片段。
生成的可执行文件(或扩展名,如果创建了一个)不包含任何字节码(如在 pyc 文件中)并且不能使用以下工具进行反编译uncompyle:当 py 文件被转换为 Python 操作码时,会生成字节码,然后在中的一个巨大循环ceval.c。然而,对于内置/cython 模块,不需要字节码,因为生成的代码直接使用 Python 的 C-API,无需拥有/评估操作码——这些模块跳过解释,这是它们更快的原因。因此,可执行文件中不会有字节码。
一个重要的注意事项:应该检查链接器是否不包含调试信息(因此可以在其中找到 pyx 文件内容作为注释的 C 代码)。带有/Z7选项的MSVC就是一个例子。
但是,生成的可执行文件可以反汇编为汇编程序,然后可以对生成的 C 代码进行逆向工程 - 因此,虽然 cythonizing 可以使其难以理解代码,但它不是隐藏密钥或安全算法的正确工具。
| 归档时间: |
|
| 查看次数: |
3992 次 |
| 最近记录: |