def print_to_screen(self, func):
            print "-------------"
            print "func %x:" % (func.start)

            opcodes = dict()
            calls = []

            if func.num_calls != 0:
                print "Function_address:", func.start,
                miss_rate = func.num_missed_calls / (func.num_calls * 1.0)
                print "miss_rate", miss_rate * 100

            for instr in func.instrs:
                if isinstance(instr, InstrCall):
                    if isinstance(instr.target, int) or isinstance(
                            instr.target, long):
                        if not instr.target in calls:
                            calls.append(instr.target)
                    elif isinstance(instr.target, Op) and instr.target.val:
                        if not instr.target.val in calls:
                            calls.append(instr.target.val)

                opcode = instr.opcode
                size = instr.size
                prefix = instr.prefixes
                mnem = instr.get_instr()

                if mnem is None:
                    continue

                if opcode == '':
                    continue
                if prefix == '':
                    prefix = chr(0x0)
                if (prefix, opcode, size, mnem) in opcodes:
                    opcodes[(prefix, opcode, size, mnem)] += 1
                else:
                    opcodes[(prefix, opcode, size, mnem)] = 1

            for call in calls:
                if isinstance(call, int) or isinstance(call, long):
                    print "    call: %x" % (call)
                else:
                    call_addr = None
                    for addr, sym in codes.dynsyms.items():
                        if sym.name == call:
                            call_addr = sym.value
                            break
                    if call_addr:
                        print "    call: %s (%x)" % (call, call_addr)
                    else:
                        print "    call: %s" % (call)

            for (prefix, opcode, size, mnem), count in opcodes.items():
                print prefix.encode('hex'), opcode.encode(
                    'hex'), size, mnem, count
def analysis_binary_instr(sql, binary, pkg_id, bin_id):
    codes = get_callgraph(binary)

    condition = 'pkg_id=' + Table.stringify(
        pkg_id) + ' and bin_id=' + Table.stringify(bin_id)
    condition_unknown = condition + ' and known=False'
    sql.delete_record(tables['binary_call'], condition)
    sql.delete_record(tables['binary_call_unknown'], condition_unknown)
    sql.delete_record(tables['binary_opcode_usage'], condition)

    for func in codes.funcs:
        opcodes = dict()
        calls = []

        for bb in func.bblocks:
            for instr in bb.instrs:
                if isinstance(instr, InstrCall):
                    if isinstance(instr.target, int) or isinstance(
                            instr.target, long):
                        if not instr.target in calls:
                            calls.append(instr.target)
                    elif isinstance(instr.target, Op) and instr.target.val:
                        if not instr.target.val in calls:
                            calls.append(instr.target.val)

                opcode = instr.opcode
                size = instr.size
                prefix = instr.prefixes
                mnem = instr.get_instr()

                if opcode == '':
                    continue
                if prefix == '':
                    prefix = chr(0x0)
                if (prefix, opcode, size, mnem) in opcodes:
                    opcodes[(prefix, opcode, size, mnem)] += 1
                else:
                    opcodes[(prefix, opcode, size, mnem)] = 1

        for call in calls:
            values = dict()
            values['pkg_id'] = pkg_id
            values['bin_id'] = bin_id
            values['func_addr'] = func.entry
            if isinstance(call, int) or isinstance(call, long):
                values['call_addr'] = call
            else:
                for addr, sym in codes.dynsyms.items():
                    if sym.name == call:
                        values['call_addr'] = sym.value
                        break
                values['call_name'] = call
            sql.append_record(tables['binary_call'], values)

        for (prefix, opcode, size, mnem), count in opcodes.items():
            values = dict()
            values['pkg_id'] = pkg_id
            values['bin_id'] = bin_id
            values['func_addr'] = func.entry
            values['prefix'] = int(prefix.encode('hex'), 16)
            values['opcode'] = int(opcode.encode('hex'), 16)
            values['size'] = size
            values['mnem'] = mnem
            values['count'] = count
            try:
                sql.append_record(tables['binary_opcode_usage'], values)
            except Exception as e:
                logging.info(e)
                logging.info(prefix.encode('hex'))
                logging.info(opcode)
                logging.info(int(opcode.encode('hex'), 16))
                logging.info(size)
                logging.info(mnem)
                logging.info(count)
                continue
        def insert_into_db(self, func, sql, pkg_id, bin_id):
            if sql == None or pkg_id == None or bin_id == None:
                logging.info("sql, pkg_id or bin_id was None??")
                traceback.print_exc()
                return

            opcodes = dict()
            calls = []
            if func.num_calls != 0:
                mrvalues = dict()
                mrvalues['pkg_id'] = pkg_id
                mrvalues['bin_id'] = bin_id
                mrvalues['func_addr'] = func.start
                miss_rate = func.num_missed_calls / (func.num_calls * 1.0)
                mrvalues['miss_rate'] = miss_rate * 100
                sql.append_record(tables['binary_call_missrate'], mrvalues)

            for instr in func.instrs:
                if isinstance(instr, InstrCall):
                    if isinstance(instr.target, int) or isinstance(
                            instr.target, long):
                        if not instr.target in calls:
                            calls.append(instr.target)
                    elif isinstance(instr.target, Op) and instr.target.val:
                        if not instr.target.val in calls:
                            calls.append(instr.target.val)
                opcode = instr.opcode
                size = instr.size
                prefix = instr.prefixes
                mnem = instr.get_instr()
                if mnem is None:
                    continue

                if opcode == '':
                    continue
                if prefix == '':
                    prefix = chr(0x0)
                if (prefix, opcode, size, mnem) in opcodes:
                    opcodes[(prefix, opcode, size, mnem)] += 1
                else:
                    opcodes[(prefix, opcode, size, mnem)] = 1

            for call in calls:
                values = dict()
                values['pkg_id'] = pkg_id
                values['bin_id'] = bin_id
                values['func_addr'] = func.start
                if isinstance(call, int) or isinstance(call, long):
                    values['call_addr'] = call
                else:
                    for addr, sym in codes.dynsyms.items():
                        if sym.name == call:
                            values['call_addr'] = sym.value
                            break
                    values['call_name'] = call
                sql.append_record(tables['binary_call'], values)

            for (prefix, opcode, size, mnem), count in opcodes.items():
                values = dict()
                values['pkg_id'] = pkg_id
                values['bin_id'] = bin_id
                values['func_addr'] = func.start
                values['prefix'] = int(prefix.encode('hex'), 16)
                values['opcode'] = int(opcode.encode('hex'), 16)
                values['size'] = size
                values['mnem'] = mnem
                values['count'] = count
                try:
                    sql.append_record(tables['binary_opcode_usage'], values)
                except Exception as e:
                    logging.info(e)
                    logging.info(prefix.encode('hex'))
                    logging.info(opcode)
                    logging.info(int(opcode.encode('hex'), 16))
                    logging.info(size)
                    logging.info(mnem)
                    logging.info(count)
                    continue
                if prefix == '':
                    prefix = chr(0x0)
                if (prefix, opcode, size, mnem) in opcodes:
                    opcodes[(prefix, opcode, size, mnem)] += 1
                else:
                    opcodes[(prefix, opcode, size, mnem)] = 1

        for call in calls:
            if isinstance(call, int) or isinstance(call, long):
                print "    call: %x" % (call)
            else:
                call_addr = None
                for addr, sym in codes.dynsyms.items():
                    if sym.name == call:
                        call_addr = sym.value
                        break
                if call_addr:
                    print "    call: %s (%x)" % (call, call_addr)
                else:
                    print "    call: %s" % (call)

        for (prefix, opcode, size, mnem), count in opcodes.items():
            print prefix.encode('hex'), opcode.encode('hex'), size, mnem, count
        print "End of Function"
        print "----------------------------------------"

    print "-----------"
    print "Dynamic Symbols: %d" % (len(codes.dynsyms))
    print "Functions: %d" % (codes.nfuncs)
    print "Basic Blocks: %d" % (codes.nbblocks)