def __PltResolver(jmprel, strtab, symtab):
     idx = 0
     while True:
         r_off = idc.get_qword(jmprel + 0x18 * idx)
         r_info1 = idc.get_wide_dword(jmprel + 0x18 * idx + 0x8)
         r_info2 = idc.get_wide_dword(jmprel + 0x18 * idx + 0xc)
         r_addend = idc.get_qword(jmprel + 0x18 * idx + 0x10)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.get_wide_dword(symtab + r_info2 * 0x18)
             name = idc.get_strlit_contents(strtab + st_name)
             # rename got
             idc.set_name(r_off, name.decode("ascii") + '_ptr')
             plt_func = idc.get_qword(r_off)
             if debug_mode:
                 print(hex(plt_func.start_ea), name)
             # rename plt
             idc.set_name(plt_func, 'j_' + name.decode("ascii"))
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr)
                 if plt_sec_func:
                     plt_sec_func_addr = plt_sec_func.start_ea
                     idc.set_name(plt_sec_func_addr,
                                  '_' + name.decode("ascii"))
                     SetFuncFlags(plt_sec_func_addr)
                 else:
                     print("[!] idaapi.get_func({}) failed".format(
                         hex(addr)))
         idx += 1
Esempio n. 2
0
	def get_jit_function(self):

		esp = idc.get_reg_value("ESP")

		method_name = self.get_method_name(esp)
		function = idc.get_wide_dword(esp + 8)

		method_id = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x20)
		abc_info_pos = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x1C)
		method_info = get_qword(abc_info_pos) + get_qword(abc_info_pos + 8)
		
		if (self.as3dump != []):

			method = next((x for x in self.as3dump if x["id"] == method_id), None)

			if (method is not None and method["info"] == method_info):
				method_name = method["name"]
				self.set_jit_info(method_id, function)

		print("Resolved jit function: 0x%x - %s" % (function, method_name))

		self.rename_addr(function, method_name)

		if ((method_name not in self.ignore and not self.ignore_all) or
			(method_name in self.debug_if_equals) or 
			(any(x for x in self.debug_if_contains if method_name is not None and x in method_name))):
			self.traced.append({"name": method_name, "ea": function, "type": "jit", "hit": 0})
			idc.add_bpt(function)
 def GetDyn():
     phoff = idc.get_wide_dword(ida_ida.inf_get_min_ea() +
                                0x1c) + ida_ida.inf_get_min_ea()
     phnum = idc.get_wide_word(ida_ida.inf_get_min_ea() + 0x2c)
     phentsize = idc.get_wide_word(ida_ida.inf_get_min_ea() + 0x2a)
     for i in range(phnum):
         p_type = idc.get_wide_dword(phoff + phentsize * i)
         if p_type == 2:  # PY_DYNAMIC
             dyn_addr = idc.get_wide_dword(phoff + phentsize * i + 8)
             return dyn_addr
 def __PltResolver(jmprel, strtab, symtab, pltgot):
     seg_sec = idc.selector_by_name('.plt.sec')
     sec_start = idc.get_segm_by_sel(seg_sec)
     sec_end = idc.get_segm_end(sec_start)
     if sec_start == idaapi.BADADDR:
         print("[-] can't find .plt.sec segment")
         return
     idx = 0
     while True:
         r_off = idc.get_wide_dword(jmprel + 0x8 * idx)
         r_info1 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x4)
         r_info2 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x5)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.get_wide_dword(symtab + r_info2 * 0x10)
             name = idc.get_strlit_contents(strtab + st_name)
             # rename got
             idc.set_name(r_off, name.decode("ascii") + '_ptr')
             plt_func = idc.get_wide_dword(r_off)
             # rename plt
             idc.set_name(plt_func, 'j_' + name.decode("ascii"))
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr)
                 if plt_sec_func:
                     plt_sec_func_addr = plt_sec_func.start_ea
                     idc.set_name(plt_sec_func_addr,
                                  '_' + name.decode("ascii"))
                     SetFuncFlags(plt_sec_func_addr)
                 else:
                     print("[!] idaapi.get_func({}) failed".format(
                         hex(addr)))
             got_off = r_off - pltgot
             target = '+{}h'.format(
                 hex(got_off).lower().replace('0x',
                                              '').replace('l',
                                                          '').rjust(2, '0'))
             for func_ea in idautils.Functions(sec_start, sec_end):
                 func = idaapi.get_func(func_ea)
                 cur = func.start_ea
                 end = func.endEA
                 find = False
                 while cur <= end:
                     code = idc.GetDisasm(cur).lower().replace(' ', '')
                     if target in code:
                         find = True
                         break
                     cur = idc.NextHead(cur, end)
                 if find:
                     idc.set_name(func_ea, '_' + name)
                     SetFuncFlags(func_ea)
         idx += 1
 def ParseDyn(dyn, tag):
     idx = 0
     while True:
         v1, v2 = idc.get_wide_dword(dyn + idx *
                                     0x8), idc.get_wide_dword(dyn +
                                                              idx * 0x8 + 4)
         if v1 == 0 and v2 == 0:
             return
         if v1 == tag:
             return v2
         idx += 1
Esempio n. 6
0
def resolveDispatcher(code):
    major = (code & 0x00ff0000) >> 0x10
    minor = code & 0xff00ffff

    res = getMajorDispatchTableAddress() + major * 8
    majorFlag = idc.get_wide_dword(res)
    majorAddress = idc.get_wide_dword(res + 4)
    if majorFlag != 0:
        return majorAddress + (minor * 0x10)

    #print "%x"% getMinorDispatchTableAddress(majorAddress)
    #print "resolved by 0x%x(%x)"% (majorAddress, minor)
    return majorAddress
def simplify_jumps(ea):
    # If we got long first conditional jump
    if idc.get_wide_byte(ea) == 0x0F:
        alternative_jmp_cmd = idc.get_wide_byte(ea + 1) ^ 1
        interm_jmp_offt = 6
    else:
        alternative_jmp_cmd = idc.get_wide_byte(ea) ^ 0xF1
        interm_jmp_offt = 2

    # Get intermediate jump's value
    if idc.get_wide_byte(ea + interm_jmp_offt) == 0x0F:
        interm_jmp_param = idc.get_wide_dword(ea + interm_jmp_offt + 2)
        final_jmp_addr = ea + interm_jmp_param + interm_jmp_offt + 6
    else:
        interm_jmp_param = idc.get_wide_byte(ea + interm_jmp_offt + 1)
        final_jmp_addr = ea + interm_jmp_param + interm_jmp_offt + 2

    # Check the last conditional jump

    # 75 ?? ... 0F 85 ?? ?? ?? ??
    if idc.get_wide_byte(final_jmp_addr) == 0x0F and \
       idc.get_wide_byte(final_jmp_addr + 1) == alternative_jmp_cmd:
        final_jmp_param = idc.get_wide_dword(final_jmp_addr + 2)
        final_jmp_target = (final_jmp_addr + final_jmp_param + 6) & 0xFFFFFFFF

    # 75 ?? ... 75 ??
    elif idc.get_wide_byte(final_jmp_addr) ^ 0xF0 == alternative_jmp_cmd:
        final_jmp_param = idc.get_wide_byte(final_jmp_addr + 1)
        final_jmp_target = (final_jmp_addr + final_jmp_param + 2) & 0xFFFFFFFF

    # Make a little cleanup: remove garbage code
    elif interm_jmp_param < 0x10:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_addr)
        return True

    else:
        return

    if final_jmp_target - ea < 0xFF:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_target)
    else:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_addr + 6)

    # Restore seconds jump
    idc.patch_byte(ea + interm_jmp_offt, 0x0F)
    idc.patch_byte(ea + interm_jmp_offt + 1, alternative_jmp_cmd)
    idc.patch_dword(ea + interm_jmp_offt + 2, final_jmp_target - (ea + interm_jmp_offt) - 6)
    idc.create_insn(ea + interm_jmp_offt)

    return True
Esempio n. 8
0
    def req_patch(self, hash):
        addr, value, length = hash['addr'], hash['value'], hash['len']

        if length == 4:
            prev_value = idc.get_wide_dword(addr)
            if not ida_bytes.create_data(ea, FF_DWORD, 4, ida_idaapi.BADADDR):
                rs_log('[x] ida_bytes.create_data FF_DWORD failed')
            if not ida_bytes.patch_dword(addr, value):
                rs_log('[x] patch_dword failed')
            if not idc.op_plain_offset(addr, 0, 0):
                rs_log('[x] op_plain_offset failed')

        elif length == 8:
            prev_value = idc.get_qword(addr)
            if not ida_bytes.create_data(addr, FF_QWORD, 8,
                                         ida_idaapi.BADADDR):
                rs_log('[x] ida_bytes.create_data FF_QWORD failed')
            if not ida_bytes.patch_qword(addr, value):
                rs_log('[x] patch_qword failed')
            if not idc.op_plain_offset(addr, 0, 0):
                rs_log('[x] op_plain_offset failed')

        else:
            rs_log("[x] unsupported length: %d" % length)
            return

        rs_log("patched 0x%x = 0x%x (previous was 0x%x)" %
               (addr, value, prev_value))
Esempio n. 9
0
def find_pointers(start, end):
    for va in range(start, end - 0x4):
        ptr = idc.get_wide_dword(va)
        if idc.get_segm_start(ptr) == idc.BADADDR:
            continue

        yield va, ptr
Esempio n. 10
0
def rename(beg, ptr, make_funcs=True):
    go_fun = Utils.load_function_comments()
    base = beg
    pos = beg + 8  #skip header
    size = ptr.ptr(pos)
    pos += ptr.size
    end = pos + (size * ptr.size * 2)
    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:
            ida_bytes.del_items(func_addr, 1, ida_bytes.DELIT_SIMPLE)
            ida_funcs.add_func(func_addr)
        name_offset = idc.get_wide_dword(base + offset + ptr.size)
        name = idc.get_strlit_contents(base + name_offset)
        comment = name
        if go_fun:
            tcomment = Utils.get_function_comment(name, go_fun)
            if tcomment:
                comment = tcomment
        Utils.add_function_comment(func_addr, comment)
        name = Utils.relaxName(name)
        print(name)
        Utils.rename(func_addr, name)
Esempio n. 11
0
    def find_fakefast(self, target_addr):
        max_size = (0x80 if self.ptr_size == 8 else 0x40)
        ea = target_addr - max_size - self.ptr_size
        end_ea = target_addr - self.ptr_size

        results = []
        while ea < end_ea:
            fake_size = idc.get_wide_dword(ea)
            idx = self.fastbin_index(fake_size & ~SIZE_BITS)

            if 0 <= idx <= 7:
                if (fake_size & 2 == 2) and ((fake_size & 4 == 4) or
                                             (fake_size & 4 == 0)):
                    chunk_addr = ea - self.ptr_size
                    align_size = self.tidx2size(idx)
                    bytes_to = target_addr - ea - self.ptr_size
                    results.append({
                        'fast_id': idx,
                        'size': align_size,
                        'address': chunk_addr,
                        'bytes_to': bytes_to
                    })
            ea += 1

        return results
Esempio n. 12
0
 def next(self):
     if self.pos >= self.end:
         raise StopIteration
     value = idc.get_wide_dword(self.pos)
     self.pos += 4
     value = self.getOffset(value)
     return self.handle_offset(value)
Esempio n. 13
0
    def iter_vtable(self):
        ea = self.vtable_start
        end = self.vtable_end

        while ea <= end:
            yield (ea, idc.get_wide_dword(ea))
            ea += 4
Esempio n. 14
0
def get_guid(address):
    """get GUID located by address"""
    guid = list()
    guid.append(idc.get_wide_dword(address))
    guid.append(idc.get_wide_word(address + 4))
    guid.append(idc.get_wide_word(address + 6))
    for addr in range(address + 8, address + 16, 1):
        guid.append(idc.get_wide_byte(addr))
    return guid
Esempio n. 15
0
	def get_native_function(self):

		ecx = idc.get_reg_value("ECX")
		esp = idc.get_reg_value("ESP")

		method_name = self.get_method_name(esp)
		
		if (idc.get_wide_byte(idc.get_wide_dword(ecx + 8) + 0x38) != 0):
			function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x28)
		else:
			function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x24)
		
		print("Resolved native function: 0x%x - %s" % (function, method_name))

		if ((method_name not in self.ignore and not self.ignore_all) or
			(method_name in self.debug_if_equals) or 
			(any(x for x in self.debug_if_contains if method_name is not None and x in method_name))):
			self.traced.append({"name": method_name, "ea": function, "type": "native", "hit": 0})
			idc.add_bpt(function)
Esempio n. 16
0
def parse_vtable(ea, typename):
    os = get_os()
    if os == OS_Linux:
        ea += 8
    funcs = []

    while ea != idc.BADADDR:
        eatemp = ea
        offs = idc.get_wide_dword(ea)
        #		if ida_bytes.is_unknown(ida_bytes.get_full_flags(ea)):
        #			break

        size = idc.get_item_size(
            ea
        )  # This is bad abd abadbadbadbabdbabdad but there's no other choice here
        if size != 4:
            # This looks like it might be a bug with IDA
            # Random points of a vtable are getting turned into unknown data
            if size != 1:
                break

            s = "".join([
                "%02x" % idc.get_wide_byte(ea + i) for i in range(3, -1, -1)
            ])  #.replace("0x", "")
            if not s.lower().startswith("ffff"):
                ea = ida_bytes.next_not_tail(ea)
                continue

            offs = int(s, 16)
            ea += 3

        name = idc.get_name(offs, ida_name.GN_VISIBLE)
        if name:
            if os == OS_Linux:
                if not (name.startswith("_Z") or
                        name.startswith("__cxa")) or name.startswith("_ZTV"):
                    break  # If we've exceeded past this vtable
            elif name.startswith("??"):
                break
        else:
            if os == OS_Win:
                break

            # dd -offsettothis
            # This is even worseworsoewewrosorooese
            s = "%02x" % offs
            if not s.lower().startswith("ffff"):
                ea = ida_bytes.next_not_tail(ea)
                continue

            name = (1 << 32) - int(offs)
        funcs.append(name)

        ea = ida_bytes.next_not_tail(ea)
    return funcs, eatemp
Esempio n. 17
0
 def get_data_guids(self):
     '''
     rename GUIDs in idb
     '''
     EFI_GUID = 'EFI_GUID *'
     EFI_GUID_ID = idc.get_struc_id('EFI_GUID')
     segments = ['.text', '.data']
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while (ea <= seg_end - 15):
             prot_name = ''
             if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1:
                 find = False
                 cur_guid = []
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                         'ami_guids', 'asrock_guids', 'dell_guids',
                         'edk_guids', 'edk2_guids', 'lenovo_guids'
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = name + '_' + \
                                 '{addr:#x}'.format(addr=ea)
                             record = {
                                 'address': ea,
                                 'service': 'unknown',
                                 'guid': cur_guid,
                                 'protocol_name': name,
                                 'protocol_place': guid_place
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) !=
                              prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols['data'].append(record)
             ea += 1
Esempio n. 18
0
 def get_data_guids(self):
     """rename GUIDs in idb"""
     EFI_GUID = "EFI_GUID"
     EFI_GUID_ID = idc.get_struc_id("EFI_GUID")
     segments = [".text", ".data"]
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while ea <= seg_end - 15:
             prot_name = str()
             if "unk" in idc.get_name(ea, ida_name.GN_VISIBLE):
                 find = False
                 cur_guid = list()
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                     "ami_guids",
                     "asrock_guids",
                     "dell_guids",
                     "edk_guids",
                     "edk2_guids",
                     "lenovo_guids",
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = f"{name}_{ea:016X}"
                             record = {
                                 "address": ea,
                                 "service": "unknown",
                                 "guid": cur_guid,
                                 "protocol_name": name,
                                 "protocol_place": guid_place,
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols["data"].append(record)
             ea += 1
def resolve_obf_calls(ea):
    next_instr_addr = idc.get_wide_dword(ea + 1)

    first_jmp_target = (ea + idc.get_wide_dword(ea + 0x7) + 0xB) & 0xFFFFFFFF
    second_jmp_target = (ea + idc.get_wide_dword(ea + 0xD) + 0x11) & 0xFFFFFFFF

    if first_jmp_target != second_jmp_target:
        return

    call_param = (first_jmp_target - ea - 5) & 0xFFFFFFFF

    # Now we can replace all code till next instruction's address with NOPs
    fill_with_nops(ea, next_instr_addr)

    # Insert CALL
    ida_bytes.patch_byte(ea, 0xE8)                      # CALL
    ida_bytes.patch_dword(ea + 1, call_param)
    idc.create_insn(ea)

    return True
Esempio n. 20
0
def get_j_val(ea):
    size = 0
    j_val = 0
    op1 = idc.get_wide_byte(ea)
    if op1 == 0x0f:  # jz or jnz
        j_val = idc.get_wide_dword(ea + 2)
        size = 6
    else:  # jz short or jnz short
        j_val = idc.get_wide_byte(ea + 1)
        size = 2

    return j_val, size
Esempio n. 21
0
def import_vtable(classname, struc):
    ea = get_vtable(classname)
    if ea == idc.BADADDR:
        return

    # Mildly adapted from Asherkin's vtable dumper
    ea = ea + 8  # Skip typeinfo and thisoffs

    funcs = []
    while ea != idc.BADADDR:
        offs = idc.get_wide_dword(ea)
        if not ida_bytes.is_code(ida_bytes.get_full_flags(offs)):
            break
        name = idc.get_name(offs, ida_name.GN_VISIBLE)
        funcs.append(name)

        ea = ida_bytes.next_not_tail(ea)


#	print(funcs)

    if not len(funcs):
        return

    strucid = add_struc_ex(classname + "_vtbl")
    vstruc = ida_struct.get_struc(strucid)
    for i in funcs:
        # Gotta do a fancy demangle, it can't have special chars
        # and there can't be multiples of the same name, so let's just jazz around all of that
        demangled = idc.demangle_name(i, idc.get_inf_attr(idc.INF_SHORT_DN))
        if demangled == None:
            demangled = i
        else:
            demangled = demangled[demangled.find("::") + 2:demangled.find("(")]
            demangled = demangled.replace("~",
                                          "_").replace("<",
                                                       "_").replace(">", "_")
        while 1:
            error = ida_struct.add_struc_member(vstruc, demangled, idc.BADADDR,
                                                idc.FF_DWORD, None, 4)

            if error == 0:
                break

            demangled += "_{}".format(
                hex(ida_struct.get_struc_last_offset(vstruc) * 4 + 4)[2:])

    # Now assign the vtable to the actual struct
    ti = idaapi.tinfo_t()
    idaapi.parse_decl(ti, None, classname + "_vtbl;", 0)
    ti.create_ptr(ti)
    ida_struct.set_member_tinfo(struc, ida_struct.get_member(struc, 0), 0, ti,
                                0)
Esempio n. 22
0
def _prepare_guid(op, prefix):
    if op.type == o_mem:
        guid_ptr = Pointer(op.value)
        if guid_ptr.type != "EFI_GUID" or not is_uname(
                guid_ptr.name) or guid_ptr.name in ["Protocol", "HandlerType"]:
            guid_data1 = str("%.8x" % get_wide_dword(op.value)).upper()
            guid_ptr.name = "%s_PROTOCOL_%s_GUID" % (prefix, guid_data1)
    else:
        print("Do not know how to extract GUID ptr from %s at 0x%X" %
              (op, op.ea))
        return

    return GUID(ptr=guid_ptr)
Esempio n. 23
0
 def find_bl_targets(text_start, text_end):
     targets = set()
     for pc in range(text_start, text_end, 4):
         d = idc.get_wide_dword(pc)
         if (d & 0xfc000000) == 0x94000000:
             imm = d & 0x3ffffff
             if imm & 0x2000000:
                 imm |= ~0x1ffffff
             if 0 <= imm <= 2:
                 continue
             target = pc + imm * 4
             if target >= text_start and target < text_end:
                 targets.add(target)
     return targets
Esempio n. 24
0
 def load(self, addr, dtyp):
     if addr is Unknown:
         return Unknown
     if not is_mapped_data(addr):
         return Unknown
     if dtyp == idaapi.dt_qword:
         return idc.get_qword(addr)
     elif dtyp == idaapi.dt_dword:
         return idc.get_wide_dword(addr)
     elif dtyp == idaapi.dt_word:
         return idc.get_wide_word(addr)
     elif dtyp == idaapi.dt_byte:
         return idc.get_wide_byte(addr)
     return Unknown
def cleanup_resolveapi_calls(ea):
    delta = 0 if idc.get_wide_byte(ea) == 0x6A else 3

    intermediate_call_target = idc.get_wide_dword(ea + 8 + delta)
    if intermediate_call_target > 0x40:
        return

    # Check if we got library name
    if idc.get_wide_dword(ea + intermediate_call_target + 8 + delta) != 0x006c6c64:   # "dll\x00"
        return

    # Check if we got enough space for patching
    if idc.get_wide_dword(ea + intermediate_call_target + 0x11 + delta) != 0x90909090 or \
    idc.get_wide_byte(ea + intermediate_call_target + 0x15 + delta) != 0x90:
        return

    idc.patch_byte(ea + 7 + delta, 0xEB)
    idc.patch_byte(ea + 8 + delta, intermediate_call_target + 3)
    fill_with_nops(ea + 9 + delta, ea + 0xC + delta)
    idc.create_insn(ea + 7 + delta)

    # Now we need to pass module name parameter through stack
    resolve_api_call_param = idc.get_wide_dword(ea + intermediate_call_target + 0xD + delta)
    resolve_api_call_param = resolve_api_call_param - 5     # offset due to inserted PUSH command

    # Insert new PUSH command
    idc.patch_byte(ea + intermediate_call_target + 0xC + delta, 0x68)
    idc.patch_dword(ea + intermediate_call_target + 0xD + delta, ea + 0xC + delta)
    idc.create_insn(ea + intermediate_call_target + 0xC + delta)

    # Restore call ResolveApi
    idc.patch_byte(ea + intermediate_call_target + 0x11 + delta, 0xE8)
    idc.patch_dword(ea + intermediate_call_target + 0x12 + delta, resolve_api_call_param)
    idc.create_insn(ea + intermediate_call_target + 0x11 + delta)
    
    return True
def read_word(ea, wordsize=WORD_SIZE):
    """Get the word at the given address.
    Words are read using Byte(), Word(), Dword(), or Qword(), as appropriate. Addresses are checked
    using is_mapped(). If the address isn't mapped, then None is returned.
    """
    if not is_mapped(ea, wordsize):
        return None
    if wordsize == 1:
        return idc.get_wide_byte(ea)
    if wordsize == 2:
        return idc.get_wide_word(ea)
    if wordsize == 4:
        return idc.get_wide_dword(ea)
    if wordsize == 8:
        return idc.get_qword(ea)
    raise ValueError('Invalid argument: wordsize={}'.format(wordsize))
Esempio n. 27
0
def trace_register_family(reg, loc, func_ea, state=None):
    """
    Trace a provided register to the location in which any member of its register family is set. If it is set using a
    mov operation, the value is either an o_imm type (return the immediate value) or an o_mem type, that means the
    referenced location MAY a pointer to the actual data, which we need to acquire. We validate this by ensuring the
    acquired value is within the loaded memory range of the application. Otherwise we return idc.BADADDR.

    If the register is set using an lea operation, it is likely done so using a stack variable (which we validate)
    and then trace back to determine how the stack variable is set.

    :param reg: The referenced register which a location is loaded into
    :param loc: The starting offset for tracing back from
    :param func_ea: Starting function offset
    :param state: the current TraceState (a new state will be created if one is not provided)

    :return: The acquired location, or idc.BADADDR
    """
    if state is None:
        state = TraceState()
    reg_fam = unsafe_get_reg_fam(reg)
    if reg_fam:
        loc = idc.prev_head(loc)
        while loc != func_ea:
            opnd = idc.print_operand(loc, 0)
            op_type_1 = idc.get_operand_type(loc, 1)
            opval_1 = idc.get_operand_value(loc, 1)
            mnem = idc.print_insn_mnem(loc)
            if 'mov' in mnem and opnd in reg_fam:
                if op_type_1 == idc.o_imm:
                    return opval_1
                elif op_type_1 == idc.o_mem:
                    poss_loc = idc.get_wide_dword(opval_1)
                    if idaapi.cvar.inf.minEA <= poss_loc < idaapi.cvar.inf.maxEA:
                        return poss_loc
                    else:
                        return opval_1
                else:
                    return idc.BADADDR
            elif mnem == 'lea' and op_type_1 == idc.o_displ and opnd in reg_fam:
                stack_var = get_operand_value_replacement(loc, 1, state)
                return trace_stack_var(stack_var, loc, func_ea, state)
            elif is_64_bit() and mnem == 'lea' and opnd in reg_fam:
                if op_type_1 == idc.o_mem:
                    return opval_1
            loc = idc.prev_head(loc)
    return idc.BADADDR
Esempio n. 28
0
def make_date_ref():
    ea = 0x9561C
    max_ea = ida_ida.inf_get_max_ea()
    min_ea = ida_ida.inf_get_min_ea()

    while True:
        ea = ida_search.find_unknown(ea, idc.SEARCH_DOWN | idc.SEARCH_NEXT)
        if ea > max_ea:
            break
        size = idc.get_item_size(ea)
        print(hex(ea))

        val = idc.get_wide_dword(ea)
        # if 0xfff38 < val < 0x188544 or 0x1f000000 < val < 0x1ffa3fd9 or 0x20000000 < val < 0x2001ffff:
        #     idc.OpOff(ea, 0, 0)
        if min_ea < val < max_ea:
            idc.op_plain_offset(ea, 0, 0)
Esempio n. 29
0
def trace_register_family_x64(reg, loc, func_ea, state=None):
    """
    Shouldn't be any different than trace_register_family except for continuing a trace if a register is loaded into
    the target register. However, using it in trace_register_family was not behaving properly, so keeping it separate
    for now. Also unsure of what the repercussions would be of adding that into the existing trace_register_family.

    :param reg: The referenced register which a location is loaded into
    :param loc: The starting offset for tracing back from
    :param func_ea: Starting function offset
    :param state: the current TraceState

    :return: The acquired location, or idc.BADADDR
    """
    if state is None:
        state = TraceState()
    reg_fam = unsafe_get_reg_fam(reg)
    if reg_fam:
        loc = idc.prev_head(loc)
        while loc != func_ea:
            opnd = idc.print_operand(loc, 0)
            op_type_1 = idc.get_operand_type(loc, 1)
            opval_1 = idc.get_operand_value(loc, 1)
            mnem = idc.print_insn_mnem(loc)
            if "mov" in mnem and opnd in reg_fam:
                if op_type_1 == idc.o_imm:
                    return opval_1
                elif op_type_1 == idc.o_mem:
                    poss_loc = idc.get_wide_dword(opval_1)
                    if idaapi.cvar.inf.minEA <= poss_loc < idaapi.cvar.inf.maxEA:
                        return poss_loc
                    else:
                        return opval_1
                elif op_type_1 == idc.o_reg:
                    return trace_register_family_x64(idc.print_operand(loc, 1),
                                                     loc, func_ea, state)
                else:
                    return idc.BADADDR
            elif mnem == "lea" and op_type_1 == idc.o_displ and opnd in reg_fam:
                stack_var = get_operand_value_replacement(loc, 1, state)
                return trace_stack_var(stack_var, loc, func_ea, state)
            elif is_64_bit() and mnem == "lea" and opnd in reg_fam:
                if op_type_1 == idc.o_mem:
                    return opval_1
            loc = idc.prev_head(loc)
    return idc.BADADDR
Esempio n. 30
0
def read_vtable(funcname, ea):
    funcs = {}
    offset = 0
    while ea != idc.BADADDR:
        offs = idc.get_wide_dword(ea)
        if not ida_bytes.is_code(ida_bytes.get_full_flags(offs)):
            break

        name = idc.get_name(offs, ida_name.GN_VISIBLE)
        demangled = idc.demangle_name(name, idc.get_inf_attr(idc.INF_SHORT_DN))
        if demangled == None:
            demangled = name

        if "(" in demangled:
            demangled = demangled[:demangled.find("(")]
        funcs[demangled.lower()] = offset

        offset += 1
        ea = ida_bytes.next_not_tail(ea)

    # We've got a list of function names, let's do this really shittily because idk any other way

    # This is a good programmer who makes their gamedata the proper way :)
    offs = funcs.get(funcname.lower(), -1)
    if offs != -1:
        return offs

    # Often done but sometimes there are subclass types thrown in, save those too
    if "::" in funcname:
        funcname = funcname[funcname.find("::") + 2:]

    # Try by exact function name
    funcnames = {}
    for key, value in get_bcompat_items(funcs):
        # Function overloads can f**k right off
        s = key[key.find("::") + 2:].lower() if "::" in key else key.lower()
        funcnames[s.lower()] = value

    offs = funcnames.get(funcname.lower(), -1)
    # Second best way, exact function name
    if offs != -1:
        return offs

    return -1
Esempio n. 31
0
	def get_method_name(self, esp):

		stringp = self.get_method_name_func(idc.get_wide_dword(esp + 4), 0)
		address = idc.get_wide_dword(stringp + 0x8)
		return idc.get_strlit_contents(address, -1, idc.STRTYPE_C)