pyarmor
pyarmor copied to clipboard
NameError: name '__armor_enter__' is not defined for __del__ destructors for python 3.6
Context Building obfuscated python wheels with several modules and classes.
Platforms
Currently need to support several platforms (aarch64, x86) for different python versions (py3.6, py3.7 and py3.8)
Pyarmor versions tested: 6.7.1, 6.8.1
Description
The un-obfuscated wheels work fine, but when running the same code after installation of an obfuscated wheel errors like the following appear:
Exception ignored in: <function ArtifactRegistry.__del__ at 0x7fb61e32dc10>
Traceback (most recent call last):
File "<frozen src.eff.core.artifact_registry>", line 91, in __del__
NameError: name '__armor_enter__' is not defined
Exception ignored in: <function Artifact.__del__ at 0x7fb61e3981f0>
Traceback (most recent call last):
File "<frozen src.eff.core.artifact>", line 177, in __del__
NameError: name '__armor_enter__' is not defined
Exception ignored in: <function Artifact.__del__ at 0x7fb61e3981f0>
Traceback (most recent call last):
File "<frozen src.eff.core.artifact>", line 177, in __del__
NameError: name '__armor_enter__' is not defined
Exception ignored in: <function Artifact.__del__ at 0x7fb61e3981f0>
Traceback (most recent call last):
File "<frozen src.eff.core.artifact>", line 177, in __del__
NameError: name '__armor_enter__' is not defined
Exception ignored in: <function Artifact.__del__ at 0x7fb61e3981f0>
Traceback (most recent call last):
The core of the problem lies in PyArmor, precisely in bad handling of destructor del methods.
I have found references to this error in PyArmor docs: https://buildmedia.readthedocs.org/media/pdf/pyarmor/stable/pyarmor.pdf It is described in “14.6.12 Object method del raise NameError exception” “If the scripts is obfuscated by non super mode and python is 3.7 and later, please obfuscate the scrits by super mode. Or refine the scripts, do not obfuscate the object method del. For example”
First tried the lambda_ trick, didn’t worked.
So then tried to switch to “Super Mode”: https://pyarmor.readthedocs.io/en/latest/mode.html#super-mode
It didn’t worked OOTB, had to fix dozens of problems along the way, with building the obfuscated wheel with that new mode, finally got it working locally, pushed it to gitlab CI and…
ERROR No available dynamic library for linux.aarch64.11.py36 with features ['11']
Just tracked it down: https://pyarmor.readthedocs.io/en/latest/platforms.html
and "Table-3. The Prebuilt Extensions For Super Mode" clearly indicates that python 3.6 is not supported for both platforms that I need to support!
How can I handle this issue?
Status update: managed to resolve this issue by modifying my code - "lambdafiction" of destructors and all methods and properties that the destructors were calling.
I consider this as just a WORKAROUND.
Please change this issue to "Request for Super Mode support for (aarch64, x86) for python 3.6."
Sorry, there is no plan to support python3.6 for super mode.
Hi @jondy, we bought 5 PyArmor licenses and only use two for now. So happens that two of our products require support for python 3.6.
From our point this is clearly a bug as we have to de-obfuscate some methods just to avoid the exceptions. And we want to have the whole code obfuscated.
If you don't plan to support python 3.6 for Super Mode, when do you plan to fix this bug for normal mode?
Thank you for purchasing pyarmor.
The solution for python3.6 is lambda as described in the document.
The obfuscated scripts could not be same as the original scripts totally, some features are changed for security or difficult to implement. __del__
for non super mode need complex logic, and super mode for python3.6 too. So the lambda function as the final solution for these cases.
Here list some changed features by pyarmor https://pyarmor.readthedocs.io/en/latest/understand-obfuscated-scripts.html#the-differences-of-obfuscated-scripts
In next minor version v7.1.0
, it may add new feature to ignore functions, so that the end users need not patch their python scripts. For example,
pyarmor obfuscate --exclude-function __del__ foo.py
Hi @jondy thanks, but it seems that this will only partially solve the problem.
Note my destructors are calling other functions => those also had to be de-obfuscated.
If they're in the one script and this script is not very important, copy the original plain script to overwrite this obfuscated script.
I have already came up with this approach to "automatically" de-obfuscate the package_info.py.
However, in the destructor-related fix this will result in showing code of three classes that we actually want to be obfuscated...
Try to obfuscate this script with --obf-code 0
separately, for example
pyarmor obfuscate --obf-code 0 --no-runtime --exact package_info.py
Then copy this obfuscated one to overwrite the default obfuscated script.
Or refactor this script, python3.6 will not handle __del__
.