Svenskithesource / PyArmor-Unpacker

A deobfuscator for PyArmor.
GNU General Public License v3.0
493 stars 73 forks source link

decrypt the imported modules #36

Closed jindaxia closed 1 year ago

jindaxia commented 1 year ago

I have a pyarmor protected exe (python3.7.2),I can make it extracted into pyc with pyinstxtractor.py,and also run the main.pyc success, I can decrypt the main.pyc use method2 the source file looks like

import sss

def protect_pytransform():
    # some pyarmor checks
    pass

protect_pytransform()
if __name__ == '__main__':
    sss.start()

this sss module was also encryted, I cannot run sss.start directly because of the restrict mode protect( not bootstrap restrict protect), how can I do this

Svenskithesource commented 1 year ago

With the current setup, this is a bit hard but there are some workarounds you can try. If they didn't alter the restrict mode when compiling the protected script you can make your own entry script which uses the restrict_bypass.py to initialize the Pyarmor functions. From there you can import sss yourself. You can modify method 2 to use the main code object of the sss module instead of the main code object of the entry script. That search for the code object happens here. It will require some knowledge of Python to do this modification though, but I'll be here to assist.

jindaxia commented 1 year ago

I can get all the encrypted module imported right now (use inspect.getmembers(sys.modules[__name__]) ), and I can dump all the functions in a module. but yes,of cause I cannot get the code object of the module, I have an idea if the module has no self executed code like this

# sss.py
import a
import b
class aa():
     # something

def start():
     # something
# main.py

import sss
sss.start()

we can compile this module with a empty template like , use dir(sss) we can get all the ojbects (classes, functions, modules)

# sss.py
import a 
import b
class aa():  # all class from 
    pass

def start():
     pass

the function compile will return a code object, then we can replace the fake classes and funtions with the real one

Svenskithesource commented 1 year ago

The ideal way to grab the module's code object is by making it pause while it's importing it. In sss.py you import a, if you create a.py in the same directory and put input() it will be paused and you can inject method 2. It might still grab the wrong code object but with some tweaking, that should work.

jindaxia commented 1 year ago

Great! It works