def show_fill_form(self): selection, start_ea, end_ea = idaapi.read_selection() if not selection: start_ea = idaapi.get_screen_ea() end_ea = start_ea + 1 # Default fill value fill_value = 0x00 # Create the form f = PatchFillForm(start_ea, end_ea, fill_value) # Execute the form ok = f.Execute() if ok == 1: # Get updated values start_ea = f.intStartEA.value end_ea = f.intEndEA.value fill_value = f.intPatch.value # Now apply newly patched bytes # NOTE: fill_value is expected to be one byte # so if a user provides a larger patch_byte() # will trim the value as expected. for ea in range(start_ea, end_ea): idaapi.patch_byte(ea, fill_value) # Refresh all IDA views self.patch_view.Refresh() # Dispose the form f.Free()
def x86_nop_region(self): selection, start_ea, end_ea = idaapi.read_selection() if not selection: start_ea = idaapi.get_screen_ea() end_ea = start_ea + 1 fill_value = 0x90 for ea in range(start_ea, end_ea): idaapi.patch_byte(ea, fill_value) # Refresh all IDA views self.patch_view.Refresh()
def activate(self, ctx): info = idaapi.get_inf_structure() selection = idaapi.read_selection() start = selection[1] end = selection[2] if selection[0] == False: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print 'Easy Nop :: Screen EA == idaapi.BADADDR' return 0 end = start + idaapi.get_item_size(start) else: end += idaapi.get_item_size(end) if start == idaapi.BADADDR: print 'Easy Nop :: Selection EA == idaapi.BADADDR' return 0 if start == end: print 'Easy Nop :: Nothing to nop' return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print end print start return 1
def activate(self, ctx): t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() end += idaapi.get_item_size(end) else: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print('Easy Nop :: Screen EA == idaapi.BADADDR') return 0 end = start + idaapi.get_item_size(start) if start == idaapi.BADADDR: print('Easy Nop :: Selection EA == idaapi.BADADDR') return 0 if start == end: print('Easy Nop :: Nothing to nop') return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print(end) print(start) return 1
def revert_patch(va, nr): """Unpatch the opcodes at @va, reverting them to their original value. Args: va (numbers.Integral): Address of the location of the patch to revert nr (numbers.Integral): Number of bytes to scan and revert Returns: bool: True if patched bytes were restored """ ret = False orig = [ida_bytes.get_original_byte(va + i) for i in range(nr)] current = [idc.get_wide_byte(va + i) for i in range(nr)] for i in range(len(orig)): if orig[i] != current[i]: ret = True idaapi.patch_byte(va + i, orig[i]) return ret
def show_fill_form(self): selection, start_ea, end_ea = idaapi.read_selection() if not selection: start_ea = idaapi.get_screen_ea() end_ea = start_ea + 1 # Default fill value fill_value = 0x90 #nop # Create the form f = PatchFillForm(start_ea, end_ea, fill_value) # Execute the form ok = f.Execute() if ok == 1: # Get updated values start_ea = f.intStartEA.value end_ea = f.intEndEA.value fill_value = f.intPatch.value # Now apply newly patched bytes # NOTE: fill_value is expected to be one byte # so if a user provides a larger patch_byte() # will trim the value as expected. for ea in range(start_ea, end_ea): idaapi.patch_byte(ea, fill_value) # Refresh all IDA views self.patch_view.refreshitems() idaapi.refresh_idaview_anyway() # Dispose the form f.Free()
def _patch(address, patch_data, len): ea = address orig_data = '' invalid_value = False while ea < (address+len): if not invalid_value: orig_byte = idc.Byte(ea) if not idc.hasValue(idc.GetFlags(ea)): print("Keypatch: WARNING: 0x{:X} has no defined value. ".format(ea)) invalid_value = True else: orig_data += chr(orig_byte) patch_byte = ord(patch_data[ea - address]) if patch_byte != orig_byte: # patch one byte if idaapi.patch_byte(ea, patch_byte) != 1: print("Keypatch: FAILED to patch byte at 0x{:X} [0x{:X}]".format(ea, patch_byte)) break ea += 1 return (ea-address, orig_data)
import idaapi from idaapi import Choose2 start_ea = 0x7C19 for ix in xrange(0xCF): print ix byte_to_decr = idaapi.get_byte(start_ea + ix) to_rotate = (0xCF - ix) % 8 byte_decr = (byte_to_decr >> to_rotate) | (byte_to_decr << (8 - to_rotate)) idaapi.patch_byte(start_ea + ix, byte_decr)
def patchByte(self, ea, val): return idaapi.patch_byte(ea, val)
for head in idautils.Heads(): for xr in idautils.XrefsFrom(head, 0): if xr.type == 19: next = head + idaapi.get_item_size(head) if idc.Byte(next) == 0xFF: continue for xr2 in idautils.XrefsFrom(next, 0): next_next = next + idaapi.get_item_size(next) if (xr2.type == 19) and (xr2.to == next_next): db = head + idaapi.get_item_size(head) if idc.Byte(head) == 0x0F: idaapi.patch_byte(head, 0x90) idaapi.patch_byte(head + 1, 0xE9) else: idaapi.patch_byte(head, 0xEB) idc.MakeUnknown(db, xr.to - db + 0x10, idaapi.DOUNK_SIMPLE) idc.MakeCode(xr.to) i = db while i < xr.to: if (i + 4) < xr.to: idc.MakeDword(i) i += 4 else: idc.MakeByte(i) i += 1
def decrypt(start, end, key): iKey = 0 for i in xrange(start, end): patch_byte(i, get_byte(i) ^ ord(key[iKey % len(key)])) iKey += 1
idc.get_strlit_contents( cpu.rdi, -1, STRTYPE_C)) cpu.rax = -2 # ENOENT seems reasonable since we can't do this anyway return 1 #actually break else: #60 exit warning("process exited") return 1 #actually break else: #vfork pass elif sc > 61: if sc < 64: if sc == 62: #kill pass else: #uname for i, ch in enumerate("Linux"): idaapi.patch_byte(cpu.rdi + i, ord(ch)) for i, ch in enumerate("ubuntu"): idaapi.patch_byte(cpu.rdi + i + 0x41, ord(ch)) for i, ch in enumerate("4.4.0-119-generic"): idaapi.patch_byte(cpu.rdi + i + 0x82, ord(ch)) for i, ch in enumerate( "#143-Ubuntu SMP Mon Apr 2 16:08:24 UTC 2018" ): idaapi.patch_byte(cpu.rdi + i + 0xc3, ord(ch)) for i, ch in enumerate("x86_64"): idaapi.patch_byte(cpu.rdi + i + 0x104, ord(ch)) elif sc > 64:
def repeating_key_xor(start_address, buffer_len, key): for i in xrange(buffer_len): c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))]) idaapi.patch_byte(start_address + i, c) return
def PatchBytes(ea, replaceList): for i in range(len(replaceList)): if replaceList[i] != -1: idaapi.patch_byte(ea + i, replaceList[i])
def nopItem(ea): #nops = [0x90] * (nextHead(ea) - ea) #idaapi.patch_many_bytes(ea, nops) for patch_ea in range(ea, nextHead(ea)): idaapi.patch_byte(patch_ea, 0x90)
# Make sure we aren't handling jump tables if idc.Byte(next_head) == 0xFF: continue # Now check that the next instruction is a direct jump of length 0 for xref2 in idautils.XrefsFrom(next_head, 0): third_head = next_head + idaapi.get_item_size(next_head) if (xref2.type == 19) and (xref2.to == third_head): db = head + idaapi.get_item_size(head) print "Bad jump: %8X -> %8X, changing to direct JMP" % (head, xref.to) # Change head to a direct jump if idc.Byte(head) == 0x0F: idaapi.patch_byte(head, 0x90) idaapi.patch_byte(head+1, 0xE9) else: idaapi.patch_byte(head, 0xEB) # Undefine and redefine code borders idc.MakeUnknown(db, xref.to - db + 0x10, idaapi.DOUNK_SIMPLE) idc.MakeCode(xref.to) # Convert the bad code into bytes i = db while i < xref.to: if (i+4) < xref.to: idc.MakeDword(i) i += 4 else:
if sc == 59: #execve msg("execve(\"%s\", ...)\n" % idc.get_strlit_contents(cpu.rdi, -1, STRTYPE_C)) cpu.rax = -2 # ENOENT seems reasonable since we can't do this anyway return 1 #actually break else: #60 exit warning("process exited") return 1 #actually break else: #vfork pass elif sc > 61: if sc < 64: if sc == 62: #kill pass else: #uname for i, ch in enumerate("Linux"): idaapi.patch_byte(cpu.rdi + i, ord(ch)) for i, ch in enumerate("ubuntu"): idaapi.patch_byte(cpu.rdi + i + 0x41, ord(ch)) for i, ch in enumerate("4.4.0-119-generic"): idaapi.patch_byte(cpu.rdi + i + 0x82, ord(ch)) for i, ch in enumerate("#143-Ubuntu SMP Mon Apr 2 16:08:24 UTC 2018"): idaapi.patch_byte(cpu.rdi + i + 0xc3, ord(ch)) for i, ch in enumerate("x86_64"): idaapi.patch_byte(cpu.rdi + i + 0x104, ord(ch)) elif sc > 64: if sc == 65: #semop pass else: #semctl pass else: #semget pass
def selfmod_decoder(rip_address): if ((rip_address > 0x400935) and (rip_address <= 0x40103D)): idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF)) return
def __call__(self): idaapi.patch_byte(self.ea, self.value)