2

Suppose I have 2 modules - one has been obfuscated by PyArmor. The other imports the obfuscated module and uses it:

# obfuscated.py
def run_task(conn):
    conn.send_msg("Here you go")
    print(conn.some_val + 55)
    return 0
# Non obfuscated (user) code
import importlib.util


class conn:
    some_val = 5
    
    def send_msg(msg):
        print(msg)

def main():
    # import obfuscated # This works...but I need to dynamically load it:

    # This does not:
    spec = importlib.util.spec_from_file_location("module.name", r'c:\Users\me\obfuscated.py')
    obfuscated = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(swdl)
    ret = obfuscated.run_task(conn)
    print("from main: ", ret)

if __name__ == "__main__":
    main()

If I import the obfuscated file using import it is fine. But I need to use importlib to dynamically import the obfuscated file. The importlib does not work - I get:

AttributeError: module 'module.name' has no attribute 'obfuscated'

The idea is that the user can write a script using the API available within obfuscated.py but need to load the module from wherever it resides on their system.

Is there anyway to achieve this?

SimpleOne
  • 1,066
  • 3
  • 12
  • 29

2 Answers2

2

I think I have a method based on what I read here: https://pyarmor.readthedocs.io/en/latest/mode.html#restrict-mode

I use a proxy between the user code and the obfuscated code.

  • User code may or may not be obfuscated
  • The obfuscated code is obviously obfuscated!
  • The proxy must not be obfuscated (for simplicity, I obfuscated everything then copied the original proxy.py over the obfuscated one)

So, now user code imports the proxy.py using importlib instead of the obfuscated.py.

And the proxy merely imports the obfuscated.py:

# proxy.py
import obfuscated
SimpleOne
  • 1,066
  • 3
  • 12
  • 29
0

I managed to import modules dynamically in this way:

    code = open('c:\Users\me\obfuscated.py','r').read()
    spec = importlib.util.spec_from_loader(package_name,loader=None)
    module = importlib.util.module_from_spec(spec)
    module.__file__ = 'c:\Users\me\obfuscated.py'
    globals_dict = {"__file__":module.__file__}
    exec(code, globals_dict)
    for item in [x for x in globals_dict["__builtins__"] if not x.startswith("_")]:
        setattr(module,item,globals_dict["__builtins__"].get(item))

It reads code from a file, initiates a module, and eventually puts variables in a dictionary. You can find the module's functions in globals_dict["__builtins__"]