From b5fd5d118338159eed5969c5df4ad7d55d732a3d Mon Sep 17 00:00:00 2001 From: Andrew Lamoureux Date: Thu, 21 Mar 2019 23:32:35 -0400 Subject: kaitai: better error reporting when parser fails --- python/examples/kaitai/kshelpers.py | 78 ++++++++++++++++++++++--------------- python/examples/kaitai/view.py | 31 +++++++-------- 2 files changed, 61 insertions(+), 48 deletions(-) (limited to 'python') diff --git a/python/examples/kaitai/kshelpers.py b/python/examples/kaitai/kshelpers.py index 43b8e525..d4507572 100644 --- a/python/examples/kaitai/kshelpers.py +++ b/python/examples/kaitai/kshelpers.py @@ -9,7 +9,7 @@ import struct import types import importlib -import binaryninja +from binaryninja import log from PySide2.QtCore import Qt from PySide2.QtWidgets import QTreeWidgetItem @@ -29,7 +29,7 @@ else: # length: int total length of data def idData(dataSample, length): result = None - #print('idData() here with sample: %s' % repr(dataSample)) + #log.log_debug('idData() here with sample: %s' % repr(dataSample)) if len(dataSample) < 16: return result @@ -55,7 +55,7 @@ def idData(dataSample, length): if dataSample[0:2] == b'\x1f\x8b' and dataSample[2:3]==b'\x08': result = 'gzip' - #print('idData() returning \'%s\'' % result) + #log.log_debug('idData() returning \'%s\'' % result) return result def idFile(fpath): @@ -73,17 +73,18 @@ def ksImportClass(moduleName): classThing = None try: - #print('__package__: -%s-' % __package__) # 'kaitai' - #print('__name__: -%s-' % __name__) # 'kaitai.kshelpers' - #print('moduleName: -%s-' % moduleName) - #print('importlib.import_module(.%s, %s)' % (moduleName, __package__)) - print('importing kaitai module "%s"' % moduleName) + #log.log_debug('__package__: -%s-' % __package__) # 'kaitai' + #log.log_debug('__name__: -%s-' % __name__) # 'kaitai.kshelpers' + #log.log_debug('moduleName: -%s-' % moduleName) + #log.log_debug('importlib.import_module(.%s, %s)' % (moduleName, __package__)) + log.log_info('importing kaitai module %s' % moduleName) module = importlib.import_module('.'+moduleName, __package__) className = ksModuleToClass(moduleName) - #print('className: -%s-' % className) + #log.log_debug('className: -%s-' % className) classThing = getattr(module, className) except Exception as e: - print(e) + log.log_error('importing kaitai module %s' % moduleName) + #log.log_debug(e) pass return classThing @@ -91,25 +92,33 @@ def ksImportClass(moduleName): def parseFpath(fpath, ksModuleName=None): if not ksModuleName: ksModuleName = idFile(fpath) - #print('parseFpath() using kaitai format: %s' % ksModuleName) + #log.log_debug('parseFpath() using kaitai format: %s' % ksModuleName) ksClass = ksImportClass(ksModuleName) if not ksClass: return None - parsed = ksClass.from_file(fpath) - parsed._read() + try: + parsed = ksClass.from_file(fpath) + parsed._read() + except Exception: + log.log_error('kaitai module %s threw exception, check file type' % ksModuleName) + return parsed def parseData(data, ksModuleName=None): if not ksModuleName: ksModuleName = idData(data, len(data)) - #print('parseData() using kaitai format: %s' % ksModuleName) + #log.log_debug('parseData() using kaitai format: %s' % ksModuleName) ksClass = ksImportClass(ksModuleName) if not ksClass: return None - parsed = ksClass.from_bytes(data) - parsed._read() + try: + parsed = ksClass.from_bytes(data) + parsed._read() + except Exception: + log.log_error('kaitai module %s threw exception, check file type' % ksModuleName) + return parsed def parseIo(ioObj, ksModuleName=None): @@ -119,15 +128,20 @@ def parseIo(ioObj, ksModuleName=None): if not ksModuleName: ioObj.seek(0, io.SEEK_SET) ksModuleName = idData(ioObj.read(16), length) - #print('parseIo() using kaitai format: %s' % ksModuleName) + #log.log_debug('parseIo() using kaitai format: %s' % ksModuleName) ioObj.seek(0, io.SEEK_SET) ksClass = ksImportClass(ksModuleName) if not ksClass: return None - ioObj.seek(0, io.SEEK_SET) - parsed = ksClass.from_io(ioObj) - parsed._read() + try: + ioObj.seek(0, io.SEEK_SET) + parsed = ksClass.from_io(ioObj) + parsed._read() + except Exception: + log.log_error('kaitai module %s threw exception, check file type' % ksModuleName) + parsed = None + return parsed #------------------------------------------------------------------------------ @@ -145,7 +159,7 @@ class KaitaiBinaryViewIO: self.position = 0 def seek(self, offs, whence=io.SEEK_SET): - #print('seek(0x%X, %d)' % (offs, whence)) + #log.log_debug('seek(0x%X, %d)' % (offs, whence)) if whence == io.SEEK_SET: self.position = offs elif whence == io.SEEK_CUR: @@ -156,7 +170,7 @@ class KaitaiBinaryViewIO: raise Exception('unknown whence in seek(): %d' % whence) def tell(self): - #print('tell() returning 0x%X' % (self.position)) + #log.log_debug('tell() returning 0x%X' % (self.position)) return self.position def read(self, length=None): @@ -164,7 +178,7 @@ class KaitaiBinaryViewIO: if length == None: length = len(self.binaryView) - self.position - #print('read(%d) (starting at position: 0x%X)' % (length, self.position)) + #log.log_debug('read(%d) (starting at position: 0x%X)' % (length, self.position)) data = self.binaryView.read(self.position, length) self.position += length return data @@ -383,16 +397,16 @@ def createLeaf(fieldName, obj): objtype = type(obj) if objtype == types.FunctionType: - #print('reject %s because its a function' % fieldName) + #log.log_debug('reject %s because its a function' % fieldName) return None elif isinstance(obj, type): - #print('reject %s because its a type' % fieldName) + #log.log_debug('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) + #log.log_debug('reject %s because its a callable' % fieldName) return None elif sys.version_info[0] == 3 and hasattr(obj, '__call__'): - #print('reject %s because its a callable' % fieldName) + #log.log_debug('reject %s because its a callable' % fieldName) return None fieldValue = None @@ -410,7 +424,7 @@ def createLeaf(fieldName, obj): elif str(objtype).startswith('