dashingsoft / pyarmor

A tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts.
http://pyarmor.dashingsoft.com
Other
3.35k stars 283 forks source link

frozen package says there's no module #100

Closed daun-io closed 5 years ago

daun-io commented 5 years ago

I've obfuscated my python package "my_package" with entry point "init.py" file and it has worked really great within pyhton interpeter like this.

pyarmor obfuscate --recursive --output dist/my_package my_package/__init__.py
cd dist
python
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:27:44) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_package
>>>

And then I create an external entry point which does simple thing like this

# entry_point.py
from my_package import Application

if __name__ == "__main__":
    app = Application()
    app.run()

it still worked great, and then I wanted to compile this entry_point.py with pyinstaller.

pyinstaller -n "my_app" entry_point.py

and then the compiled entry_point.exe prints an error like this:

File "my_package\__init__.py", line 3, in <module>
    __pyarmor__(__name__, __file__, b'\xee\x0b\xcd\x35\x39\x74\x44\x44\x3d\xd9\x76\x11\x9a\xc8\x32\x7c\xd2\x33\x7a\x94\xd9\xd5\x7d\x91\x60\x7b\x8d\x4c\x18\xcd\x82\x7a\x5d\xff\x65\x90\x53\x2b\x01\x7a\x4f\x3e\x9c\xfe\x7c\x02\x1e\x23\x39\x76\x05\x55\x1a\x10\x1c\x64\x8f\xf2\x00\xc5\x75\x5f\x43\x90\xdd\x2b\x3d\xb2\xdd\xc2\x55\x25\x51\x03\xf1\x57\x5a\x7f\x5b\xe5\x72\x23\x3c\xa4\x17\x02\xa1\x69\x1b\x50\xf6\x4b\x28\x41\xaa\xba\xfc\x8e\xfd\x7d\x4a\x2a\x75\xfa\x5b\xbf\x2f\x1d\x96\x41\xec\xd2\x2f\x10\x07\xf6\x90\xa7\x0e\x37\x09\x34\x6a\x5f\x85\x96\xac\x65\xf6\xe0\x4b\x29\xcf\xeb\x20\xa3\xfe\x04\x76\xa8\x08\xd6\xa7\xf7\x44\x74\x71\x29\x71\x64\x73\x62\xf5\x51\x47\x19\xd3\x4b\x86\x52\xb5\x44\xb7\x62\xa1\x37\xc3\xd5\x00\x28\xd6\x26\x8c\xe4\x0d\xff\xdc\x0d\x15\x2b\x76\xe7\xe1\xdb\x69\x8c\xc1\x8b\x5b\x16\xdf\xaf\x8b\xc0\xca\xd0\x2d\xe5\xae\x5e\x1e\x05\xef\xc3\x57\xd6\xc5\x4d\x10\x48\x5e\xfd\xdf\x03\x15\x21\x22\x12\x0d\xc3\xae\xdd\x25\xd3\x14\x7e\x1d\x36\x90\xf4\x10\xa6\x4f\x00\x1c\x3b\xa4\x2d\xdb\x4d\xd3\x00\xcb\x92\x42\xf0\x0f\xa5\x1c\xea\x20\x16\x27\x5e\x5d\x66\xdc\x3d\xa1\xde\x62\x43\xb1\x76\xdf\x1d\xd6\xa5\xf9\x7e\x24\x98\xd9\xcb\xf0\x8e\x04\x4e\xd4\x24\x26\x51\x28\x3f\x6c\x80\x75\x98\x3a\x9c\x3e\xef\x02\x73\xd3\x78\x51\xb0\x01\xf2\x53\xaa\x38\x80\x64\xd6\x94\x1f\x95\xf2\x2a\x0d\x07\x60\x6b\x2b\xf3\x96\x98\x02\x12\x31\x30\x70\xfd\x69\x5e\x4c\x58\x79\xde\xdf\xab\xc3\x82\x6a\xb4\x25\xa4\xf1\x05\x65\x3c\x19\x6d\xcf\x6f\xdc\xc5\x8b\x7f\x26\xff\xb7\x20\x5c\x33\xfb\xcc\x79\x03\xb3\xe6\x73\x5f\xc7\x32\xc7\xb2\x93\x4f\x6c\xea\x4d\x3c\x50\xda\xee\xe9\xdf\x95\x97\xa6\xe1\xe4\x06\x92\xc1\x5f\x79\xb7\x5d\xb8\x32\x3e\x2c\x84\x83\xe4\x82\x37\xae\xc8\x48\x1e\x01\x23\x31\x08\xee\xd8\xa4\x40\x5b\x91\xfb\x30\x0d\x68\xaf\x5a\x65\xb2\x19\xd0\x2e\x21\x3d\x2e\x2d\xb9\x41\xb9\x59\x56\x48\xe7\x08\xc7\x6b\x9c\x2a\x18\x9b\xe2\x93\x3a\x7d\x9c\x97\x64\x79\x1b\x51\x0f\x69\xc9\x9d\xec\xde\x92\x0c\x7d\x5e\x36\xd3\xda\xb4\x76\xa7\xad\x74\x3d\xb2\xd2\xcd\x36\x18\xe5\x69\x32\x22\x01\xc5\x8f\x09\xde\x13\x8a\xa7\xc8\x4f\xeb\xa0\xfc\x16\xc1\x9f\x05\xe5\x2f\x43\x44\x10\x7b\x1d\x45\x4f\x79\xb4\xde\x5f\xd0\x2a\x83\x7d\x36\xe4\xb0\x44\x41\xe5\xfb\x4f\x77\xe5\x2d\x1f\x4a\xda\x16\x06\x5a\x03\x6c\xa0\x5e\x9a\xb2\xa3\xc6\x70\x76\x46\x46\x2c\xb0\xc6\x1d\xbe\xa1\x55\xfb\x30\x11\xa0\xdf\xce\x62\xde\x27\x85\xe4\xc4\xa0\x72\xdd\xb7\xa2\x28\x10\xb7\xa4\x3c\x3c\xa4\x0d\x76\x22\xf1\xca\x48\x22\x6e\x05\xbd\x59\x74\xe6\x72\x5a\x87\x3f\x66\x59\x76\xac\xac\x70\x5c\xac\x78\x9b\x3d\x60\x1b\xd3\x82\x08\x19\xda\x31\xea\x8a\x75\xa3\x05\xea\x34\x86\x3d\xb3\xc6\xd4\x59\xff\xde\xcc\x68\xb8\xcb\x33\xcf\x76\x11\x3e\xf5\xdf\xfe\xa4\x14\x22\x99\x1d\xea\x0d\xc2\xd7\x7c\x21\xff\x43\x1b\x07\xdc\xe3\xb0\x42\x38\xae\x5a\xd1\xd9\x06\x85\xc5\x2f\x31\xe3\x0d\x15\xde\x72\x13\x15\x53\x51\x25\x3d\x87\x1d\x7d\x2a\xee\x4b\x3d\x2c\xde\x5c\x5b\x6d\xe2\x81\x9b\x1e\x73\xd0\xc4\x03\x0d\x49\xab\xe3\xd5\x98\x46\x2d\x8a\x69\x60\x7e\x72\x9a\xe3\x19\x4f\xd8\xcb\x74\x3a\x94\x0e\xe8\xd9\x23\xb8\xfb\xe6\x1b\x2a\xd7\x07\x08\xea\x9a\x5b\x37\x99\x37\x7b\xb8\x43\x42\x3d\x7d\xc5\x73\x11\x34\x6a\xa2\x22\x09\x1e\x7a\xb8\x18\x8b\xb0\xc2\x6e\x49\xa8\x00\x55\x5b\x49\x55\xfb\x70\x91\x57\x07\x58\x8d\x57\x12\xfa\x13\xe8\x58\x7a\xc4\x31\x50\x1c\x33\xec\x17\x32\xf8\xa0\x23\xfd\x4b\x51\x8d\xd4\x07\x78\xf3\x7a\x38\x1d\xba\xf8\xfe\x70\x64\x8f\x55\xda\x3a\x6a\xe0\x6e\xd2\x5b\x31\x24\xd1\x52\x0d\xee\xad\xd2\xa9\x13\xe4\xbb\xe9\x4c\xe6\x6c\xcc\x95\x25\x2b\x4a\x15\x36\x35\x9b\xcb\x0c\xb3\x82\x2d\xc2\x30\x80\x37\x09\x49\x04\xe9\x42\x5a\x58\xa3\x91\xfe\x24\x04\x63\xeb\xe6\x4f\x86\x55\x59\xac\xa9\x7b\x85\x73\x8c\xb4\x5f\xf9\xb9\xb2\xf7\x95\x36\xe5\xf8\x35\x57\x1b\xdd\x7d\x94\xca\xf6\x05\xa3\x6b\x32\xac\x69\x64\x73\x91\xe7\xb7\x60\x52\x29\xd9\x95\xf4\x77\x45\x11\x9b\xaf\x76\x7f\x71\x70\xf8\x01\xb9\x65\x66\xe9\x93\x03\xd6\x8d\x46\xcb\x30\x94\x87\x38\x7f\x30\xc5\xb4\xce\x37\xd5\xf7\x85\x26\xf0\x25\x5d\x64\x33\x3a\xd7\x75\xf8\x73\xa2\x6c\x57\x06\xbe\x91\x97\x0f\x52\x4d\x02\x13\x4f\xe1\x81\x00\xbb\x74\x90\x43\x2c\xb5\xd1\x1f\x5b\x68\x4c\xce\xb1\x80\x22\xd6\x16\x56\xee\xcd\x29\x4e\xb6\x94\xed\xc7\x35\xd6\x35\x1b\x6e\x7b\x2a\x23\x9d\x15\xba\x6b\x1f\xaa\x33\x4e\x07\xe5\xa9\xf1\xe9\x10\x7a\xef\x05\xee\xce\x0c\x01\xb1\xa9\xa4\x8d\x68\x94\x3f\xd9\xd7\xfe\x76\xe2\xc8\xf7\x1a\xc0\x78\x45\xbc\x54\xbe\x7a\x9a\xb1\xc0\xf0\x37\xd3\xfd\x6f\x8b\x06\x66\xe8\xe0\xff\x60\x05\xfa\x96\x54\xc4\xf8\x4f\x06\xc7\xe8\xac\xb7\x3d\xc5\xae\x68\xee\xa3\xcb\xe8\xb8\x12\x0a\x79\x3c\xc2\x9f\xe5\x04\x4e\xbd\x93\xc1\x4d\xd6\x54\x52\xb7\x2b\xb5\xcd\xdc\x90\xd4\xdd\x47\x33\xe6\x2c\xe2\x1d\x70\x33\x47\xb0\x0f\x9f\x64\xf3\xbb\xe6\x22\x89\xab\x55\x00\x2b\x1e\x29\x27\x8b\x4e\x2f\xd7\x4e\x7b\x67\xc5\xe5\x58\xe4\x69\xf7\x4b\x68\x85\x7f\x89\xd1\xe6\xd3\x9f\xe1\x53\x7a\xc3\xce\x66\x1e\x30\x0b\x61\x62\x50\xa1\xef\xe6\x07\x24\xac\x25\x02\xf3\xa6\x8c\xfd\x4a\xe1\x34\xf8\xda\xed\x6f\x61\x77\xe6\xd6\xfb\x70\xf7\x3a\xda\x72\x01\x27\x20\xe9\x77\x57\xdf\xf5\x64\x28\x12\xb1\x15\x91\x34\xad\xeb\xcb\xad\x52\x4a\xd5\xc1\xee\x5e\x61\x40\xdf\x53\xe4\xd5\xd4\x9b\x8e\x7e\x68\x0d\x3a\xdc\x95\x9e\xe2\x80\x3d\xd1\xbb\xcc\x9f\x34\x2d\xe1\x54\xfa\x00\xdd\xb4\x2f\x2f\x81\x59\x43\xce\x08\x4c\x08\x41\x1f\xc9\xfc\xda\x6f\x47\x5b\x3e\x13\xf2\x44\xfd\x84\x47\x04\xd5\x0c\x04\x20\x2f\xa0\xe5\xfe\x45\x85\x19\xf8\xaf\x54\x97\xb5\xf2\xdb\x41\xee\x9b\xdb\x6a\xdd\xbe\xa3\x0a\x4a\x8e\x1c\xa6\x3b\xf9\xde\xaa\x7c\xff\x94\xf5\xd0\x00\xda\x36\x12\xc5\x7f\x91\x0d\x26\x7b\x52\xdc\xae\x66\xd5\xfd\xa1\x4a\x8c\x9b\x3c\x6e\xcd\x52\x42\xa1\xe8\x50\x18\x57\xad\x75\x51\x70\x79\x7f\xc0\x11', 1)
  File "<frozen my_package>", line 23, in <module>
ModuleNotFoundError: No module named 'my_package.module_name'
[27940] Failed to execute script my_app

Is there any tips to solve this?

jondy commented 5 years ago

After the package is obfuscated, pyinstaller could not find any other imported module except __init__.py.

Try to use he pyarmor command pack in this case:

# before run command pack, remove the obfuscated package. 
pyarmor pack -e " -n my_app" -s "my_app.spec" entry_point.py

Note that you couldn't pack the obfuscated scripts, once the scripts have been obfuscated, pyinstaller could not find the dependent modules.

Refer to https://pyarmor.readthedocs.io/en/latest/man.html#pack https://pyarmor.readthedocs.io/en/latest/pack-obfuscated-scripts.html

daun-io commented 5 years ago

Thanks for the answer :)

I've tried to pack it with pyarmor command pack and it actually worked, I was able to execute the packed executable. However, when I tried to investigate the internals using decompiler and then it turned out that the only entry_point.py is hidden and my_package, which includes core source codes which I intended to encrypt wasn't really encrypted at all. Is there any way to encrypt dependent packages?

I'm guessing that I can use pyinstaller's "hidden-import" option to help pyinstaller finding other dependent modules with obfuscated packages.

jondy commented 5 years ago

Please upgrade to v5.5.2, this issue has been fixed in this version.

daun-io commented 5 years ago

I've upgraded to v5.5.2 and recompiled my package with this code

# before run command pack, remove the obfuscated package. 
pyarmor pack -e " -n my_app" -s "my_app.spec" entry_point.py

and then my my_app.exe raised ModuleNotFoundError: No module named 'my_package' which means it isn't bundled inside of the pyinstaller executable however I found that dist/obf/dist includes correctly obfuscated scripts of my_package so I copied them to dist/my_app and it worked which means it's importing obfuscated package from outside of the pyinstaller bundle.

I think my issue is kinda solved since I was able to make my_package obfuscated and the entry_point is fully packaged.

But can I pack obfuscated my_package inside the pyinstaller bundle?

jondy commented 5 years ago

The dependent package my_package should be bundled to executable file by command pack automatically.

First try to bundle your application with pyinstaller directily, for example

pyinstaller --clean -y -n my_app entry_point.py
cd dist/myapp
./myapp

If it works, try to pack by parmor,

rm -rf dist/ my_app.spec
pyarmor pack -e " -n my_app" -s "my_app.spec" entry_point.py
cd dist/myapp
./myapp

Note that entry_point.py isn't obfuscated scripts, once it's obfuscated, all the dependent modules and packages couldn't be found

Generally if the python script could be bundle by PyInstaller, it could be packed by pyarmor. Just pass the extra options of PyInstaller by -e

daun-io commented 5 years ago

Thanks for the answer :) I've found that the reason I wasn't able to pack obfuscated package was because I didn't properly uninstall the package which was installed inside of my python environment which prevented referencing locally obfuscated package. I'll close the issue 👍