def find_module_ptr(self):
        str_ptr = idc.FindBinary(0, idc.SEARCH_DOWN | idc.SEARCH_CASE,
                                 '"SceUIDModuleClass"')
        if str_ptr == idc.BADADDR:
            raise RuntimeError("failed to apply str_ptr heuristic")
        log("stage 1: str_ptr at 0x{:08X}".format(str_ptr))

        haystack = " ".join(chunk(p32(str_ptr).encode("hex"), 2))
        cls_ptr = idc.FindBinary(0, idc.SEARCH_DOWN | idc.SEARCH_CASE,
                                 haystack)
        if cls_ptr == idc.BADADDR:
            raise RuntimeError("failed to apply cls_ptr heuristic")
        cls_ptr -= 0xC
        log("stage 2: cls_ptr at 0x{:08X}".format(cls_ptr))

        haystack = " ".join(chunk(p32(cls_ptr).encode("hex"), 2))
        ea = 0
        while True:
            ea = idc.FindBinary(ea, idc.SEARCH_DOWN | idc.SEARCH_CASE,
                                haystack)
            if ea == idc.BADADDR:
                raise RuntimeError(
                    "failed to find the last module using the heuristic")
            ptr = idc.Dword(ea + 0x20)
            name = c_str(ptr, 0x20)
            if name == "SceKrm":
                self.last_module_ptr = ea + 4
                log("stage 3: last_module_ptr at 0x{:08X}".format(
                    self.last_module_ptr))
                break

            ea = idc.NextAddr(ea)
Esempio n. 2
0
def find_all(opcode_str):
    ret = []
    ea = idc.FindBinary(0, 1, opcode_str)
    while ea != idc.BADADDR:
        ret.append(ea)
        ea = idc.FindBinary(ea + 4, 1, opcode_str)
    return ret
Esempio n. 3
0
def find_encrypted_strings(opcode, start, end):
    ea = start
    ret = []
    ea = idc.FindBinary(ea, 1, opcode)
    while ea != idc.BADADDR and ea < end:
        ret.append(ea)
        ea = idc.FindBinary(ea + 4, 1, opcode)
    return ret
Esempio n. 4
0
 def find_all_switch_jumps(self):
     self._switch_dict = defaultdict(list)
     next_switch = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
     while next_switch != idc.BADADDR:
         sw = idaapi.get_switch_info_ex(next_switch)
         if idc.GetMnem(next_switch).startswith("jmp") and sw:
             ic = self.get_jlocs(sw)
             self._switch_dict[idaapi.get_func_name(next_switch)].append((next_switch, sw.ncases, ic))
         next_switch = idc.FindBinary(idc.NextHead(next_switch), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
Esempio n. 5
0
 def getVersionByString(self):
     pos = idautils.Functions().next()
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 31 30") != idc.BADADDR:
         return 'Go 1.10'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 39") != idc.BADADDR:
         return 'Go 1.9'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 38") != idc.BADADDR:
         return 'Go 1.8'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 37") != idc.BADADDR:
         return 'Go 1.7'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 36") != idc.BADADDR:
         return 'Go 1.6'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 35") != idc.BADADDR:
         return 'Go 1.5'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 34") != idc.BADADDR:
         return 'Go 1.4'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 33") != idc.BADADDR:
         return 'Go 1.3'
     if idc.FindBinary(pos, idc.SEARCH_DOWN,
                       "67 6f 31 2e 32") != idc.BADADDR:
         return 'Go 1.2'
Esempio n. 6
0
File: core.py Progetto: yannayl/Sark
def iter_find_query(query, start=None, end=None, down=True):
    start, end = fix_addresses(start, end)

    if down:
        direction = idc.SEARCH_DOWN
    else:
        direction = idc.SEARCH_UP

    current = idc.FindBinary(start, direction, query)
    while current < end:
        yield current
        current = idc.FindBinary(current + 1, direction, query)
Esempio n. 7
0
    def renameDword(self):
        proc_addr = self._import_table.item(self._import_table.currentRow(), 3).text()
        proc_name = str(self._import_table.item(self._import_table.currentRow(), 2).text())
        renamed = 0
        if proc_addr:
            try:
                proc_addr = int(proc_addr, 16)
                proc_bin_str = " ".join([x.encode("hex") for x in struct.pack("<I", proc_addr)])
                next_dword = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
                while next_dword != idc.BADADDR:
                    log.debug("Trying to fix-up 0x{:08x}".format(next_dword))
                    # DWORDs can be "inaccessible" for many reasons and it requires "breaking up" the data blobs
                    # and manually fixing them

                    # Reason 1: In a dword array in an unknown section
                    if idc.isUnknown(next_dword):
                        idc.MakeUnkn(next_dword, idc.DOUNK_EXPAND)
                        idc.MakeDword(next_dword)
                    # Reason 2: In a dword array in a data section
                    elif idc.isData(next_dword):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)
                    # Reason 3: In a dword array in a code section (validate via "dd <dword>,")
                    elif idc.isCode(next_dword) and idc.GetDisasm(next_dword).startswith("dd "):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)

                    # Only perform
                    if idc.Name(next_dword).startswith(("off_", "dword_")) or idc.Name(next_dword) == "":
                        success = idc.MakeNameEx(next_dword, proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                        i = 0
                        new_proc_name = proc_name
                        while not success and i < 10:
                            new_proc_name = "{}{}".format(proc_name, i)
                            success = idc.MakeNameEx(next_dword, new_proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                            i += 1
                        if success:
                            renamed += 1
                            item = self._import_table.item(self._import_table.currentRow(), 5)
                            item.setText("{}, {}".format(str(item.text()), new_proc_name))
                            log.debug("DWORD @ 0x{:08x} now has name {}".format(next_dword, new_proc_name))
                        else:
                            log.error("Unable to auto-rename successfully, terminating search")
                            break
                    else: log.debug("Value at 0x{:08x} does not meet renaming requirements".format(next_dword))
                    next_dword = idc.FindBinary(next_dword+4, idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
            except Exception, e:
                log.error("Error encountered: {}".format(e))
            log.debug("Renamed {:d} instances of {}".format(renamed, proc_name))
Esempio n. 8
0
def code_search(ea, val):
    """Search forward for the next occurance of val. Return None if no match."""
    res = idc.FindBinary(ea, idc.SEARCH_DOWN, val)
    if res == idaapi.BADADDR:
        return None
    else:
        return res
Esempio n. 9
0
 def match_binary(addr, search_flag, pattern_list):
     ret_addr = idc.BADADDR
     for pattern in pattern_list:
         ret_addr = idc.FindBinary(addr, search_flag, pattern)
         if ret_addr != idc.BADADDR:
             break
     return ret_addr
Esempio n. 10
0
def _find_function_end(location):
    '''
    Description:
        If the location is the last applicable byte, assume that's the end byte.

        Else, search down until we find the last (highest EA) "retn" before either aligns or a function.
        If that fails, look for the last (higheste EA) "jmp" instruction.

    Input:
        location - The EA from which to start looking for a function end.

    Output:
        A list of applicable EAs (one per type) or idc.BADADDR if none are found.
    '''
    if idaapi.get_func(location + 1) or idc.isAlign(
            idc.GetFlags(location + 1)):  # This bit is inclusive
        return [location + 1]  # This bit is exclusive

    eas = []
    # CA + CB are retf, but aren't used often; 'EA' is 16 bit; 'FF' jumps are too rare
    for opcode in ['C3', 'C2', 'E9', 'EB']:
        ea = location
        function_end = idc.BADADDR
        while ea != idc.BADADDR:
            ea = idc.FindBinary(ea + 1, idc.SEARCH_DOWN, opcode)
            if not (idaapi.get_func(ea) or idc.isAlign(idc.GetFlags(ea))):
                function_end = ea
            else:
                break
        if function_end != idc.BADADDR:
            eas.append(_un_nop(function_end, idc.PrevHead) +
                       1)  # Again, exclusive

    eas.sort(reverse=True)
    return eas
Esempio n. 11
0
def _find_function_start(location):
    '''
    Description:
        If the location is the first applicable byte, assume that's the start byte.

        Else, search up until we find the first (lowest EA) "push ebp" before either aligns or a function.
        If that fails, look for "push esp", then "push esi", and finally "push edi".

    Input:
        The EA from which to start looking for a function start

    Output:
        A list of applicable EAs (one per type) or idc.BADADDR if none are found.
    '''
    if idaapi.get_func(location - 1) or idc.isAlign(
            idc.GetFlags(location - 1)):
        return [location]

    eas = []
    for opcode in ['55', '54', '56', '57']:
        ea = location
        function_start = idc.BADADDR
        while ea != idc.BADADDR:
            ea = idc.FindBinary(ea - 1, idc.SEARCH_UP, opcode)
            if not (idaapi.get_func(ea) or idc.isAlign(idc.GetFlags(ea))):
                function_start = ea
            else:
                break
        if function_start != idc.BADADDR:
            eas.append(_un_nop(function_start, idc.NextHead))

    eas.sort()
    return eas
Esempio n. 12
0
def find_binary_instruction_start(search_start_location, search_direction, target, min_location=idc.MinEA(),
                                  max_location=idc.MaxEA()):
    """
    Description:
        Given a starting location, target, and direction, find an instruction starting with the target bytes.

    Input:
        search_start_location - The EA to start searching at
        search_direction - either idc.SEARCH_UP or idc.SEARCH_DOWN
        target - The target as space separated bytes (i.e. '55' for 'push ebp')
        min_location - The minimum EA to accept results for (default: idc.MinEA())
        max_location - The maximum EA to accept results for (default: idc.MaxEA())

    Output:
        Returns the first matching location if found, otherwise idc.BADADDR
    """
    target = target.upper()
    while search_start_location < max_location:
        ea = idc.FindBinary(search_start_location, search_direction, target)
        if (min_location <= ea < max_location
                and ea == idc.ItemHead(ea)
                and idaapi.get_many_bytes(ea, idc.ItemSize(ea)).encode('hex').upper().startswith(target.replace(' ', ''))):
            return ea
        else:
            search_start_location = ea + (1 if search_direction == idc.SEARCH_DOWN else -1)
    return idc.BADADDR
 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
Esempio n. 14
0
def find_func_pattern(pattern):  # Direct Function Pattern
    addr = idc.FindBinary(0, SEARCH_DOWN, pattern)
    if addr == BADADDR: return 0

    try:
        return idaapi.get_func(addr).startEA
    except exception:
        return 0
Esempio n. 15
0
def FindFuncPattern(Pattern):  # Find's Func. by Pattern
    addr = idc.FindBinary(0, SEARCH_DOWN, Pattern)
    if addr == BADADDR: return 0

    try:
        return idaapi.get_func(addr).startEA
    except Exception:
        return 0
Esempio n. 16
0
def FindFunctionByPatternStartEA(pattern):
    address = idc.FindBinary(0, SEARCH_DOWN, pattern)
    if address == BADADDR:
        return BADADDR

    try:
        return idaapi.get_func(address).startEA
    except Exception:
        return -1
Esempio n. 17
0
def relocGlobalVar(sigStr,
                   relativeOffset=0,
                   dataOffset=0,
                   instructionLength=0):
    sigAddr = idc.FindBinary(0, idc.SEARCH_DOWN, sigStr)
    scanResult = sigAddr + relativeOffset
    if (dataOffset != None):
        rel32 = idc.Dword(scanResult + dataOffset)
        scanResult = scanResult + instructionLength + rel32
    return scanResult
Esempio n. 18
0
def findGoPcLn():
    pos = idautils.Functions().next() # Get some valid address in .text segment
    while True:
        possible_loc = idc.FindBinary(pos, idc.SEARCH_DOWN, lookup) #header of gopclntab
        if possible_loc == idc.BADADDR:
            break
        if check_is_gopclntab(possible_loc):
            return possible_loc
        pos = possible_loc+1
    return None
Esempio n. 19
0
def find_all_bin(str):
    start_addr = 0
    res = []
    while start_addr != idc.BADADDR:
        addr = idc.FindBinary(start_addr + 1, idc.SEARCH_DOWN, str, 16)
        if addr == idc.BADADDR:
            break
        yield here(addr)
        start_addr = addr
    return
def resolve_loops():

    PATTERNS = ["81 FB ?? ?? ?? ?? 75"]

    count_patched = 0
    count_not_patched = 0

    for pattern in PATTERNS:

        ea = 0

        while ea != BADADDR:
            '''
             pattern: 81 FB ?? ?? ?? ?? 75
            .text:00406AA0 01 C7                add     edi, eax
            .text:00406AA2 66 41                inc     cx
            .text:00406AA4 43                   inc     ebx
            .text:00406AA5 81 FB A6 01 00 00    cmp     ebx, 1A6h
            .text:00406AAB 75 F3                jnz     short loc_406AA0

            patched:
            .text:00406AA0 01 C7                add     edi, eax
            .text:00406AA2 66 41                inc     cx
            .text:00406AA4 43                   inc     ebx
            .text:00406AA5 90                   nop
            .text:00406AA6 90                   nop
            .text:00406AA7 90                   nop
            .text:00406AA8 90                   nop
            .text:00406AA9 90                   nop
            .text:00406AAA 90                   nop
            .text:00406AAB 90                   nop
            .text:00406AAC 90                   nop
            '''

            ea = idc.FindBinary(ea, SEARCH_NEXT | SEARCH_DOWN | SEARCH_CASE,
                                pattern)

            if ea_in_bounds(ea):

                # Patch CMP and conditional jmp instructions in order to remove the loop
                idc.PatchByte(ea + 0, 0x90)
                idc.PatchByte(ea + 1, 0x90)
                idc.PatchByte(ea + 2, 0x90)
                idc.PatchByte(ea + 3, 0x90)
                idc.PatchByte(ea + 4, 0x90)
                idc.PatchByte(ea + 5, 0x90)
                idc.PatchByte(ea + 6, 0x90)
                idc.PatchByte(ea + 7, 0x90)

                idc.MakeCode(ea)

                count_patched += 1

    print "\tPatched resolve_loops: {0}".format(count_patched)
    print "\tNot Patched resolve_loops: {0}".format(count_not_patched)
Esempio n. 21
0
def findGoPcLn():
    possible_loc = idc.FindBinary(0, idc.SEARCH_DOWN, lookup,
                                  16)  #header of gopclntab
    print "Possible gopclntab: %s" % hex(possible_loc)

    while possible_loc != idc.BADADDR:
        if check_is_gopclntab(possible_loc):
            return possible_loc
        else:
            possible_loc = ida_search.FindBinary(possible_loc + 1,
                                                 idc.SEARCH_DOWN, lookup, 16)
    return None
Esempio n. 22
0
 def makeFuncsFromPreamble(funcpreamble, startea=idc.FirstSeg(), endea = idaapi.BADADDR):
     """ This method makes functions everywhere that the sequence 'funpreamble' is found.
         NOTE: this method is generally unsafe, because it will attempt to make functions where
         there may be no function.  Use it with caution.
     """
     ea = startea
     i = 0
     while (ea != idaapi.BADADDR and ea < endea):
         ea = idc.FindBinary(ea, SEARCH_DOWN, funcpreamble)
         idc.MakeFunction(ea)
         idc.Wait()
         ea = ea + 1 # idc.FindBinary(ea) returns ea if ea matches, silly
Esempio n. 23
0
def FindNOPAddr(name, offset):
    address = idc.FindBinary(0, SEARCH_DOWN, "\"" + name + "\"")
    dword = -1

    if address == BADADDR:
        return -1

    xrefs = XrefsTo(address)
    for xref in xrefs:
        dword = xref.frm + offset

    return dword
Esempio n. 24
0
def FindFuncFirstReference(Reference): # Find's Func. by Reference, Returns first 
	addr = idc.FindBinary(0, SEARCH_DOWN, "\"" + Reference + "\"")
	if addr == BADADDR: return 0
	
	dword = -1
	xrefs = XrefsTo(addr)
	for xref in xrefs:
		dword = xref.frm
		
	try:
		return idaapi.get_func(dword).startEA
	except Exception:
		return 0
Esempio n. 25
0
def autoCode(hex_value):
  start = idc.MinEA();
  len=idc.MaxEA()-start;
  addr=start;
  flag = False
  for x in range(len):
    addr = idc.FindBinary(addr, SEARCH_DOWN|SEARCH_CASE|SEARCH_NEXT, hex_value)
    if addr != idc.BADADDR:
      make_code(addr,addr+4)
      print "{:>8X} {:<32}".format(addr,idc.GetDisasm(addr))
    else:
      flag = False
    #addr=idc.NextHead(addr)
  return 0
Esempio n. 26
0
def FindFunctionFirstXRef(name):
    address = idc.FindBinary(0, SEARCH_DOWN, "\"" + name + "\"")
    dword = BADADDR

    if address == BADADDR:
        return BADADDR

    xrefs = XrefsTo(address)
    for xref in xrefs:
        dword = xref.frm

    try:
        return idaapi.get_func(dword).startEA
    except Exception:
        return -1
def processEncrypt(ea, name, CRYPTSTART_PATTERN, CRYPTEND_PATTERN, EPILOGUE_PATTERN, PROLOGUE_PATTERN):
	prologue = idc.FindBinary(ea, SEARCH_UP, PROLOGUE_PATTERN) if len(PROLOGUE_PATTERN) != 0 else idc.GetFunctionAttr(ea, FUNCATTR_START)
	epilogue = idc.FindBinary(ea, SEARCH_DOWN, EPILOGUE_PATTERN) if len(EPILOGUE_PATTERN) != 0 else idc.GetFunctionAttr(ea, FUNCATTR_END)
	
	idc.MakeFunction(prologue, epilogue + EPILOGUE_PATTERN.count(' ') + 1);

	cryptStart = idc.FindBinary(ea, SEARCH_DOWN if name != "BYTE" else SEARCH_UP, CRYPTSTART_PATTERN)
	cryptEnd = idc.FindBinary(ea, SEARCH_DOWN, CRYPTEND_PATTERN)

	# Generate Encrypt
	ea = cryptStart + CRYPTSTART_PATTERN.count(' ') + 1

	opStr = ""

	while ea < cryptEnd:

		if idc.GetMnem(ea) != 'mov':
			result = {
			  'add': lambda x: "new Add({0})".format(idc.GetOperandValue(x, 1)),
			  'sub': lambda x: "new Sub({0})".format(idc.GetOperandValue(x, 1)),
			  'xor': lambda x: "new Xor({0})".format(idc.GetOperandValue(x, 1)),
			  'ror': lambda x: "new Ror({0})".format(idc.GetOperandValue(x, 1)),
			  'rol': lambda x: "new Rol({0})".format(idc.GetOperandValue(x, 1)),
			  'not': lambda x: "new Not()",
			  'inc': lambda x: "new Inc()",
			  'dec': lambda x: "new Dec()",
			}[idc.GetMnem(ea)](ea)
			opStr += str("{0}{1}".format(result, ", " if idc.NextNotTail(ea) != cryptEnd else ""))
			
		ea = idc.NextNotTail(ea)
	
	print "CryptOperations.Add(0x{0:X}, new Operations({1}));".format(zlib.crc32(opStr) & 0xffffffff, opStr)

	idc.MakeNameEx(prologue, "Encrypt_{0}_{1:X}".format(name, zlib.crc32(opStr) & 0xffffffff), SN_NOCHECK | SN_NOWARN)

	return;
Esempio n. 28
0
def FindFunctionAddr(name, offset, operandValue):
    address = idc.FindBinary(0, SEARCH_DOWN, "\"" + name + "\"")
    dword = -1

    if address == BADADDR:
        return BADADDR

    xrefs = XrefsTo(address)
    for xref in xrefs:
        dword = xref.frm + offset

    if dword == BADADDR:
        return BADADDR

    return idc.GetOperandValue(dword, operandValue)
    def __seek(self):
        # Method 1 (biased approach)
        current_address = self.start_address
        while current_address < self.end_address:
            next_iter = self.__find_entry(current_address)
            if next_iter == 1 or next_iter == 0:
                next_address = idc.FindBinary(current_address + 1, idc.SEARCH_DOWN, ENTRY_ID_BYTECODE + " ?? ??")
                current_address = next_address
            elif next_iter > 1:
                current_address = next_iter
            else:
                print("ERROR.SeekingIteration: Issue obtaining a valid macro block to search from at " + \
                      format_address(hex(current_address)))
                break

        print("============================================================")
 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