verify.py: Don't try to verify bytecode against compiled code if

magics of running interpreter mismatch bytecode to be compared.
load_module() now returns the magic found in the code object file.
This commit is contained in:
rocky 2015-12-18 22:04:50 -05:00
parent 6bc425b45e
commit 0a49c7a15b
4 changed files with 42 additions and 29 deletions

View File

@ -77,13 +77,18 @@ def _load_file(filename):
return co
def load_module(filename):
'''
load a module without importing it
load_module(filename: string): code_object
"""
load a module without importing it.
load_module(filename: string): version, magic_int, code_object
filename: name of file containing Python byte-code object
(normally a .pyc)
code_object: code_object from this file
'''
version: Python major/minor value e.g. 2.7. or 3.4
magic_int: more specific than version. The actual byte code version of the
code object
"""
with open(filename, 'rb') as fp:
magic = fp.read(4)
@ -117,11 +122,11 @@ def load_module(filename):
co = uncompyle6.marsh.load_code(fp, magic_int)
pass
return version, co
return version, magic_int, co
def uncompyle(version, co, out=None, showasm=False, showast=False):
"""
diassembles and deparses a given code block 'co'
disassembles and deparses a given code block 'co'
"""
assert isinstance(co, types.CodeType)
@ -173,7 +178,7 @@ def uncompyle_file(filename, outstream=None, showasm=False, showast=False):
decompile Python byte-code file (.pyc)
"""
check_object_path(filename)
version, co = load_module(filename)
version, magic_int, co = load_module(filename)
if type(co) == list:
for con in co:
uncompyle(version, con, outstream, showasm, showast)
@ -282,9 +287,13 @@ def main(in_base, out_base, files, codes, outfile=None,
outstream.close()
if do_verify:
try:
verify.compare_code_with_srcfile(infile, outfile)
if not outfile: print('\n# okay decompyling', infile, __memUsage())
okay_files += 1
msg = verify.compare_code_with_srcfile(infile, outfile)
if not outfile:
if not msg:
print('\n# okay decompyling %s' % infile)
okay_files += 1
else:
print('\n# %s\n\t%s', infile, msg)
except verify.VerifyCmpError as e:
verify_failed_files += 1
os.rename(outfile, outfile + '_unverified')

View File

@ -1,8 +1,6 @@
from __future__ import print_function
import struct, sys
__all__ = ['magics', 'versions', 'magic2int']
import imp, struct, sys
def __build_magic(magic):
if (sys.version_info >= (3, 0)):
@ -13,6 +11,8 @@ def __build_magic(magic):
def magic2int(magic):
return struct.unpack('Hcc', magic)[0]
PYTHON_MAGIC_INT = magic2int(imp.get_magic())
by_magic = {}
by_version = {}
@ -96,15 +96,13 @@ def __show(text, magic):
print(text, struct.unpack('BBBB', magic), struct.unpack('HBB', magic))
def test():
import imp
magic_20 = magics['2.0']
current = imp.get_magic()
current_version = struct.unpack('HBB', current)[0]
magic_current = by_magic[ current ]
print(type(magic_20), len(magic_20), repr(magic_20))
print()
print('This Python interpreter has version', magic_current)
print('Magic code: ', current_version)
print('Magic code: ', PYTHON_MAGIC_INT)
print(type(magic_20), len(magic_20), repr(magic_20))
if __name__ == '__main__':

View File

@ -15,14 +15,13 @@ to produce a code object
from __future__ import print_function
import imp, sys, types
import sys, types
from struct import unpack
from uncompyle6.magics import magic2int
from uncompyle6.magics import PYTHON_MAGIC_INT
internStrings = []
PYTHON_MAGIC_INT = magic2int(imp.get_magic())
PYTHON3 = (sys.version_info >= (3, 0))
if PYTHON3:

View File

@ -1,18 +1,22 @@
#
# (C) Copyright 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# (C) Copyright 2015 by Rocky Bernstein
#
# byte-code verifier for uncompyle
#
"""
byte-code verification
"""
from __future__ import print_function
import dis, inspect, operator, sys, types
import dis, inspect, operator, types
import uncompyle6
import uncompyle6.scanner as scanner
from uncompyle6 import PYTHON3
from uncompyle6.magics import PYTHON_MAGIC_INT
# FIXME: DRY
if (sys.version_info >= (3, 0)):
if PYTHON3:
truediv = operator.truediv
from functools import reduce
else:
@ -344,14 +348,19 @@ class Token(scanner.Token):
def compare_code_with_srcfile(pyc_filename, src_filename):
"""Compare a .pyc with a source code file."""
version, code_obj1 = uncompyle6.load_module(pyc_filename)
version, magic_int, code_obj1 = uncompyle6.load_module(pyc_filename)
if magic_int != PYTHON_MAGIC_INT:
msg = ("Can't compare code - Python is running with magic %s, but code is magic %s "
% (PYTHON_MAGIC_INT, magic_int))
return msg
code_obj2 = uncompyle6._load_file(src_filename)
cmp_code_objects(version, code_obj1, code_obj2)
return None
def compare_files(pyc_filename1, pyc_filename2):
"""Compare two .pyc files."""
version, code_obj1 = uncompyle6.load_module(pyc_filename1)
version, code_obj2 = uncompyle6.load_module(pyc_filename2)
version, magic_int1, code_obj1 = uncompyle6.load_module(pyc_filename1)
version, magic_int2, code_obj2 = uncompyle6.load_module(pyc_filename2)
cmp_code_objects(version, code_obj1, code_obj2)
if __name__ == '__main__':
@ -359,6 +368,4 @@ if __name__ == '__main__':
t2 = Token('LOAD_CONST', -421, 'code_object _expandLang', 55)
print(repr(t1))
print(repr(t2))
if (sys.version_info < (3, 0)):
print(cmp(t1, t2), cmp(t1.type, t2.type), cmp(t1.attr, t2.attr))
print(t1.type == t2.type, t1.attr == t2.attr)