pyarmor icon indicating copy to clipboard operation
pyarmor copied to clipboard

NameError: name '__armor_enter__' is not defined for __del__ destructors for python 3.6

Open tkornuta-nvidia opened this issue 3 years ago • 9 comments

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?

tkornuta-nvidia avatar Oct 30 '21 01:10 tkornuta-nvidia

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."

tkornuta-nvidia avatar Oct 30 '21 04:10 tkornuta-nvidia

Sorry, there is no plan to support python3.6 for super mode.

jondy avatar Oct 30 '21 13:10 jondy

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?

tkornuta-nvidia avatar Nov 01 '21 21:11 tkornuta-nvidia

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

jondy avatar Nov 02 '21 02:11 jondy

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

jondy avatar Nov 02 '21 03:11 jondy

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.

tkornuta-nvidia avatar Nov 04 '21 18:11 tkornuta-nvidia

If they're in the one script and this script is not very important, copy the original plain script to overwrite this obfuscated script.

jondy avatar Nov 05 '21 04:11 jondy

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...

tkornuta-nvidia avatar Nov 09 '21 02:11 tkornuta-nvidia

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__.

jondy avatar Nov 09 '21 11:11 jondy