Существует некоторая путаница относительно того, что делает uncompyle6 .Он начинается с Python bytecode или, точнее, «wordcode», если это Python 3.6 или выше.В качестве альтернативы, он часто используется для декомпиляции скомпилированного Python-файла, который содержит байт-код.
Судя по тому, что вы показываете выше, я считаю, что вы хотите начать с представления text байт-кодасоздается дизассемблером, зависящим от версии, который поставляется (и полностью работает только с) версией, на которой работает Python.
Вот причина, по которой вы получаете это странное сообщение «Ошибка импорта» выше от uncompyle6 .Он смотрит на начало текстового файла, который вы странным образом называете скомпилированным Python-файлом.Этот файл начинается со строки в кодировке ASCII "1
", а uncompyle6 интерпретирует это в соответствии с определенным форматом для скомпилированного файла Python , где начало файла содержит некую строку версии в кодировке PythonТехнически называемый «магическим числом».
Не бойтесь, я написал еще несколько инструментов, которые помогут вам приблизиться к тому месту, куда вы хотите попасть.В частности, я написал кросс-версию Python на ассемблере , чтобы он соответствовал встроенному в Python дизассемблеру .
Это в моем проекте github python-xasm .
Используя это, вы можете создать настоящий байт-код Python, который можно запустить.И если код, который вы написали, действительно похож на то, что выполнил Python, он, вероятно, может быть декомпилирован обратно в Python высокого уровня.
Однако xasm в настоящее время нуждается в немного большей помощи, чемчто у тебя выше.В частности, он не будет угадывать по именам кодов операций, к какой версии Python они могут принадлежать.Сопоставить имена кодов операций с приемлемыми версиями Python еще сложнее, чем вы думаете.Если вы видите LOAD_CONST
, вам также нужно подумать, занимает ли инструкция 2 байта или 3. Если 2, то это Python 3.6 и выше, иначе Python <3.6.И если это не достаточно сложно, некоторые версии Python изменяют значение кода операции для определенного имени кода операции!Поэтому возможно, что вы не сможете точно определить <em>, из какого интерпретатора Python происходит какая-то сборка.Но я предполагаю, что вам все равно, пока все, что вы придумаете, будет последовательным.
Итак, с учетом вышеизложенного, теперь вернемся к решению вашего вопроса.
Сначала создайте настоящий байт-код.Вы можете сделать это следующим образом
import py_compile
py_compile.compile("/tmp/test.py", "/tmp/test.pyc", 'exec')
Теперь вместо использования встроенного дизассемблера Python используйте кросс-версию дизассемблера, который я написал, и который поставляется с xdis , который называется pydisasm и используйте опцию --asm
, которая выведет сборку в xasm
-дружественном способе:
$ pydisasm --asm
# pydisasm version 4.0.0-git
# Python bytecode 3.6 (3379)
# Disassembled from Python 3.6.5 (default, Aug 12 2018, 16:37:27)
# [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
# Timestamp in code: 1554492841 (2019-04-05 15:34:01)
# Source code size mod 2**32: 23 bytes
# Method Name: <module>
# Filename: exec
# Argument count: 0
# Kw-only arguments: 0
# Number of locals: 0
# Stack size: 3
# Flags: 0x00000040 (NOFREE)
# First Line: 1
# Constants:
# 0: 1
# 1: 2
# 2: None
# Names:
# 0: a
# 1: b
# 2: print
1:
LOAD_CONST (1)
STORE_NAME (a)
2:
LOAD_CONST (2)
STORE_NAME (b)
3:
LOAD_NAME (print)
LOAD_NAME (a)
LOAD_NAME (b)
BINARY_ADD
CALL_FUNCTION 1
POP_TOP
LOAD_CONST (None)
RETURN_VALUE
Обратите внимание на всю дополнительную информацию в комментариях вверхуфайл, который содержит некоторые действительно загадочные вещи, такие как «размер стека» и «флаги».Это и большинство других вещей должны храниться в файле байт-кода Python.
Сохраните это в файл, и , затем , вы можете собрать его в байт-код.А потом декомпилируй это.
$ ./xasm/xasm_cli.py /tmp/test.pyasm
Wrote /tmp/test.pyc
$ uncompyle6 /tmp/test.pyc
# uncompyle6 version 3.2.6
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.5 (default, Aug 12 2018, 16:37:27)
# [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
# Embedded file name: exec
# Compiled at: 2019-04-05 15:34:01
# Size of source mod 2**32: 23 bytes
a = 1
b = 2
print(a + b)
# okay decompiling /tmp/test.pyc
Я выступил с молниеносной речью на Pycon2018 в Медельине, Колумбия, по этому поводу.Извините, что вы пропустили это, но вы можете найти видео здесь http://rocky.github.io/pycon2018-light.co
Здесь показано, как:
- создать скомпилированный файл Python из исходного текста Python в кодировке ASCII,
- измените его, чтобы удалить хвостовую рекурсию,
- запишите это обратно в скомпилированный файл Python, а затем
- запустите код.
Конечно, вы не можете декомпилировать это, потому что - это нелегко Python, который подражает так близко - он был изменен вручную.
Наконец, похоже,Вас также интересует, как связаны байт-код и исходный код.Поэтому я упомяну, что uncompyle6 имеет параметры --tree
и еще более подробный --grammar
, который покажет шаги, предпринятые для восстановления Python из байт-кода Python.