Выполнить байт-код .pyc из кода Python? - PullRequest
0 голосов
/ 08 июня 2018

У меня есть документ с байт-кодом, который объявляет функции и логотип.У меня также есть файл .py, где я вызываю байт-код для вывода логотипа и строк в функции.Как мне на самом деле выполнить байт-код?Мне удалось его разобрать и посмотреть ассемблерный код.Как я могу на самом деле запустить его?

question.py

import dis
import logo
def work_here():
    # execute the bytecode

def main():
    work_here()

if __name__ == '__main__':
    main()

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Чтобы импортировать файл .pyc, вы просто делаете то же самое, что вы делаете с файлом .py: import spam найдет соответствующим образом расположенное spam.pyc (или, скорее, что-то вроде __pycache__/spam.cpython-36.pyc) так же, какон найдет подходящее место spam.py.Его код верхнего уровня запускается, все функции и классы определяются так, что вы можете вызывать их и т. Д., Точно так же, как с файлом .py;единственное отличие состоит в том, что нет исходного текста, который можно было бы показать для таких вещей, как трассировка или пошаговый отладчик.


Если вы хотите программно импортировать файл .pyc по явному пути или выполнить его без импортаэто, вы снова делаете то же самое, что вы делаете с файлом .py.

Посмотрите на Примеры в importlib.Например:

path = 'bytecoderepo/myfile.pyc'
spec = importlib.util.spec_from_file('myfile', path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)

И теперь код в bytecoderepo/myfile.pyc был выполнен, и полученный модуль доступен в переменной mod, но не в sys.modules или не сохранен какглобальный.


Если вам действительно нужно покопаться в формате .pyc и, например, извлечь байт-код какой-либо функции, чтобы вы могли exec ее (или построить объект функции из нее), без выполнения основного кода модуля, детали документируются только в исходном коде и могут изменяться между версиями Python.Начните с importlib;возможность (проверять и) пропускать заголовок и marshal.loads тело может быть настолько большим, насколько вам нужно изучить, но, вероятно, нет (поскольку в конечном итоге это то, что загрузчик модулей уже сделал для вас в приведенном выше примере кода, поэтомуесли этого недостаточно, нужно глубже проникнуть во внутренние органы).

0 голосов
/ 08 июня 2018

Попробуйте что-то вроде:

import dis

code = 'some byte code'

b_code = dis.Bytecode(code)

exec(b.codeobj)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...