Falldog / pyconcrete

Protect your python script, encrypt it as .pye and decrypt when import it
Apache License 2.0
694 stars 149 forks source link

deploy code with different python version #50

Closed shoulewoba closed 5 years ago

shoulewoba commented 5 years ago

When i try to protect some python sdk with pyconcrete, i just cannot deploy protected python sdk on another pc because python version might be unmatched. But as for python sdk, it might be deployed on a lot of pc of which python version cannot be control, so, is there any way to solve this problem?

Falldog commented 5 years ago

pyconcrete compile .py to .pyc and then encripte to .pye .pyc is version dependency, different python version has different .pyc format.

There are 2 solution

  1. Don't compile .py to .pyc, just encrypt .py to .pye pros: simple, need update pyconcrte source cons: lower security, it's not safe
  2. Build your package in all support python version, the user need to download different version by them self
shoulewoba commented 5 years ago

i just modified the pyconcrete-admin.py: def _compile_pye_file(self, args, py_file): """ if there is no .pyc file, compile .pyc first then compile .pye """ import pyconcrete pyc_file = py_file # + 'c' pye_file = py_file + 'e' pyc_exists = exists(pyc_file)

if not pyc_exists or os.stat(py_file).st_mtime != os.stat(pyc_file).st_mtime:

        #py_compile.compile(py_file, cfile=pyc_file)
    if not exists(pye_file) or os.stat(py_file).st_mtime != os.stat(pye_file).st_mtime:
        pyconcrete.encrypt_file(pyc_file, pye_file)
        if args.verbose:
            print('* create %s' % pye_file)
    else:
        if args.verbose:
            print('* skip %s' % pye_file)

    # .pyc doesn't exists at beginning, remove it after .pye created
    if not pyc_exists or args.remove_pyc:
        os.remove(pyc_file)
    if args.remove_py:
        os.remove(py_file)

just to skip the ".py ->.pyc" part, but which doesn't really work, ValueError will be raised from init.py of pyconcrete.

Do i need to modify many parts of pyconcrete to support the first solution?

Falldog commented 5 years ago

you need to modify src/pyconcrete/__init__.py load_module() don't need to do marshal.loads, exec the source code directly

reference: https://stackoverflow.com/questions/1027714/how-to-execute-a-file-within-the-python-interpreter

shoulewoba commented 5 years ago

ths a lot!