Exemplo n.º 1
0
def add_enums(function):
    """ Add standard enums from parsed MSDN documentation for all imported
    library calls and their arguments.

    Arguments:
    function -- function object
    """
    enum_count = 0
    for argument in function.arguments:
        # Add standard enums
        if not argument.enums:
            g_logger.debug(' No standard constants available for %s' %
                           argument.name)
        else:
            for enum in argument.enums:
                g_logger.debug('  Importing enum %s for argument %s' %
                               (enum, argument.name))
                if idc.import_type(-1, enum) != idaapi.BADADDR:
                    g_logger.debug('  ' + enum + ' ' +
                                   hex(idc.get_enum(enum)) +
                                   ' added successfully')
                    enum_count = enum_count + 1
                else:
                    g_logger.debug('  Could not add ' + enum)

        if not argument.constants:
            # No constants for this argument
            continue

        argument.name = argument.name
        function.name = function.name

        # Add constant descriptions
        for constant in argument.constants:
            if constant.name == 'NULL':
                # Create unique name, so we can add descriptive comment to it
                constant.name = 'NULL_{}_{}'.format(argument.name,
                                                    function.name)
                # Add custom enum for NULL values if it does not exist yet
                enumid = idc.get_enum(NULL_ENUM_NAME)
                if enumid == idaapi.BADADDR:
                    enumid = idc.add_enum(-1, NULL_ENUM_NAME,
                                          idaapi.hex_flag())
                idc.add_enum_member(enumid, constant.name, 0, -1)
                constid = idc.get_enum_member_by_name(constant.name)
                idc.set_enum_member_cmt(constid,
                                        format_comment(constant.description),
                                        False)
            else:
                constid = idc.get_enum_member_by_name(constant.name)
                if constid:
                    if idc.set_enum_member_cmt(
                            constid, format_comment(constant.description),
                            False):
                        g_logger.debug('    Description added for %s' %
                                       constant.name)
                    else:
                        g_logger.debug('    No description added for %s' %
                                       constant.name)
    return enum_count
Exemplo n.º 2
0
 def set_enum_member(name, member, value):
     ok = idc.add_enum_member(idc.get_enum(str(name)), str(member),
                              int(value), -1)
     if not ok:
         if idaapi.get_enum_member_by_name(str(member)) == idaapi.BADADDR:
             print("Could not add enum member {member} at {name}".format(
                 name=name, member=member))
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
0
 def is_in_ida(symbol_type, symbol_name):
     if symbol_type == "Enumeration":
         return idc.get_enum(
             IDAtools.clean_name(symbol_name)) != idaapi.BADADDR
     else:
         if str(IDAtools.clean_name(symbol_name)) in IDAtools.MAPPED_IDS:
             return True
         else:
             IDAtools.MAPPED_IDS[str(
                 IDAtools.clean_name(symbol_name))] = "1"
             return False
Exemplo n.º 6
0
def get_enum_const_name(enum_name, const_value):
    """ Name of the constant value of the enum or empty string if enum or const does not exist """
    if not enum_name:
        return ""
    enum_id = idc.get_enum(enum_name)
    if enum_id == BADADDR:
        log.warn("Enum not found %s", enum_name)
        return ""
    const_id = idc.get_enum_member(enum_id, const_value, 0, ida_enum.DEFMASK)
    if const_id == BADADDR:
        log.warn("Enum const not found %s, 0x%X", enum_name, const_value)
        return ""
    return idc.get_enum_member_name(const_id)
Exemplo n.º 7
0
def readStructMacro(path):
    """
    Parses struct macros and updates a corresponding enum with their values
    :param path: the path to the file containing the macros
    :return:
    """
    # parse macro file
    macroFile = open(path)
    members = []
    structName = ''
    for line in macroFile.readlines():
        if line.lstrip().startswith('\struct_entry'):
            if ', ' in line:
                name = line[line.index(')')+1 : line.index(',')]
                size = line[line.index(', ')+2 :].rstrip()
                if '//' in size:
                    size = size[:size.index('//')].rstrip()
                if size.startswith('0x'):
                    size = int(size, 16)
                else:
                    size = int(size)
            else:
                name = line[line.index(')')+1 :].rstrip()
                if '//' in name:
                    name = name[:name.index('//')].rstrip()
                size = 0
            members.append((name, size))
        if line.startswith('def_struct_offsets'):
            structName = line[line.index(', ')+2:].rstrip()
    print('parsed struct "' + structName + '"')

    # read into enum
    enumId = idc.get_enum(structName)
    if enumId == idaapi.BADADDR:
        enumId = idc.add_enum(idaapi.BADADDR, structName, idaapi.decflag())

    # parse all enum members, needed to know what member to replace
    offset = 0x00
    for member, size in members:
        enumMember = idc.get_enum_member(enumId, offset, 0, ida_enum.DEFMASK)
        if enumMember == idaapi.BADADDR:
            print("why???")
            idc.add_enum_member(enumId, structName + member, offset, idaapi.BADADDR)
        elif idc.get_enum_member_name(enumMember) != structName + member:
            # update member name, if value already exists
            print('\tupdate %s // 0x%X' % (structName + member, offset))
            idc.set_enum_member_name(enumMember, structName + member)

        offset += size
    return True