gpt4 book ai didi

python - 需要 PEP 302 实现细节

转载 作者:行者123 更新时间:2023-12-03 17:38:26 27 4
gpt4 key购买 nike

我正在尝试使用基于 PEP302 的导入 Hook 来捕获模块的导入,这样我就可以拥有一些在运行时加载的加密 .py 文件。我正在关注 https://github.com/citrusbyte/python-obfuscation 上有关 python 混淆的模板.

基本思想很简单:使用插入到 sys.meta_path 中的 Finder() 函数拦截导入命令,该函数捕获导入指令。 Finder 检查该模块是否是我们想要自己处理的模块,如果是,则返回一个自定义 Loader 对象。否则它会忽略导入。自定义加载器在 sys.modules 中创建一个条目,并读取 python 模块源并使用 PEP302 文档中定义的 exec 将其添加到新创建的模块中。

这工作得很好,但我有一种我无法弄清楚的具体情况。假设有 3 个文件,main、foo 和 bar。 main 设置导入钩子(Hook),然后导入 foo 和 bar。 foo 本身导入 bar。所以情况是:

main:
set_import_hook
import foo
import bar
foo:
import bar
bar:
<irrelevant>

我在 Finder 函数中设置了调试语句作为钩子(Hook),以查看它正在传递的内容。

当我有未加密的代码(即我自己不处理并添加到 sys.modules 的代码时,打印输出显示以下行为:
Finder (foo)
Finder (bar) called from inside foo when foo itself is loaded
Finder (bar) called from main after returning from the import foo

当我自己处理和加载 foo 和 bar 文件时,行为如下:
Finder (foo)
Finder (foo.bar) tries to load bar in the context of foo
Finder (bar) called from main after returning from import foo

这会导致 sys.modules 中存在两个版本的 bar。如果您在这两种情况下查看 sys.modules.keys(),在第一种情况下它只显示 foo 和 bar。在第二种情况下,它显示 foo、foo.bar 和 bar。

我不明白这种行为。创建模块的过程如 PEP 302 文档中所述。这就是我使用的:
    module = sys.modules.setdefault(name, imp.new_module(name))
module.__file__ = filename
module.__path__ = [os.path.dirname(os.path.abspath(file.name))]
module.__loader__ = self
sys.modules[name] = module
exec(src, module.__dict__)

谢谢。

最佳答案

经过大量查看各种示例和文档后,我得到了部分答案。

在上面的代码中,我注意到我没有设置 module.__package__ .在导入过程中的某处,导致输入 foo.__package__ = 'foo'在模块定义中设置。这导致 foo 被视为一个包,并且它所做的任何导入都被视为相对于包目录的导入。

当针对我没有进行模块设置的导入运行时,我看到 module.__package__被系统设置为无。但是设置 module.__package__ = None在上面的代码中不起作用。某些东西将其重置为 foo。

有效的解决方案是设置 module.__package__ = '' (空字符串)。所以添加模块的代码的工作部分是:

module = sys.modules.setdefault(name, imp.new_module(name))
module.__file__ = filename
module.__path__ = [os.path.dirname(os.path.abspath(file.name))]
module.__loader__ = self
module.__package__ = ''
sys.modules[name] = module
exec(src, module.__dict__)

这现在可以工作了,模块 foo 和 bar 只被导入一次。加密和非加密模块的行为看起来相似。

我还是不明白 module.__package__在哪里如果未明确设置为 '',则设置.

关于python - 需要 PEP 302 实现细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42681336/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com