Пример #1
0
def markStructFromToolkit(func_ea, structOff, structName):
    f = Function.Function(func_ea)
    toolkitMovs = FuncAnalyzer.traceRegVar(f.func_ea, f.func_ea + f.getSize(withPool=False), 10, 0)
    for trace_ea in toolkitMovs:
        # lock into the register in question
        insn = Instruction.Insn(trace_ea)
        if insn.isComputationalInsn():
            regWrites = FuncAnalyzer.traceRegWrites(f.func_ea, f.func_ea + f.getSize(withPool=False),
                                                    insn.ops[0].reg)
            # TODO: traceRegWrites messes up insn
            insn = Instruction.Insn(trace_ea)
            # find the relevent register variable to trace
            regVarIdx = FuncAnalyzer.getRegWriteIndex(trace_ea, regWrites)
            insn = Instruction.Insn(trace_ea)
            # trace all reads to this register variable in particular
            # print('args', f.func_ea, f.func_ea + f.getSize(withPool=False),
            #                                           insn.ops[0].reg, regVarIdx)
            toolkitAccesses = FuncAnalyzer.traceRegVar(f.func_ea, f.func_ea + f.getSize(withPool=False),
                                                      insn.ops[0].reg, regVarIdx)
            # those now will represent all registers R10 moved to, and thus, all of those accesses
            # are accesses to the R10 struct
            for access in toolkitAccesses:
                # now mark with Toolkit enum
                accessInsn = Instruction.Insn(access)
                if accessInsn.ops[1].type == ida_ua.o_displ:
                    if accessInsn.ops[1].addr == structOff:
                        # print(hex(access), idc.GetDisasm(access))

                        structAcccesses = FuncAnalyzer.traceRegVar(f.func_ea, f.func_ea + f.getSize(withPool=False),
                                                                   accessInsn.ops[0].reg, regVarIdx+1)
                        for structAccess in structAcccesses:
                            # print(hex(structAccess), idc.GetDisasm(structAccess))
                            idc.op_enum(structAccess, 1, idc.get_enum(structName), 0)
    return True
Пример #2
0
def rename_constant(arg_ea, fct_name, arg_name, arg_enums):
    """ Rename constants to values from standard enumerations. """
    instruction = idc.print_insn_mnem(arg_ea)
    if instruction == 'push':
        op_num = 0
    elif instruction == 'mov':
        op_num = 1
    else:
        raise RenamingException('Constant: unhandled instruction ' +
                                instruction)

    op_val = idc.get_operand_value(arg_ea, op_num)
    # NULL
    if op_val == 0:
        targetid = idc.get_enum_member_by_name('NULL_{}_{}'.format(
            arg_name, fct_name))
        serial = 0
        enumid = idc.get_enum(NULL_ENUM_NAME)
        constid = idc.get_enum_member(enumid, 0, serial, -1)
        while constid != idaapi.BADADDR:
            if constid == targetid:
                idc.op_enum(arg_ea, op_num, enumid, serial)
                return
            serial = serial + 1
            constid = idc.get_enum_member(enumid, 0, serial, -1)

    # All other constants
    op_type = idc.get_operand_type(arg_ea, op_num)
    if op_type == idaapi.o_imm:
        # only one choice
        if len(arg_enums) == 1:
            enumid = idc.get_enum(arg_enums[0])
            idc.op_enum(arg_ea, op_num, enumid, 0)
            return

        for enum in arg_enums:
            enumid = idc.get_enum(enum)
            constid = get_constant_id(enumid, op_val)
            if constid == idaapi.BADADDR:
                # Not in this enum
                continue
            else:
                # Found the right enum
                idc.op_enum(arg_ea, op_num, enumid, 0)
                return
Пример #3
0
def OpEnum(ea, n, enumid):
    return idc.op_enum(ea, n, enumid, 0)
Пример #4
0
    def activate(self, ctx):
        # print("ctx.cur_ea : 0x%x" % ctx.cur_ea)
        # print("ctx.cur_extracted_ea : 0x%x" % ctx.cur_extracted_ea)

        # Extract selected enum
        instruction = idc.GetDisasm(ctx.cur_ea)
        selection = ctx.cur_extracted_ea

        # correctly parse the selected value as int (hex or decimal)
        # since ctx.cur_extracted_ea has a bug (IDA always consider
        # the selected value as hex)
        if instruction.find("{0:X}h".format(selection)) != -1:
            # print("hex value found !")
            selected_value = ctx.cur_extracted_ea
        elif instruction.find("{0:d}".format(selection)) != -1:
            # print("int value found !")
            selected_value = int("%x" % ctx.cur_extracted_ea)
        else:
            # print("nothing selected !")
            return 1

        # next power of two for masking
        selected_value_mask = self.shift_bit_length(selected_value) - 1
        # print("selected_value : 0x%X" % selected_value)
        # print("selected_value mask : 0x%X" % selected_value_mask)

        # query magnum db
        url = SearchMagicNumber.MAGNUMDB_QUERY.format(
            value=selected_value, key=SearchMagicNumber.MAGNUMDB_KEY)
        answer = urlopen(url)
        results = json.loads(answer.read())

        # Let the user select the best answer
        c = ChooseMagicNumber(selected_value, results["Items"])
        selected_index = c.Show(modal=True)
        if selected_index < 0:
            return

        # Apply the newly found enum
        selected_item = results["Items"][selected_index]
        selected_name = selected_item["Title"].encode('ascii')
        selected_value = int(selected_item["Value"])

        # serial is important since several entries can have the same value
        entryid, serial = self._manager.add_magnumdb_entry(
            selected_name, selected_value)

        # locate the operand where to apply the enum
        insn = idautils.DecodeInstruction(ctx.cur_ea)

        try:
            # ida < 7.4
            operands = insn.Operands
        except AttributeError:
            # ida 7.4
            operands = insn.ops

        for op in filter(lambda o: o.type == idaapi.o_imm, operands):

            # heuristic : the selected immediate is the first in the instruction with
            # the same exact value (we are using a mask since IDA loves to set FFFFFFFF to high words)
            if op.value & selected_value_mask == selected_value:
                # Apply the enum
                op_enum(ctx.cur_ea, op.n, idaapi.get_enum("_IDA_MAGNUMDB"),
                        serial)
                break

        return 1