用Cython生成的可执行文件真的没有源代码吗?

2024-06-16 11:46:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经阅读了Making an executable in Cython和BuvinJ对How to obfuscate Python code effectively?的回答,并想测试用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!

那么让我们使用Cython:

cython test.pyx --embed

这将产生一个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

它起作用了!它产生一个140KB的test.exe可执行文件,很好

但是在这个答案中How to obfuscate Python code effectively?含蓄地说,这个“编译”将隐藏源代码这似乎不是真的,如果运行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

这表明人类可读形式的源代码仍然存在

问题:有没有一种方法可以使用Cython编译代码,从而使声明“源代码不再公开”是正确的?

注意:我正在寻找一种既不存在源代码也不存在字节码(.pyc)的解决方案(如果嵌入了字节码/.pyc,那么使用uncompyle6恢复源代码就很简单了)


PS:我记得几年前我也做过同样的观察,但我再也找不到了,经过更深入的研究,它是:Is it possible to decompile a .dll/.pyd file to extract Python Source Code?


Tags: to方法intestimportjson源代码code
1条回答
网友
1楼 · 发布于 2024-06-16 11:46:14

该代码位于exe旁边的原始pyx文件中。删除/不将此pyx文件与exe一起分发


查看生成的C代码时,您将看到可执行文件显示错误消息的原因:

对于引发的错误,Cython将发出类似以下代码:

__PYX_ERR(0, 11, __pyx_L3_error) 

其中__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; \
}

变量__pyx_f定义为

static const char *__pyx_f[] = {
  "test.pyx",
  "stringsource",
};

基本上__pyx_f[0]告诉我们在哪里可以找到原始代码。现在,当引发异常时,(嵌入式)Python解释器将查找原始pyx文件并找到相应的代码(可以在^{}中查找,该代码在引发错误时调用)

一旦这个pyx文件不存在,Python解释器/任何其他人将不再知道原始源代码。但是,错误跟踪仍将显示函数名和行号,但不再显示任何代码段

生成的可执行文件(或扩展名,如果创建的话)不包含任何字节码(如pyc文件中的字节码),并且无法使用uncompyle之类的工具进行反编译:当py文件被转换为Python操作码时,将生成字节码,然后在a huge loop in ^{}中对其进行计算。然而,对于内置的/cython模块,不需要字节码,因为生成的代码直接使用Python的C-API,不需要对操作码进行评估-这些模块跳过解释,这是它们being faster的一个原因。因此,可执行文件中不会有字节码

不过有一个重要的注意事项:应该检查链接器是否包含调试信息(因此,可以在其中找到pyx文件内容作为注释的C代码)MSVC with ^{}选项就是这样一个例子


然而,生成的可执行文件可以被反汇编成汇编程序,然后生成的C代码可以被反向工程——因此,虽然cythonizing可以使代码难以理解,但它不是隐藏密钥或安全算法的正确工具

相关问题 更多 >