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)
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