예제 #1
0
def ida_main():
    import idc

    filepath = idc.AskFile(0, "*.map", "Load a Dolphin emulator symbol map")
    if filepath is None:
        return
    symbol_map = load_dolphin_map(filepath)

    for symbol in symbol_map:
        addr = int(symbol.vaddr, 16)
        size = int(symbol.size, 16)
        idc.MakeUnknown(addr, size, 0)
        if symbol.section in [".init", ".text"]:
            idc.MakeCode(addr)
            success = idc.MakeFunction(
                addr, idc.BADADDR if not size else (addr + size))
        else:
            success = idc.MakeData(addr, idc.FF_BYTE, size, 0)

        if not success:
            idc.Message("Can't apply properties for symbol:"
                        " {0.vaddr} - {0.name}\n".format(symbol))

        flags = idc.SN_NOCHECK | idc.SN_PUBLIC
        if symbol.name.startswith("zz_"):
            flags |= idc.SN_AUTO | idc.SN_WEAK
        else:
            flags |= idc.SN_NON_AUTO
        idc.MakeNameEx(addr, symbol.name, flags)
예제 #2
0
    def make_data(self, object_version, address):
        size = 0
        try:
            size = object_version.get_size()
        except KeyError:
            pass
        flags = None
        try:
            flags = object_version.get_object_flags()
        except KeyError:
            pass

        if size == 0:
            idc.MakeUnkn(address, idc.DOUNK_EXPAND)
        else:
            if flags is not None:
                if idc.isASCII(flags):
                    try:
                        str_type = object_version.get_string_type()
                        YaToolIDATools.check_and_set_str_type(str_type)
                    except KeyError:
                        pass
                    idc.MakeStr(address, address + size)
                    idc.SetFlags(address, flags)

                if idc.isStruct(flags):
                    found = False
                    for xref_offset_operand, xref_id_attr in object_version.get_xrefed_id_map(
                    ).iteritems():
                        (xref_offset, xref_operand) = xref_offset_operand
                        for xref_hash, xref_attrs in xref_id_attr:

                            if xref_hash in self.struc_ids:
                                struc_id = self.struc_ids[xref_hash]
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "making unknown from 0x%08X to 0x%08X"
                                        % (address, address + size))
                                idaapi.do_unknown_range(
                                    address, size, idc.DOUNK_DELNAMES)

                                #   idc.MakeUnkn(address, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                #   for i in xrange(1, size):
                                #       MakeName(address + i, "")
                                #       idc.MakeUnkn(address + i, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                # idc.MakeStructEx uses idaapi.doStruct (but asks for name while
                                # we already have the struc id)
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "Making struc at %s : %s (sizeof(%s)=0x%08X, size=0x%08X, flags=0x%08X"
                                        % (self.yatools.address_to_hex_string(
                                            address),
                                           self.yatools.address_to_hex_string(
                                               struc_id),
                                           idaapi.get_struc_name(struc_id),
                                           idc.GetStrucSize(struc_id), size,
                                           flags))
                                idc.SetCharPrm(idc.INF_AUTO, True)
                                idc.Wait()
                                if idaapi.doStruct(address, size,
                                                   struc_id) == 0:
                                    if DEBUG_EXPORTER:
                                        logger.warning("Making struc failed")
                                idc.SetCharPrm(idc.INF_AUTO, False)
                                #                                     idc.SetFlags(address, flags)
                                found = True
                    else:
                        logger.error(
                            "bad struc flags : idc.isStruct is true but no xref available for object %s"
                            % self.hash_provider.hash_to_string(
                                object_version.get_id()))
                    if not found:
                        logger.error(
                            "bad struc flags : idc.isStruct is true "
                            "but no struc available for object %s (%s)" %
                            (self.hash_provider.hash_to_string(
                                object_version.get_id()),
                             object_version.get_name()))
                else:
                    idc.MakeData(address, flags & (idc.DT_TYPE | idc.MS_0TYPE),
                                 size, 0)

            else:
                idc.MakeData(address, idc.FF_BYTE, size, 0)

        self.make_name(object_version, address, False)

        self.set_type(object_version, address)
    def locateLocalConstants(self, scs, sds):
        """Locate and define all of the local strings / numeric constants, that match our observed pattern.

        Args:
            scs (list): List of (sark) code segments.
            sds (list): List of (sark) data segments.
        """
        self._analyzer.logger.info(
            "Locating local strings / constants in the code sections")
        for sc in scs:
            cur_ea = pad(sc.startEA, self._local_alignment)
            while cur_ea < sc.endEA:
                # check for a data constant
                if self.isDataConstant(cur_ea):
                    # check for a string (refs already checked)
                    if self._analyzer.str_identifier.isLocalAsciiString(
                            cur_ea, check_refs=False):
                        length = self._analyzer.str_identifier.defineAsciiString(
                            cur_ea)
                        padded_length = pad(length, self._local_alignment)
                        if padded_length != length:
                            idc.MakeUnknown(cur_ea + length,
                                            padded_length - length, 0)
                            idc.MakeData(cur_ea + length, 0,
                                         padded_length - length, 0)
                        cur_ea += padded_length
                    # This means it is a constant
                    else:
                        if self._local_pad is None:
                            idc.MakeData(cur_ea, 0, self._local_alignment, 0)
                        else:
                            # check the size of the constant using the byte padding
                            for offset in xrange(self._local_alignment - 1, -1,
                                                 -1):
                                if idc.Byte(cur_ea +
                                            offset) != self._local_pad:
                                    break
                            # prepare the bytes
                            idc.MakeUnknown(cur_ea, self._local_alignment, 0)
                            # the data constant - try to make it pretty
                            if offset + 1 == 2:
                                idc.MakeWord(cur_ea)
                            elif offset + 1 == 4:
                                idc.MakeDword(cur_ea)
                            elif offset + 1 == 8:
                                idc.MakeQword(cur_ea)
                            else:
                                idc.MakeData(cur_ea, 0, offset + 1, 0)
                            # the padding
                            idc.MakeData(cur_ea + offset + 1, 0,
                                         self._local_alignment - offset + 1, 0)
                            # Now check for a pointer (only supports code pointers for now)
                            if offset + 1 == self._analyzer.addressSize():
                                value = self._analyzer.parseAdderss(cur_ea)
                                # only support pointers inside our local segment (more probable)
                                if sc.startEA <= value and value < sc.endEA:
                                    self._analyzer.markCodePtr(
                                        cur_ea, value, aggressive=False)
                                # try a pointer to a declared string
                                else:
                                    for sd in sds:
                                        if sd.startEA <= value and value <= sd.endEA:
                                            line = sark.Line(value)
                                            if line.is_string and line.startEA == value:
                                                self._analyzer.markDataPtr(
                                                    cur_ea,
                                                    value,
                                                    aggressive=False)
                                            break
                        # now move onward
                        cur_ea += self._local_alignment
                # found nothing, move on
                else:
                    cur_ea += self._local_alignment