让我们假设有一个大型商业项目(又名项目),它在底层使用 Python 来管理用于配置新控制界面的插件,这些控制界面可以由项目附加和使用。
存在小型信息泄露,项目的 Python API 的某些部分泄露给了公共信息,人们能够编写 Python 脚本,这些脚本被底层 Python 实现调用,作为项目插件加载机制的一部分。
此外,使用
inspect
模块和原始 __dict__
阅读材料,人们能够找到 Project 底层 Python 实现的主要部分。
有没有办法让Python密码保密?
快速查看 Python 文档揭示了一种以这种方式抑制
inspect
模块导入的方法:
import sys
sys.modules['inspect'] = None
彻底解决问题了吗?
不,这并不能解决问题。有人可以将检查模块重命名为其他名称并导入它。
你想做的事情是不可能的。 python 解释器必须能够获取你的字节码并执行它。总是有人能够反编译字节码。他们始终能够生成 AST 并使用变量和类名称查看代码流程。
请注意,这个过程也可以使用编译的语言代码来完成;不同之处在于你会得到组装。有些工具可以从汇编中推断 C 结构,但我没有足够的经验来评论细节。
您想隐藏哪些具体信息?你能保留算法服务器端并将你的软件变成接触你的网络服务的客户端吗?将代码保存在您控制的机器上是真正控制代码的唯一方法。你不能给某人一个上锁的盒子和盒子的钥匙,并在他们必须打开盒子才能运行它时阻止他们打开盒子。这与 DRM 不起作用的原因相同。
尽管如此,逆向工程仍然有可能变得“困难”,但当客户端拥有可执行文件时,这永远不会是不可能的。
坦率地说,如果一群专注且坚定的黑客(是好的意义上的,而不是贬义的意义上的)可以破解 PlayStation 的代码签名安全模型,那么您的应用程序就没有机会。 一旦您将应用程序交给公司外部的人,就可以对其进行逆向工程。
现在,如果你想努力让它变得更难,你可以编译自己的嵌入式 python 可执行文件,删除不必要的模块,混淆编译的 python 字节码并将其包装在一些恶意软件 rootkit 中,如果出现以下情况,这些恶意软件 rootkit 将拒绝启动你的应用程序:调试器正在运行。
但你应该真正考虑一下你的商业模式。 如果您将那些对您的产品充满热情的人视为威胁,如果您将那些愿意花时间和精力定制您的产品以个性化他们的体验的人视为危险,也许您需要重新考虑您的安全方法。 假设您不从事 DRM 业务,或者拥有类似的模式,涉及从不情愿的消费者那里榨取金钱,请考虑开发一种涉及与用户共享信息并允许他们协作改进您的产品的方法。
不,没有。
Python 特别容易进行逆向工程,但其他语言,甚至是编译语言,也很容易进行逆向工程。
但是,您可以使该过程显着复杂化,例如通过弄乱 Python 内部结构。然而,在跳到“如何”去做之前,我建议您评估“是否”去做。 “窃取”您的代码通常比自己编写代码更难(毕竟,需要完全理解它们才能扩展它们)。然而,一个纯粹的、未混淆的 Python 插件接口对于围绕你的程序创建一个完整的生态系统至关重要,这远远超过了让别人窥视你可能不完美设计的编码内部结构可能带来的负面影响。
答案是否定的。但我会详细阐述对策。 这是我所有项目的 setup.py。我用Python编码。我不懂 CPython。对于我的一些项目,我使用了 MPI4Py。这需要重写 CFLAGS,这是一个不同的问题,在不同的模块中解决。
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from logging import Logger
from setuptools import setup, Extension, find_packages
from structlog import get_logger
from Cython.Build import cythonize
logger:Logger = get_logger()
try:
from iaflags import main as flags
flags()
except ImportError:
logger.exception('Cannot import `iaflags` module')
finally:
logger.info('Completed `iaflags` block')
extensions = [
Extension(
"iamain.*",
sources=["src/iamain/*.pyx"],
language="c++"
)
]
setup(
ext_modules=cythonize(extensions),
packages=["iamain"],
package_dir = {
'iamain' : 'src/iamain',
},
package_data={
'': ['*.so'],
},
exclude_package_data={
'': ['*.cpp', '*.pyx',]
}
)
话虽这么说……显然,您仍然想确保只在无堆栈的 Python 实现上运行。
@typechecked
def introspect()->str:
""" returns the source code for the currently running module """
#logger.debug('introspect')
cf = currentframe()
if cf is None:
raise IntrospectionError()
cm = getmodule(cf)
try:
return getsource(cm)
except OSError as e:
return decompile(cm)