def ParseInstrumentation(data):
	instrumentation = Instrumentation()
	
	statusBlockString = ''
	for line in data.splitlines():
		statusBlockString += line + '\n'

		if line.startswith("INSTRUMENTATION_STATUS_CODE:"):
			status = _ParseStatus(statusBlockString)
			instrumentation.addStatus(status)
			statusBlockString = ""
	
	return instrumentation
Esempio n. 2
0
def ParseInstrumentation(data):
    instrumentation = Instrumentation()

    statusBlockString = ''
    for line in data.splitlines():
        statusBlockString += line + '\n'

        if line.startswith("INSTRUMENTATION_STATUS_CODE:"):
            status = _ParseStatus(statusBlockString)
            instrumentation.addStatus(status)
            statusBlockString = ""

    return instrumentation
Esempio n. 3
0
class TestInstrumentationToTestResultTransformer(unittest.TestCase):
	SUCCESS = 0
	ERROR = -1
	FAIL = -2
	
	def setUp(self):
		self._instrumentation = Instrumentation()
		
	def _addTestRun(self, className, methodName, result):
		status = Status()
		status['class'] = className
		status['test'] = methodName
		status.statusCode = 1
		self._instrumentation.addStatus(status)
		
		status = Status()
		status['class'] = className
		status['test'] = methodName
		status.statusCode = result
		self._instrumentation.addStatus(status)

	def _addSuccessfulTestRun(self, className, methodName):
		self._addTestRun(className, methodName, self.SUCCESS)
	
	def _addFailingTestRun(self, className, methodName, stack):
		self._addTestRun(className, methodName, self.FAIL)
		self._instrumentation.statuses()[-1]['stack'] = stack
	
	def _addErroringTestRun(self, className, methodName, stack):
		self._addTestRun(className, methodName, self.ERROR)
		self._instrumentation.statuses()[-1]['stack'] = stack

	def assertTestSuite(self, suite, name, package):
		self.assertEqual(suite.name, name)
		self.assertEqual(suite.package, package)
	
	def assertTestCase(self, case, method):
		self.assertEqual(case.name, method)
Esempio n. 4
0
def main():

    global tm_start

    for mod in ('metapc', 'ppc', 'arm'):
        arch_mod = __import__('arch.%s' % mod, globals(), locals(), ['*'])
        arch = arch_mod.Arch()
        if arch:
            if arch.check_arch():
                # This is a valid module for the current architecure
                # so the search has finished
                log_message('Using architecture module [%s]' % mod)
                break
    else:
        log_message(
            'No module found to process the current architecure [%s]. Exiting.'
            % (arch.processor_name))
        return

    global instrumentation

    log_message('Initialization sucessful.')

    db_engine, db_host, db_name, db_user, db_password = (None, ) * 5
    batch_mode = False
    module_comment = ''
    process_sections = False

    # If the configuration filename has been fetched from the
    # environment variables, then use that.
    #
    if CONFIG_FILE_NAME:
        config_file_path = CONFIG_FILE_NAME

    # Otherwise fallback into the one expected in the IDA directory
    #
    else:
        config_file_path = os.path.join(idaapi.idadir(''), 'ida2sql.cfg')

    if os.path.exists(config_file_path):
        cfg = ConfigParser.ConfigParser()
        cfg.read(config_file_path)

        if cfg.has_section('database'):
            if cfg.has_option('database', 'engine'):
                db_engine = getattr(DB_ENGINE, cfg.get('database', 'engine'))

            if cfg.has_option('database', 'host'):
                db_host = cfg.get('database', 'host')

            if cfg.has_option('database', 'schema'):
                db_name = cfg.get('database', 'schema')

            if cfg.has_option('database', 'user'):
                db_user = cfg.get('database', 'user')

            if cfg.has_option('database', 'password'):
                db_password = cfg.get('database', 'password')

            if cfg.has_option('importing', 'mode'):
                batch_mode = cfg.get('importing', 'mode')

                if batch_mode.lower() in ('batch', 'auto'):
                    batch_mode = True

            if cfg.has_option('importing', 'comment'):
                module_comment = cfg.get('importing', 'comment')

            if cfg.has_option('importing', 'process_sections'):
                process_sections = cfg.get('importing', 'process_sections')

                if process_sections.lower() in ('no', 'false'):
                    process_sections = False
                else:
                    process_sections = True

    if None in (db_engine, db_host, db_name, db_user, db_password):

        (db_engine, db_host, db_name, db_user,
         db_password) = query_configuration()

        if None in (db_engine, db_host, db_name, db_user, db_password):
            log_message('User cancelled the exporting.')
            return

    failed = False
    try:
        sqlexporter = SQLExporter(arch,
                                  db_engine,
                                  db=db_name,
                                  user=db_user,
                                  passwd=db_password,
                                  host=db_host,
                                  use_new_schema=USE_NEW_SCHEMA)
    except ImportError:
        print "Error connecting to the database, error importing required module: %s" % sys.exc_info(
        )[0]
        failed = True
    except Exception:
        print "Error connecting to the database, Reason: %s" % sys.exc_info(
        )[0]
        failed = True

    if failed:
        # Can't connect to the database, indicate that to BinNavi
        if batch_mode is True:
            idc.Exit(FATAL_CANNOT_CONNECT_TO_DATABASE)
        else:
            return

    if not sqlexporter.is_database_ready():

        if batch_mode is False:
            result = idc.AskYN(
                1,
                'Database has not been initialized yet. Do you want to create now the basic tables? (This step is performed only once)'
            )
        else:
            result = 1

        if result == 1:
            sqlexporter.init_database()
        else:
            log_message('User requested abort.')
            return

    iteration = os.environ.get('EXPORT_ITERATION', None)
    module_id = os.environ.get('MODULE_ID', None)

    if iteration is None and module_id == None:
        # Export manually
        print "Exporting manually ..."
        iteration = -1
        sqlexporter.set_callgraph_only(False)
        sqlexporter.set_exporting_manually(True)
        status = sqlexporter.new_module(idc.GetInputFilePath(),
                                        arch.get_architecture_name(),
                                        idaapi.get_imagebase(), module_comment,
                                        batch_mode)

    elif iteration is not None and module_id is not None:

        # Export the next k functions or the call graph
        sqlexporter.set_exporting_manually(False)
        sqlexporter.set_callgraph_only(int(iteration) == -1)
        sqlexporter.set_module_id(int(module_id))
        status = True

    else:

        sqlexporter.set_exporting_manually(False)
        status = sqlexporter.new_module(idc.GetInputFilePath(),
                                        arch.get_architecture_name(),
                                        idaapi.get_imagebase(), module_comment,
                                        batch_mode)
        sqlexporter.set_callgraph_only(False)

    if status is False:
        log_message('Export aborted')
        return
    elif status is None:
        log_message(
            'The database appears to contain data exported with different schemas, exporting not allowed.'
        )
        if batch_mode:
            idc.Exit(FATAL_INVALID_SCHEMA_VERSION)

    instrumentation = Instrumentation()

    instrumentation.new_function_callable(sqlexporter.process_function)
    instrumentation.new_packet_callable(sqlexporter.process_packet)
    instrumentation.new_section_callable(sqlexporter.process_section)

    tm_start = time.time()

    already_imported = sqlexporter.db.get_already_imported()

    incomplete = process_binary(arch, process_sections, int(iteration),
                                already_imported)

    sqlexporter.finish()

    log_message(
        'Results: %d functions, %d instructions, %d basic blocks, %d address references'
        % (len(sqlexporter.exported_functions),
           len(sqlexporter.exported_instructions),
           sqlexporter.basic_blocks_next_id - 1,
           sqlexporter.address_references_values_count))

    log_message(
        'Results: %d expression substitutions, %d operand expressions, %d operand tuples'
        % (sqlexporter.expression_substitutions_values_count,
           sqlexporter.operand_expressions_values_count,
           sqlexporter.operand_tuples___operands_values_count))

    log_message('Exporting completed in %s' % get_time_delta_string())

    # If running in batch mode, exit when done
    if batch_mode:
        if incomplete:
            shiftedModule = (sqlexporter.db.module_id << 0x10) | 0xFF

            idc.Exit(shiftedModule)
        elif not sqlexporter.callgraph_only:
            shiftedModule = (sqlexporter.db.module_id << 0x10) | 0xFE

            idc.Exit(shiftedModule)
        else:
            idc.Exit(0)
Esempio n. 5
0
def main():
    
    global tm_start
    
    for mod in ('metapc', 'ppc', 'arm'):
        arch_mod = __import__('arch.%s' % mod, globals(), locals(), ['*'])
        arch = arch_mod.Arch()
        if arch:
            if arch.check_arch():
                # This is a valid module for the current architecure
                # so the search has finished
                log_message('Using architecture module [%s]' % mod)
                break
    else:
        log_message('No module found to process the current architecure [%s]. Exiting.' % (arch.processor_name))
        return
        
    global instrumentation
    
    log_message('Initialization sucessful.')
    
    db_engine, db_host, db_name, db_user, db_password = (None,)*5
    batch_mode = False
    module_comment = ''
    process_sections = False
    
    
    # If the configuration filename has been fetched from the
    # environment variables, then use that.
    #
    if CONFIG_FILE_NAME:
        config_file_path = CONFIG_FILE_NAME
        
    # Otherwise fallback into the one expected in the IDA directory
    #
    else:
        config_file_path = os.path.join(idaapi.idadir(''), 'ida2sql.cfg')
     
    
    if os.path.exists(config_file_path):
        cfg = ConfigParser.ConfigParser()
        cfg.read(config_file_path)
        
        if cfg.has_section('database'):
            if cfg.has_option('database', 'engine'):
                db_engine = getattr(DB_ENGINE, cfg.get('database', 'engine'))
            
            if cfg.has_option('database', 'host'):
                db_host = cfg.get('database', 'host')
            
            if cfg.has_option('database', 'schema'):
                db_name = cfg.get('database', 'schema')
            
            if cfg.has_option('database', 'user'):
                db_user = cfg.get('database', 'user')
            
            if cfg.has_option('database', 'password'):
                db_password = cfg.get('database', 'password')
            
            if cfg.has_option('importing', 'mode'):
                batch_mode = cfg.get('importing', 'mode')
                
                if batch_mode.lower() in ('batch', 'auto'):
                    batch_mode = True
            
            if cfg.has_option('importing', 'comment'):
                module_comment = cfg.get('importing', 'comment')
            
            if cfg.has_option('importing', 'process_sections'):
                process_sections = cfg.get('importing', 'process_sections')
                
                if process_sections.lower() in ('no', 'false'):
                    process_sections = False
                else:
                    process_sections = True
                
    
    if None in (db_engine, db_host, db_name, db_user, db_password):
    
        (db_engine, db_host, 
        db_name, db_user, 
        db_password) = query_configuration()    
        
        if None in (db_engine, db_host, db_name, db_user, db_password):
            log_message('User cancelled the exporting.')
            return
            
    failed = False
    try:
        sqlexporter = SQLExporter(arch, db_engine, db=db_name,
                user=db_user, passwd=db_password, host=db_host, use_new_schema=USE_NEW_SCHEMA)
    except ImportError:
        print "Error connecting to the database, error importing required module: %s" % sys.exc_info()[0]
        failed = True
    except Exception:
        print "Error connecting to the database, Reason: %s" % sys.exc_info()[0]
        failed = True

    if failed:
        # Can't connect to the database, indicate that to BinNavi
        if batch_mode is True:
            idc.Exit(FATAL_CANNOT_CONNECT_TO_DATABASE)
        else:
            return
    
    if not sqlexporter.is_database_ready():
        
        if batch_mode is False:
            result = idc.AskYN(1, 'Database has not been initialized yet. Do you want to create now the basic tables? (This step is performed only once)')
        else:
            result = 1
            
        if result == 1:
            sqlexporter.init_database()
        else:
            log_message('User requested abort.')
            return
    
    iteration = os.environ.get('EXPORT_ITERATION', None)
    module_id = os.environ.get('MODULE_ID', None)
        
    if iteration is None and module_id == None:
        # Export manually
        print "Exporting manually ..."
        iteration = -1
        sqlexporter.set_callgraph_only(False)
        sqlexporter.set_exporting_manually(True)
        status = sqlexporter.new_module(
            idc.GetInputFilePath(), arch.get_architecture_name(), idaapi.get_imagebase(), module_comment, batch_mode)
            
    elif iteration is not None and module_id is not None:
        
        # Export the next k functions or the call graph
        sqlexporter.set_exporting_manually(False)
        sqlexporter.set_callgraph_only(int(iteration) == -1)
        sqlexporter.set_module_id(int(module_id))
        status = True
        
    else:
        
        sqlexporter.set_exporting_manually(False)
        status = sqlexporter.new_module(
            idc.GetInputFilePath(), arch.get_architecture_name(), idaapi.get_imagebase(), module_comment, batch_mode)
        sqlexporter.set_callgraph_only(False)
        
    if status is False:
        log_message('Export aborted')
        return
    elif status is None:
        log_message('The database appears to contain data exported with different schemas, exporting not allowed.')
        if batch_mode:
            idc.Exit(FATAL_INVALID_SCHEMA_VERSION)
    
    instrumentation = Instrumentation()
    
    instrumentation.new_function_callable(sqlexporter.process_function)
    instrumentation.new_packet_callable(sqlexporter.process_packet)
    instrumentation.new_section_callable(sqlexporter.process_section)
    
    
    tm_start = time.time()
    
    already_imported = sqlexporter.db.get_already_imported()

    incomplete = process_binary(arch, process_sections, int(iteration), already_imported)
    
    sqlexporter.finish()
    
    log_message('Results: %d functions, %d instructions, %d basic blocks, %d address references' % (
        len(sqlexporter.exported_functions), len(sqlexporter.exported_instructions),
        sqlexporter.basic_blocks_next_id-1, sqlexporter.address_references_values_count ))
        
    log_message('Results: %d expression substitutions, %d operand expressions, %d operand tuples' % (
        sqlexporter.expression_substitutions_values_count, sqlexporter.operand_expressions_values_count,
        sqlexporter.operand_tuples___operands_values_count ) )
        
        
    log_message('Exporting completed in %s' % get_time_delta_string())
    
    # If running in batch mode, exit when done
    if batch_mode:
        if incomplete:
            shiftedModule = (sqlexporter.db.module_id << 0x10) | 0xFF
        
            idc.Exit(shiftedModule)
        elif not sqlexporter.callgraph_only:
            shiftedModule = (sqlexporter.db.module_id << 0x10) | 0xFE
    
            idc.Exit(shiftedModule)
        else:
            idc.Exit(0)
Esempio n. 6
0
	def setUp(self):
		self._instrumentation = Instrumentation()
class TestInstrumentationToTestResultTransformer(unittest.TestCase):
	SUCCESS = 0
	ERROR = -1
	FAIL = -2
	
	def setUp(self):
		self._instrumentation = Instrumentation()
		
	def _addTestRun(self, className, methodName, result):
		status = Status()
		status['class'] = className
		status['test'] = methodName
		status.statusCode = 1
		self._instrumentation.addStatus(status)
		
		status = Status()
		status['class'] = className
		status['test'] = methodName
		status.statusCode = result
		self._instrumentation.addStatus(status)

	def _addSuccessfulTestRun(self, className, methodName):
		self._addTestRun(className, methodName, self.SUCCESS)
	
	def _addFailingTestRun(self, className, methodName, stack):
		self._addTestRun(className, methodName, self.FAIL)
		self._instrumentation.statuses()[-1]['stack'] = stack
	
	def _addErroringTestRun(self, className, methodName, stack):
		self._addTestRun(className, methodName, self.ERROR)
		self._instrumentation.statuses()[-1]['stack'] = stack

	def assertTestSuite(self, suite, name, package):
		self.assertEqual(suite.name, name)
		self.assertEqual(suite.package, package)
	
	def assertTestCase(self, case, method):
		self.assertEqual(case.name, method)

	PACKAGE = 'com.example'
	CLASS_NAME = 'TestClass'
	FULL_CLASS = '.'.join((PACKAGE, CLASS_NAME))
	METHOD = 'testMethod'
	
	def testOneSucceedingTestMethod(self):
		self._addSuccessfulTestRun(self.FULL_CLASS, self.METHOD)
		
		testResults = Transform(self._instrumentation)
		
		self.assertTestSuite(testResults[0], self.FULL_CLASS, self.PACKAGE)
		self.assertTestCase(testResults[0].testCases[0], self.METHOD)

	FAIL_REASON = 'frame1'
	STACK = '\n'.join((FAIL_REASON, 'frame2'))

	def testOneFailingTestMethod(self):
		self._addFailingTestRun(self.FULL_CLASS, self.METHOD, self.STACK)
		
		testResults = Transform(self._instrumentation)
		
		testSuite = testResults[0]
		testCase = testSuite.testCases[0]
		self.assertTrue(testCase.isFailing())
		self.assertEqual(testCase.failMessage, self.FAIL_REASON)
		self.assertEqual(testCase.failStack, self.STACK)

	METHOD2 = 'testMethod2'
	
	def testTwoSucceedingTestMethods(self):
		self._addSuccessfulTestRun(self.FULL_CLASS, self.METHOD)
		self._addSuccessfulTestRun(self.FULL_CLASS, self.METHOD2)
		
		testResults = Transform(self._instrumentation)
		
		self.assertTestCase(testResults[0].testCases[0], self.METHOD)
		self.assertTestCase(testResults[0].testCases[1], self.METHOD2)
	
	def testOneErroringTestMethod(self):
		self._addErroringTestRun(self.FULL_CLASS, self.METHOD, self.STACK)
		
		testResults = Transform(self._instrumentation)
		
		testSuite = testResults[0]
		testCase = testSuite.testCases[0]
		self.assertTrue(testCase.isErroring())
		self.assertEqual(testCase.errorMessage, self.FAIL_REASON)
		self.assertEqual(testCase.errorStack, self.STACK)
	
	CLASS_NAME2 = 'TestClass2'
	FULL_CLASS2 = '.'.join((PACKAGE, CLASS_NAME2))
	
	def testTwoTestSuites(self):
		self._addSuccessfulTestRun(self.FULL_CLASS, self.METHOD)
		self._addSuccessfulTestRun(self.FULL_CLASS2, self.METHOD)
		
		testResults = Transform(self._instrumentation)
		
		self.assertTestSuite(testResults[0], self.FULL_CLASS, self.PACKAGE)
		self.assertTestCase(testResults[0].testCases[0], self.METHOD)

		self.assertTestSuite(testResults[1], self.FULL_CLASS2, self.PACKAGE)
		self.assertTestCase(testResults[1].testCases[0], self.METHOD)