[BUG] `.pyarmor_config` with many entry points don't get obfuscated correctly when `build` command is run
LuisHenri opened this issue · comments
Hello!
First of all, the PyArmor version I'm using is the v7.7.4 and I'm running it with Python v3.8.10.
I have an application which has 2 entry points: main.py
and config/__init__.py
.
So far, I have used the obfuscate
command with many configuration flags in it to obfuscate my code. But since it is error prone, I tried to define the settings inside .pyarmor_config
.
My obfuscate command:
pyarmor obfuscate --platform linux.x86_64 --bootstrap 2 --with-license outer --src="." --plugin pyarmor_plugins/check_software.py --plugin pyarmor_plugins/get_features.py --recursive --output=deployment config/__init__.py main.py
Part of my .pyarmor_config file:
{
...
"src": ".",
"manifest": "include main.py, recursive-include src *.py, recursive-include config *.py",
"entry": "config/__init__.py, main.py",
"output": "deployment",
"restrict_mode": 1,
...
"bootstrap_code": 2,
...
}
Then I would run pyarmor build -B
.
However, when I use pyarmor build
and try to run my obfuscated script, I get:
File "<.../config/init.py>", line 3, in <module>
RuntimeError: Check restrict mode of module failed
After some digging, I found out that it might be a problem on how build
function differs from the obfuscate
function (I thought build
was supposed to be an obfuscate
based on the .pyarmor_config file).
The make_entry
function is used differently on each of them:
obfuscate function:
elif is_entry and bootstrap:
name = os.path.abspath(a)[len(path)+1:]
make_entry(name, path, output, relative=relative, suffix=suffix,
advanced=advanced)
if (not supermode) and project.entry and bootstrap_code:
soutput = os.path.join(output, os.path.basename(project.src)) \
if project.get('is_package') else output
make_entry(project.entry, project.src, soutput,
rpath=project.runtime_path, relative=relative,
suffix=suffix, advanced=advanced)
Basically: In obfuscate
it is inside the FOR loop. In build
it is outside just after it.
I quickly tested it locally by putting this make_entry
function on build
inside the FOR loop and it obfuscated correctly just as if I ran my old pyarmor obfuscate
command.
Question: Wouldn't it be simpler to just call obfuscate
inside build
?
Pyarmor 8 has been rewitten, so if it's not bug, I may not spend time refining Pyarmor 7 code.
But I'm curious why make_entry
doesn't work in build
out of loop.
By this patch check the different output for build
and obfuscate
command
--- a/src/utils.py
+++ b/src/utils.py
@@ -444,7 +444,7 @@ def _make_entry(filename, rpath=None, relative=None, shell=None, suffix='',
paras.append('advanced=1')
f.write(entry_lines[1] % ', '.join(paras))
f.write(''.join(lines[n:]))
-
+ print(filename, entry_code, entry_lines[1] % ', '.join(paras))
Besides, I close this issue becuase the question is prefer to submit in discussion area
Hi @jondy,
I still think this is a bug somehow.
Isn't project.entry
a string like main.py,config/__init__.py
? If so, how does make_entry
handles it? Because I would assume it makes the filename
an entry. And that makes sense if it is inside the FOR loop, because it iterates through each file and checks if is_entry
. Which is not the case if you do it outside the FOR loop.
I did a simple test with
main.py
config/__init__.py # only one line "issue = 1720"
The content main.py
from config import issue
print('hello', issue)
Then I build a project with .pyarmor_config
{
"version": "2.1",
"name": "ttt",
"title": "ttt",
"src": ".",
"is_package": null,
"manifest": "include main.py, recursive-include config *.py",
"entry": "config/__init__.py,main.py",
"output": "dist2",
"runtime_path": null,
"restrict_mode": 1,
"obf_code": 1,
"obf_mod": 2,
"wrap_mode": 1,
"advanced_mode": 0,
"bootstrap_code": 2,
"cross_protection": 1,
"mixins": null,
"plugins": null,
"platform": null,
"package_runtime": 1,
"enable_suffix": 0,
"license_file": null,
"build_time": 1711467498.723676
}
Then build it,
...
INFO Super mode is off
INFO Super plus mode is off
INFO config/__init__.py -> dist2/config/__init__.py
INFO main.py -> dist2/main.py
INFO 2 scripts has been obfuscated
INFO Insert bootstrap code to entry script dist2/config/__init__.py
INFO Insert bootstrap code to entry script dist2/main.py
INFO Build project OK.
And run the obfuscated script
$ cd dist2
$ python main.py
hello 1720
$ cp ../main.py test.py
$ python test.py
hello 1720
There is no any issue.
I found you use many plugins, so maybe it's your own code report the error.
If you prefer to move it to loop in build, just apply one simple patch, and use it only for yourself.