Files

147 lines
5.9 KiB
Python

from lighthouse.util.log import lmsg
from lighthouse.util.misc import iteritems
from lighthouse.util.disassembler import disassembler
#------------------------------------------------------------------------------
# Exception Definitions
#------------------------------------------------------------------------------
class LighthouseError(Exception):
"""
An error generated by Lighthouse.
"""
def __init__(self, *args, **kwargs):
super(LighthouseError, self).__init__(*args, **kwargs)
#------------------------------------------------------------------------------
# Coverage File Exceptions
#------------------------------------------------------------------------------
class CoverageException(LighthouseError):
"""
A class of errors pertaining to loading & mapping coverage files.
"""
name = NotImplementedError
description = NotImplementedError
def __init__(self, message, filepath):
super(CoverageException, self).__init__(message)
self.filepath = filepath
@property
def verbose(self):
return "Error: %s\n\n%s" % (self.name, self.description)
def __str__(self):
return self.message + " '%s'" % self.filepath
class CoverageParsingError(CoverageException):
"""
An error generated by the CoverageReader when all parsers fail.
"""
name = "PARSE_FAILURE"
description = \
"Failed to parse one or more of the selected coverage files!\n\n" \
" Possible reasons:\n" \
" - You selected a file that was *not* a coverage file.\n" \
" - The selected coverage file is malformed or unreadable.\n" \
" - A suitable parser for the coverage file is not installed.\n\n" \
"Please see the disassembler console for more info..."
def __init__(self, filepath, tracebacks):
super(CoverageParsingError, self).__init__("Failed to parse coverage file", filepath)
self.tracebacks = tracebacks
class CoverageMissingError(CoverageException):
"""
An error generated when no data was extracted from a CoverageFile.
"""
name = "NO_COVERAGE_ERROR"
description = \
"No usable coverage data was extracted from one of the selected files.\n\n" \
" Possible reasons:\n" \
" - You selected a coverage file for the wrong binary.\n" \
" - The name of the executable file used to generate this database\n" \
" is different than the one you collected coverage against.\n" \
" - Your DBI failed to collect any coverage for this binary.\n\n" \
"Please see the disassembler console for more info..."
def __init__(self, filepath):
super(CoverageMissingError, self).__init__("No coverage extracted from file", filepath)
class CoverageMappingAbsent(CoverageException):
"""
A warning generated when coverage data cannot be mapped.
"""
name = "NO_COVERAGE_MAPPED"
description = \
"One or more of the loaded coverage files has no visibly mapped data.\n\n" \
" Possible reasons:\n" \
" - The loaded coverage data does not fall within defined functions.\n" \
" - You loaded an absolute address trace with a different imagebase.\n" \
" - The coverage data might be corrupt or malformed.\n\n" \
"Please see the disassembler console for more info..."
def __init__(self, coverage):
super(CoverageMappingAbsent, self).__init__("No coverage data could be mapped", coverage.filepath)
self.coverage = coverage
class CoverageMappingSuspicious(CoverageException):
"""
A warning generated when coverage data does not appear to match the database.
"""
name = "BAD_COVERAGE_MAPPING"
description = \
"One or more of the loaded coverage files appears to be badly mapped.\n\n" \
" Possible reasons:\n" \
" - You selected the wrong binary/module to load coverage from.\n" \
" - Your coverage file/data is for a different version of the\n" \
" binary that does not match what the disassembler has open.\n" \
" - You recorded self-modifying code or something with very\n" \
" abnormal control flow (obfuscated code, malware, packers).\n" \
" - The coverage data might be corrupt or malformed.\n\n" \
"This means that any coverage displayed by Lighthouse is PROBABLY\n" \
"WRONG and is not be trusted because the coverage data does not\n" \
"appear to match the disassembled binary."
def __init__(self, coverage):
super(CoverageMappingSuspicious, self).__init__("Coverage data appears badly mapped", coverage.filepath)
self.coverage = coverage
#------------------------------------------------------------------------------
# UI Warnings
#------------------------------------------------------------------------------
def warn_errors(errors, ignore=[]):
"""
Warn the user of any encountered errors with a messagebox.
"""
if not errors:
return
for error_type, error_list in iteritems(errors):
#
# loop through the individual instances/files that caused this error
# and dump the results to the disassembler console...
#
lmsg("-"*50)
lmsg("Files reporting %s:" % error_type.name)
for error in error_list:
lmsg(" - %s" % error.filepath)
# suppress popups for certain errors, if the user has specified such
if error_type in ignore:
continue
#
# popup a more verbose error messagebox for the user to read regarding
# this class of error they encountered
#
disassembler.warning(error.verbose)
# done ...
lmsg("-"*50)