From 24ead55316ac8497df5842caf4e1d51f2b799787 Mon Sep 17 00:00:00 2001 From: Andrew Lamoureux Date: Tue, 19 Mar 2019 17:32:44 -0400 Subject: kaitai: adjustments and rearrangements for python2/3 compat --- python/examples/kaitai/kshelpers.py | 463 +++++++++++------------------------- 1 file changed, 138 insertions(+), 325 deletions(-) mode change 100755 => 100644 python/examples/kaitai/kshelpers.py (limited to 'python/examples/kaitai/kshelpers.py') diff --git a/python/examples/kaitai/kshelpers.py b/python/examples/kaitai/kshelpers.py old mode 100755 new mode 100644 index 859a206c..55ebd01e --- a/python/examples/kaitai/kshelpers.py +++ b/python/examples/kaitai/kshelpers.py @@ -1,112 +1,109 @@ #!/usr/bin/env python -from __future__ import absolute_import - import io +import os import sys +import struct import types +import importlib import binaryninja from PySide2.QtCore import Qt from PySide2.QtWidgets import QTreeWidgetItem -from .kaitaistruct import KaitaiStruct - -#sys.path.append('kaitai_struct_formats/archive') -#sys.path.append('kaitai_struct_formats/cad') -#sys.path.append('kaitai_struct_formats/common') -#sys.path.append('kaitai_struct_formats/database') -#sys.path.append('./kaitai_struct_formats/executable') -#sys.path.append('kaitai_struct_formats/filesystem') -#sys.path.append('kaitai_struct_formats/firmware') -#sys.path.append('kaitai_struct_formats/font') -#sys.path.append('kaitai_struct_formats/game') -#sys.path.append('kaitai_struct_formats/geospatial') -#sys.path.append('kaitai_struct_formats/hardware') -#sys.path.append('kaitai_struct_formats/image') -#sys.path.append('kaitai_struct_formats/log') -#sys.path.append('kaitai_struct_formats/machine_code') -#sys.path.append('kaitai_struct_formats/media') -#sys.path.append('kaitai_struct_formats/network') -#sys.path.append('kaitai_struct_formats/scientific') -#sys.path.append('kaitai_struct_formats/security') -#sys.path.append('kaitai_struct_formats/serialization') -#sys.path.append('kaitai_struct_formats/windows') +if sys.version_info[0] == 2: + import kaitaistruct +else: + from . import kaitaistruct #------------------------------------------------------------------------------ # id and parse #------------------------------------------------------------------------------ -def id_data(data): - if len(data) < 16: - return None +# return the name of the kaitai module to service this data +# +# dsample: str data sample +# length: int total length of data +def idData(dataSample, length): + result = None - if data[0:4] == "\x7fELF": - return 'elf' - if data[0:4] in ['\xfe\xed\xfa\xce', '\xce\xfa\xed\xfe', '\xfe\xed\xfa\xcf', '\xcf\xfa\xed\xfe']: - return 'macho' - if data[0:2] == 'MZ': - return 'pe' - if data[0:8] == '\x89\x50\x4e\x47\x0d\x0a\x1a\x0a': - return 'png' - if data[2:11] == '0xFF\xe0\x00\x10JFIF\x00': - return 'jpeg' - if data[0:6] == 'GIF89a': - return 'gif' - - return None - -def id_file(fpath): - data = None + if len(dataSample) < 16: + return result + + if dataSample[0:4] == b'\x7fELF': + result = 'elf' + if dataSample[0:4] in [b'\xfe\xed\xfa\xce', b'\xce\xfa\xed\xfe', b'\xfe\xed\xfa\xcf', b'\xcf\xfa\xed\xfe']: + result = 'mach_o' + if dataSample[0:2] == b'MZ': + result = 'microsoft_pe' + if dataSample[0:8] == b'\x89PNG\x0d\x0a\x1a\x0a': + result = 'png' + if dataSample[2:11] == b'\xFF\xe0\x00\x10JFIF\x00': + result = 'jpeg' + if dataSample[0:4] == b'GIF8': + result = 'gif' + if dataSample[0:2] in [b'BM', b'BA', b'CI', b'CP', b'IC', b'PT'] and struct.unpack('0 and isinstance(subObj[0], KaitaiStruct): - for i in range(len(subObj)): - print '%s.%s[%d]:' % (indent, fieldName, i) - dump(subObj[i], depth+1) - else: - print '%s.%s: %s' % (indent, fieldName, str(subObj)) - elif type(subObj) == types.DictionaryType: - print '%s.%s: %s' % (indent, fieldName, subObj) - - elif type(subObj) == types.StringType: - print '%s.%s: %s' % (indent, fieldName, repr(subObj)) - - elif type(subObj) == int: - print '%s.%s: 0x%X (%d)' % (indent, fieldName, subObj, subObj) - - elif str(type(subObj)).startswith('0: + elif isinstance(subObj, list): + if len(subObj)<=0: + continue + # CASE: is list of KaitaiObjects -> recurse! - if isinstance(subObj[0], KaitaiStruct): + if isinstance(subObj[0], kaitaistruct.KaitaiStruct): child = KaitaiTreeWidgetItem() - populate_child(ksobj, fieldName, fieldName, None, child) + populateChild(ksobj, fieldName, fieldName, None, child) # does _debug have an array version of start/end? startsEnds = None @@ -486,7 +306,7 @@ def build_qtree(ksobj): startsEnds = ksobj._debug[fieldName]['arr'] for i in range(len(subObj)): - grandchild = build_qtree(subObj[i]) + grandchild = buildQtree(subObj[i]) fieldLabel = '%s[%d]' % (fieldName, i) grandchild.setLabel(fieldLabel) @@ -501,10 +321,10 @@ def build_qtree(ksobj): # CASE: is list of primitive objects -> create leaves else: child = KaitaiTreeWidgetItem() - populate_child(ksobj, fieldName, fieldName, None, child) + populateChild(ksobj, fieldName, fieldName, None, child) # TODO: explain this hack - kstmp = KaitaiStruct(ksobj._io) + kstmp = kaitaistruct.KaitaiStruct(ksobj._io) kstmp._parent = ksobj child.setKaitaiObject(kstmp) @@ -531,7 +351,7 @@ def build_qtree(ksobj): child = createLeaf(fieldName, subObj) if child: # don't override createLeaf()'s work on label, value - populate_child(ksobj, fieldName, None, None, child) + populateChild(ksobj, fieldName, None, None, child) qwi.addChild(child) return qwi @@ -539,24 +359,35 @@ def build_qtree(ksobj): def createLeaf(fieldName, obj): objtype = type(obj) - if objtype == types.MethodType: + if objtype == types.FunctionType: + #print('reject %s because its a function' % fieldName) + return None + elif isinstance(obj, type): + #print('reject %s because its a type' % fieldName) + return None + elif sys.version_info[0] == 2 and callable(obj): + #print('reject %s because its a callable' % fieldName) return None - elif objtype == types.TypeType: + elif sys.version_info[0] == 3 and hasattr(obj, '__call__'): + #print('reject %s because its a callable' % fieldName) return None fieldValue = None - if objtype in [types.StringType, types.UnicodeType]: - #if filter(lambda c: c<32 or c>127, obj): + if isinstance(obj, str): fieldValue = repr(obj) - elif objtype == types.IntType: + elif isinstance(obj, bytes): + fieldValue = repr(obj) + elif sys.version_info[0] == 2 and objtype == types.UnicodeType: + fieldValue = repr(obj) + elif isinstance(obj, int): fieldValue = '0x%X (%d)' % (obj, obj) - elif objtype == types.BooleanType: + elif isinstance(obj, bool): fieldValue = '%s' % (obj) elif str(objtype).startswith('