Пример #1
0
def read_mem(addr, forced_addr_sz=None, read_only=False):
    global ADDR_SZ

    if not read_only:
        if forced_addr_sz:
            idc.MakeUnknown(addr, forced_addr_sz, idc.DOUNK_SIMPLE)
        else:
            idc.MakeUnknown(addr, ADDR_SZ, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if forced_addr_sz == 2:
        if not read_only:
            idc.MakeWord(addr)
            idaapi.autoWait()
        return idc.Word(addr)
    if forced_addr_sz == 4 or ADDR_SZ == 4:
        if not read_only:
            idc.MakeDword(addr)
            idaapi.autoWait()
        return idc.Dword(addr)
    if forced_addr_sz == 8 or ADDR_SZ == 8:
        if not read_only:
            idc.MakeQword(addr)
            idaapi.autoWait()
        return idc.Qword(addr)
Пример #2
0
def create_string(addr, string_len):
    # if idaapi.get_segm_name(addr) is None:
    if idc.get_segm_name(addr) is None:
        common._debug(
            'Cannot load a string which has no segment - not creating string @ 0x%02x'
            % addr)
        return False

    common._debug('Found string load @ 0x%x with length of %d' %
                  (addr, string_len))
    # This may be overly aggressive if we found the wrong area...
    if idc.GetStringType(addr) is not None and idc.GetString(
            addr) is not None and len(idc.GetString(addr)) != string_len:
        common._debug(
            'It appears that there is already a string present @ 0x%x' % addr)
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if idc.GetString(addr) is None and idc.MakeStr(addr, addr + string_len):
        idaapi.autoWait()
        return True
    else:
        # If something is already partially analyzed (incorrectly) we need to MakeUnknown it
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()
        if idc.MakeStr(addr, addr + string_len):
            idaapi.autoWait()
            return True
        common._debug('Unable to make a string @ 0x%x with length of %d' %
                      (addr, string_len))

    return False
    def check_address(address):
        # Checks if given address contains virtual table. Returns True if more than 2 function pointers found
        # Also if table's addresses point to code in executable section, than tries to make functions at that addresses
        if helper.is_code_ea(address):
            return False

        if not idaapi.get_name(address):
            return False

        functions_count = 0
        while True:
            func_address = helper.get_ptr(address)
            # print "[INFO] Address 0x{0:08X}".format(func_address)
            if helper.is_code_ea(func_address) or helper.is_imported_ea(
                    func_address):
                functions_count += 1
                address += const.EA_SIZE
            else:
                segment = idaapi.getseg(func_address)
                if segment and segment.perm & idaapi.SEGPERM_EXEC:
                    idc.MakeUnknown(func_address, 1, idaapi.DOUNK_SIMPLE)
                    if idc.MakeFunction(func_address):
                        functions_count += 1
                        address += const.EA_SIZE
                        continue
                break
            idaapi.autoWait()
        return functions_count
    def markSwitchTables(self, sc, aggressive=True):
        """Help IDA by marking all of the needed information from the observed switch tables.

        Args:
            sc (segment): (sark) code segment in which we are interested right now
            aggressive (bool, optional): True iff the marking operation should be aggressive, see notes. (True by default)

        Notes
        -----
            1. Make sure the switch case jump instruction is indeed a code line
            2. Make sure the jump instruction has a code reference to all of the switch cases
            3. (Aggressive) Make sure each switch table entry is a proper code pointer to it's matching case
            4. (Aggressive) Enforce the correct code type over the entire gap between the minimal and maximal case
        """
        for switch_instr, table_start, table_end in filter(
                lambda x: sc.startEA <= x[0] and x[1] < sc.endEA,
                self._switch_case_entries):
            cases = []
            if not sark.Line(switch_instr).is_code:
                idc.MakeUnknown(switch_instr, self._analyzer.addressSize(), 0)
                idc.MakeCode(switch_instr)
            for ea in xrange(table_start, table_end,
                             self._analyzer.addressSize()):
                entry = self._analyzer.parseAdderss(ea)
                if aggressive:
                    self._analyzer.markCodePtr(ea, entry)
                fixed_entry = self._analyzer.cleanPtr(entry)
                cases.append(fixed_entry)
                idc.add_cref(switch_instr, fixed_entry,
                             idc.XREF_USER | idc.dr_O)
            if aggressive:
                self._analyzer.setCodeType(min(cases), max(cases),
                                           self._analyzer.ptrCodeType(entry))
Пример #5
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)
Пример #6
0
def make_array(ea, size):
    if ea != idc.BADADDR and ea != 0:
        flags = idc.GetFlags(ea)
        if not idc.isByte(flags) or idc.ItemSize(ea) != 1:
            idc.MakeUnknown(ea, 1, idc.DOUNK_SIMPLE)
            idc.MakeByte(ea)
        idc.MakeArray(ea, size)
 def __find_entry(self, iterate_address):
     possible_entry_address = self.__find_entry_jump(iterate_address)
     if possible_entry_address == 0 or possible_entry_address == 1:
         return 0
     elif possible_entry_address == -1:
         print("ERROR.FindingEntry: Issue finding entry from " + format_address(hex(iterate_address)) + \
               " to " + format_address(hex(self.end_address)) + ".")
         return -1
     else:
         following_landing_address = idc.FindBinary(possible_entry_address, idc.SEARCH_DOWN, LANDING_STRIP)
         if following_landing_address == idc.BADADDR or following_landing_address == 0:
             # print("ERROR.FindingEntry: Issue finding landing for " + format_address(hex(possible_entry_address)) + ".")
             # assume end has not yet been reached, will continue to find the correct macro entry
             return 0
         else:
             # unwrap landing strip as it is usually formatted as data
             idc.MakeUnknown(following_landing_address, 2, idc.DOUNK_SIMPLE)
             idc.MakeCode(following_landing_address)
             # apply logging
             possible_jump_location_address = get_jump_destination(possible_entry_address)
             log_oreans_macro_information(possible_entry_address, possible_jump_location_address, following_landing_address)
             self.macros.append([possible_entry_address, possible_jump_location_address, following_landing_address])
             if BUFFER_NOP:
                 nop(possible_entry_address + 5, following_landing_address)
             if BUFFER_HIDE:
                 hide(possible_entry_address + 5, following_landing_address, BUFFER_NAME, BUFFER_START_NAME, BUFFER_END_NAME)
             # change main iterator address with that pass the landing so it will step over macro range
             next_macro_search_range_address = following_landing_address + 5
             return next_macro_search_range_address
Пример #8
0
def apply_struct(ea, name, size):
    sid = idc.GetStrucIdByName(name)
    if (size == -1):
        size = idc.GetStrucSize(sid)

    idc.MakeUnknown(ea, size, idc.DOUNK_DELNAMES)
    idaapi.doStruct(ea, size, sid)

    return size
Пример #9
0
 def define(self):
     """
     Defines the string in the IDB.
     """
     try:
         idc.MakeUnknown(self.startEA, self.byte_length, idc.DOUNK_SIMPLE)
         idaapi.make_ascii_string(self.startEA, self.byte_length, self.string_type)
     except:
         append_debug('Unable to define string at 0x%X' % self.startEA)
Пример #10
0
def read_string(ea):
    s = idc.GetString(ea, -1, idc.ASCSTR_C)
    if s:
        slen = len(s) + 1
        idc.MakeUnknown(ea, slen, idc.DOUNK_SIMPLE)
        idaapi.make_ascii_string(ea, slen, idc.ASCSTR_C)
        return s, ea + slen
    else:
        return s, ea
Пример #11
0
def apply_struct(ea, sid, size):
    if size == -1:
        size = idc.GetStrucSize(sid)

    idc.MakeUnknown(ea, size, idc.DOUNK_DELNAMES)

    idaapi.doStruct(ea, size, sid)

    return size
    def markCodePtr(self, src, dest, aggressive=True):
        """Mark a code pointer from src to dest.

        Args:
            src (int): effective address for the pointer's location
            dest (int): effective address for the pointed code address
            aggressive (bool, optional): True iff should redefine the src & dest (True by default)
        """
        clean_dest = self.cleanPtr(dest)
        if aggressive:
            idc.MakeUnknown(src, self.addressSize(), 0)
        if self.makeAddress(src):
            idc.add_dref(src, clean_dest, idc.XREF_USER | idc.dr_O)
            idc.add_cref(src, clean_dest, idc.XREF_USER | idc.dr_O)
            ida_offset.op_offset(src, 0, idc.REF_OFF32)
            if aggressive:
                idc.MakeUnknown(dest, self.addressSize(), 0)
                idc.MakeCode(self.cleanPtr(dest))
    def delCodePtr(self, src, dest):
        """Delete a code pointer (probably was found to be a False Positive).

        Args:
            src (int) effective address for the pointer's location
            dest (int): effective address for the (assumed) pointed code address
        """
        idc.del_dref(src, dest)
        idc.del_cref(src, dest, 0)
        idc.MakeUnknown(src, self.addressSize(), 0)
    def markDataPtr(self, src, dest, aggressive=True):
        """Mark a data pointer from src to dest.

        Args:
            src (int): effective address for the pointer's location
            dest (int): effective address for the pointed data address
            aggressive (bool, optional): True iff should redefine the src (True by default)
        """
        if aggressive:
            idc.MakeUnknown(src, self.addressSize(), 0)
        if self.makeAddress(src):
            idc.add_dref(src, dest, idc.XREF_USER | idc.dr_O)
            ida_offset.op_offset(src, 0, idc.REF_OFF32)
Пример #15
0
def PatchCall(addr):
    '''
    To improve IDA's analysis, the patch converts call abuse
    into push and jmp instructions. The patched data is saved
    as a comment.
    '''

    if idc.Byte(addr) == 0xE8:
        logger = logging.getLogger(__name__)
        logger.info("Patching push as call @ %x" % addr)
        data_size = idc.Dword(addr + 1)
        if (data_size) >= 0xfe:
            logger.info("Can't patch: 0x%x" % addr)
            return
        fname = idc.GetFunctionName(addr)
        target = idc.GetOperandValue(addr, 0)
        data_addr = addr + idautils.DecodeInstruction(addr).size
        orig_data = idc.Word(data_addr)
        orig_asm = idc.GetDisasm(addr)
        idc.MakeUnknown(addr, target - addr,
                        idaapi.DOUNK_EXPAND | idaapi.DOUNK_DELNAMES)
        idc.PatchByte(addr, 0x68)
        idc.PatchDword(addr + 1, data_addr)
        idc.PatchByte(data_addr, 0xEB)
        idc.PatchByte(data_addr + 1, data_size - 2)
        # idaapi.analyze_area(addr, data_addr + 2)
        uksize = 0
        if fname != idc.GetFunctionName(target) and fname is not None:
            while uksize < 32:
                x = idautils.DecodeInstruction(target + uksize)
                if x is None:
                    break
                uksize += x.size
            idc.MakeUnknown(target, uksize,
                            idaapi.DOUNK_EXPAND | idaapi.DOUNK_DELNAMES)
            # idaapi.analyze_area(target, target + uksize + 1)
        idc.MakeComm(addr, "Original: " + orig_asm)
        idc.MakeComm(data_addr, "Original: %x" % orig_data)
Пример #16
0
def make_str(address):
    """Calculate the length, undefine and make an ascii string."""
    # calculate the length, with a hardcoded maximum length
    ret = ''
    for offset in xrange(MAX_STRING_LENGTH):
        ch = idc.GetOriginalByte(address + offset)
        if not ch:
            break

        ret += chr(ch)

    idc.MakeUnknown(address, offset, idc.DOUNK_SIMPLE)
    idc.MakeStr(address, address + offset)
    return ret
Пример #17
0
    def dbg_trace(self, tid, ea):
        if ea >> 12 == 0x18f:
            self.ctx = 3
        if self.ctx == 0:
            return 1
        self.ctx -= 1

        idc.RefreshDebuggerMemory()
        idc.MakeUnknown(ea, 20, 0)
        idc.MakeCode(ea)
        mnem = idc.GetDisasm(ea)
        print(hex(ea), mnem)
        regs = 'eax ebx ecx edx esi edi eip'.split(' ')
        regs = {x: idc.GetRegValue(x) for x in regs}
        self.ins.append(Attributize(None, mnem=mnem, **regs))
        return 1
def define_string(decoded_string):
    '''
    Defines a string object in the IDB for the provided string.

    Input:
        decoded_string - The EncodedString object to define in IDA
    '''
    try:
        idc.MakeUnknown(decoded_string.startEA, decoded_string.byte_length,
                        idc.DOUNK_SIMPLE)
        idaapi.make_ascii_string(decoded_string.startEA,
                                 decoded_string.byte_length,
                                 decoded_string.string_type)
    except:
        append_debug('Unable to define string at 0x%X' %
                     decoded_string.startEA)
Пример #19
0
    def defineAsciiString(self, ea):
        r"""Define an ascii string at the given address.

        Args:
            ea (int): effective start address of the wanted ascii string

        Return Value:
            The length of the defined string + 1 for the '\0' terminator
        """
        content = idc.GetString(ea, -1, -1)
        if not sark.Line(ea).is_string:
            self._analyzer.logger.debug("Defined a unique ascii string at: 0x%x (Length of %d)", ea, len(content) + 1)
        idc.MakeUnknown(ea, len(content) + 1, 0)
        # Backward compatibility is always fun
        if idaapi.IDA_SDK_VERSION <= 700:
            idaapi.make_ascii_string(ea, len(content) + 1, idc.ASCSTR_C)
        else:
            idc.MakeStr(ea, ea + len(content) + 1)
        return len(content) + 1
 def __find_all_usages(self, name, signature):
     sub_instance_counter = 0
     current_address = self.start_address
     while (current_address != idc.BADADDR or
            current_address != 0) and current_address <= self.end_address:
         current_address = idc.FindBinary(current_address, idc.SEARCH_DOWN,
                                          signature)
         if (current_address != idc.BADADDR or current_address != 0
             ) and current_address <= self.end_address:
             sub_usage_name = "oreans_" + name + "_" + str(
                 sub_instance_counter)
             idc.MakeUnknown(current_address, 6, idc.DOUNK_SIMPLE)
             idc.MakeCode(current_address)
             label(sub_usage_name, current_address)
             log_oreans_blacklist_information(sub_usage_name,
                                              current_address)
             self.found_counter += 1
             sub_instance_counter += 1
             current_address += 1
Пример #21
0
def resizeRegion(analyzer, start_ea, end_ea, new_start_ea, new_end_ea):
    """Resize a given code region, according to the new dimensions.

    Args:
        analyzer (instance): analyzer instance to be used
        start_ea (int): effective start address of the original region
        end_ea (int): effective end address of the original region
        new_start_ea (int): effective start address for the new region
        new_end_ea (int): effective end address for the new region
    """
    analyzer.logger.info(
        "Resizing code region of type %d: 0x%x (0x%x) - 0x%x (0x%x)",
        analyzer.codeType(start_ea), new_start_ea, start_ea, end_ea,
        new_end_ea)
    code_type_before = analyzer.codeType(min(start_ea, new_start_ea) - 1)
    code_type_middle = analyzer.codeType(start_ea)
    code_type_after = analyzer.codeType(max(end_ea, new_end_ea))
    # Make sure it will be treated as code
    fix_regions = []
    if new_start_ea < start_ea:
        fix_regions.append((new_start_ea, start_ea))
    elif new_start_ea != start_ea:
        fix_regions.append((start_ea, new_start_ea))
    if end_ea < new_end_ea:
        fix_regions.append((end_ea, new_end_ea))
    elif end_ea != new_end_ea:
        fix_regions.append((new_end_ea, end_ea))
    # Make the changed parts unknown, before re-analyzing them
    for region_start, region_end in fix_regions:
        idc.MakeUnknown(region_start, region_end - region_start, 0)
    # manually set the wanted value over the entire region
    if start_ea < new_start_ea:
        analyzer.setCodeType(start_ea, new_start_ea, code_type_before)
    elif start_ea != new_start_ea:
        analyzer.setCodeType(new_start_ea, start_ea, code_type_middle)
    if end_ea < new_end_ea:
        analyzer.setCodeType(end_ea, new_end_ea, code_type_middle)
    elif end_ea != new_end_ea:
        analyzer.setCodeType(new_end_ea, end_ea, code_type_after)
    # now reanalyze the new section
    for region_start, region_end in fix_regions:
        idaapi.analyze_area(region_start, region_end)
Пример #22
0
def convertRegion(analyzer, start_ea, end_ea):
    """Convert (Cancel) a given code region (change it's code type).

    Args:
        analyzer (instance): analyzer instance to be used
        start_ea (int): effective start address of the region
        end_ea (int): effective end address of the region
    """
    wanted_code_type = analyzer.codeType(end_ea)
    analyzer.logger.info(
        "Converting code region of type %d to %d: 0x%x - 0x%x (%d)",
        analyzer.codeType(start_ea), wanted_code_type, start_ea, end_ea,
        end_ea - start_ea)
    # Make sure it will be treated as code
    idc.MakeUnknown(start_ea, end_ea - start_ea, 0)
    # manually set the wanted value over the entire region
    analyzer.setCodeType(start_ea, end_ea, wanted_code_type)
    # now reanalyze the new section
    idaapi.analyze_area(
        analyzer.alignTransitionAddress(start_ea, wanted_code_type), end_ea)
Пример #23
0
def rename(beg, ptr, make_funcs=True):
    base = beg
    pos = beg + 8  #skip header
    size = ptr.ptr(pos)
    pos += ptr.size
    end = pos + (size * ptr.size * 2)
    print "%x" % end
    while pos < end:
        offset = ptr.ptr(pos + ptr.size)
        ptr.maker(pos)  #in order to get xrefs
        ptr.maker(pos + ptr.size)
        pos += ptr.size * 2
        ptr.maker(base + offset)
        func_addr = ptr.ptr(base + offset)
        if make_funcs == True:
            idc.MakeUnknown(func_addr, 1, idc.DOUNK_SIMPLE)
            idc.MakeFunction(func_addr)
        name_offset = idc.Dword(base + offset + ptr.size)
        name = idc.GetString(base + name_offset)
        name = Utils.relaxName(name)
        Utils.rename(func_addr, name)
Пример #24
0
 def check_address(address):
     # Checks if given address contains virtual table. Returns True if more than 2 function pointers found
     # Also if table's addresses point to code in executable section, than tries to make functions at that addresses
     functions_count = 0
     while True:
         func_address = idaapi.get_64bit(address) if Const.EA64 else idaapi.get_32bit(address)
         flags = idaapi.getFlags(func_address)  # flags_t
         # print "[INFO] Address 0x{0:08X}".format(func_address)
         if idaapi.isCode(flags):
             functions_count += 1
             address += Const.EA_SIZE
         else:
             segment = idaapi.getseg(func_address)
             if segment and segment.perm & idaapi.SEGPERM_EXEC:
                 idc.MakeUnknown(func_address, 1, idaapi.DOUNK_SIMPLE)
                 if idc.MakeFunction(func_address):
                     functions_count += 1
                     address += Const.EA_SIZE
                     continue
             break
         idaapi.autoWait()
     return functions_count
Пример #25
0
def apply_struct(objname, address):
    """Apply a Structure to an address."""
    structure = _struct_by_name(objname)
    size = ctypes.sizeof(structure)

    # it is known
    idc.MakeUnknown(address, size, idc.DOUNK_SIMPLE)
    idc.MakeStruct(address, objname)

    # read the structure and return that data
    data = (idc.GetOriginalByte(x) for x in xrange(address, address + size))
    _ret = structure.from_buffer_copy(''.join(chr(x) for x in data))

    class _Structure:
        pass

    ret = _Structure()
    offset = 0
    for name, typ in structure._fields_:
        # pointer to an ascii string
        if typ == ctypes.c_char_p:
            value = idc.Dword(address + offset)
            setattr(ret, name, make_str(value))
        # pointer to an unicode string
        elif typ == ctypes.c_wchar_p:
            # TODO implement unicode string stuff
            pass
        # this is a pointer to another structure
        elif hasattr(typ, 'contents'):
            _name = _registered_structures[typ._type_][0]
            _addr = idc.Dword(address + offset)
            setattr(ret, name, apply_struct(_name, _addr))
        else:
            setattr(ret, name, getattr(_ret, name))
        offset += ctypes.sizeof(typ)
    return ret
Пример #26
0
    def __seek(self):
        # Method 2 (reversal approach) one of the most accurate methods
        current_address = self.start_address
        while current_address < self.end_address:
            current_address = idc.FindBinary(current_address, idc.SEARCH_DOWN,
                                             LANDING_STRIP)
            presumed_landing_address = current_address
            if presumed_landing_address == idc.BADADDR or presumed_landing_address == 0:
                # have reached the end
                break
            else:
                # [macro + [macro + normal]] renders (macro + normal) usually not interp'd by ida
                idc.MakeUnknown(presumed_landing_address, 2, idc.DOUNK_SIMPLE)
                idc.MakeCode(presumed_landing_address)
                zoning_address = presumed_landing_address
                next_iter = 0
                if len(self.macros) > 0:
                    # finding following macro...
                    entry_search_limit_address = (self.macros[-1])[2]
                    next_iter = self.__find_entry(entry_search_limit_address,
                                                  zoning_address,
                                                  presumed_landing_address)
                else:
                    # landing is above start, finding first macro...
                    next_iter = self.__find_entry(self.start_address,
                                                  zoning_address,
                                                  presumed_landing_address)

                if next_iter == 0:
                    print(
                        "ERROR.SeekingIteration: Issue obtaining a valid macro block to search from."
                    )
                    break
                else:
                    current_address = next_iter
        print("============================================================")
Пример #27
0
def undefine(start, end):
    idc.MakeUnknown(start, end - start, idc.DOUNK_SIMPLE)
Пример #28
0
def write_data(ea, blob, reanalyze=True):
    """ Write bytes to idb """
    if reanalyze: idc.MakeUnknown(ea, len(blob), 0)
    idaapi.patch_many_bytes(ea, blob)
    if reanalyze: idc.MakeCode(ea)
Пример #29
0
 def reset():
     idc.MakeUnknown(idc.MinEA(), 0x1000, 0)
     for i in range(0x1000):
         idc.PatchByte(idc.MinEA() + i, 0)
Пример #30
0
def make_string(addr, siz):
    print("Creating string at %x %d size" % (addr, siz))
    idc.MakeUnknown(addr, siz, idc.DOUNK_SIMPLE)
    ida_bytes.create_strlit(addr, siz, -1)