示例#1
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
示例#2
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)
示例#3
0
	def setUp(self):
		self._instrumentation = Instrumentation()