#python-3.x #unmarshalling #inspect
Вопрос:
простой скрипт проверки файла pyc есть проблема с функцией co_name, скрипт работает хорошо, пока модуль маршала не загрузится, а затем не упадет.
magic: 160d0d0a
mod_time: 1493965574
source_size: 231
code:
Traceback (most recent call last):
File "/home/ubuntu/Downloads/book-resources-master/chapter4/code-exec-eg/python/inspect.py", line 24, in <module>
inspect_code(code)
File "/home/ubuntu/Downloads/book-resources-master/chapter4/code-exec-eg/python/inspect.py", line 8, in inspect_code
print('{}{}(line:{})'.format(indent, code.co_names, code.co_firstlineno))
AttributeError: 'float' object has no attribute 'co_names'
если кто-нибудь может помочь !
Спасибо
import marshal
import types
def to_long(s):
return s[0] (s[1] << 8) (s[2] << 16) (s[3] << 24)
def inspect_code(code, indent=' '):
print('{}{}(line:{})'.format(indent, code.co_names, code.co_firstlineno))
for c in code.co_consts:
if isinstance(c, types.CodeType):
inspect_code(c, indent ' ')
f = open('__pycache__/add.cpython-39.pyc', 'rb')
magic = f.read(4)
print('magic: {}'.format(magic.hex()))
mod_time = to_long(f.read(4))
print('mod_time: {}'.format(mod_time))
source_size = to_long(f.read(4))
print('source_size: {}'.format(source_size))
print('ncode:')
code = marshal.load(f)
inspect_code(code)
f.close()
import dis
dis.disassemble(code)
Ответ №1:
Я не знаком ни с marshal
модулем, ни pyc
с содержимым, но когда я попробовал ваш код с Python 3.9, я получил ошибку при чтении значения кода. И формат файла кажется другим для моего примера pyc, построенного на Python 3.9.
magic: 610d0d0a
mod_time: 0 # <---- Unknown
source_size: 1621462747 # <---- Must be mode time
Когда я прочитал еще 4 байта, прежде чем прочитать значение для кода, я получил это:
magic: 610d0d0a
mod_time: 0
source_size: 1621462747
4 more bytes: 14 # <----- Must be source size
Тогда я мог бы прочитать значение кода:
code:
('print',)(line:1)
1 0 LOAD_NAME 0 (print)
2 LOAD_CONST 0 ('Hello')
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 1 (None)
10 RETURN_VALUE
Я не уверен, почему вы можете работать marshal.load()
без ошибок, но можете ли вы попытаться прочитать 4 байта больше или меньше перед вызовом marshal.load(f)
?
Комментарии:
1. Я думаю, что проблема не в чтении перед вызовом, а в определении модуля в моей версии, однако я уже обновил свою версию python, но ничего не происходит.!!