def start_patch(leetbabes): dec_key_data = [['0x7777', '0x700000018', '0x8', '0x41', '0x0'], ['0x7777', '0x7000000018', '0x8', '0x42', '0x0'], ['0x7777', '0xdb00000018', '0x8', '0x43', '0x0'], ['0x7777', '0x3b00000018', '0x8', '0x27', '0x0'], ['0x7777', '0xa300000018', '0x8', '0x94', '0x0'], ['0x707', '0x700000014', '0x8', '0x41', '0x0'], ['0x707', '0x800000014', '0x8', '0x42', '0x0'], ['0x707', '0xb00000014', '0x8', '0x43', '0x0'], ['0x707', '0x700000014', '0x8', '0x27', '0x0'], ['0x707', '0x700000014', '0x8', '0x94', '0x0'], ['0xaabb', '0x700000014', '0x8', '0x41', '0x0'], ['0xaabb', '0xb00000014', '0x8', '0x42', '0x0'], ['0xaabb', '0x1200000014', '0x8', '0x43', '0x0'], ['0xaabb', '0x800000014', '0x8', '0x27', '0x0'], ['0xaabb', '0xc00000014', '0x8', '0x94', '0x0'], ['0x202', '0x700000018', '0x8', '0x41', '0x0'], ['0x202', '0x9000000018', '0x8', '0x42', '0x0'], ['0x202', '0x11b00000018', '0x8', '0x43', '0x0'], ['0x202', '0x4b00000018', '0x8', '0x27', '0x0'], ['0x202', '0xd300000018', '0x8', '0x94', '0x0'], ['0xabcd', '0x700000018', '0x8', '0x41', '0x0'], ['0xabcd', '0x9000000018', '0x8', '0x42', '0x0'], ['0xabcd', '0x11c00000018', '0x8', '0x43', '0x0'], ['0xabcd', '0x4b00000018', '0x8', '0x27', '0x0'], ['0xabcd', '0xd300000018', '0x8', '0x94', '0x0'], ['0x1234', '0x700000018', '0x8', '0x41', '0x0'], ['0x1234', '0x7700000018', '0x8', '0x42', '0x0'], ['0x1234', '0xe900000018', '0x8', '0x43', '0x0'], ['0x1234', '0x3e00000018', '0x8', '0x27', '0x0'], ['0x1234', '0xad00000018', '0x8', '0x94', '0x0'], ['0x301', '0x700000018', '0x8', '0x41', '0x0'], ['0x301', '0x7800000018', '0x8', '0x42', '0x0'], ['0x301', '0xec00000018', '0x8', '0x43', '0x0'], ['0x301', '0x3f00000018', '0x8', '0x27', '0x0'], ['0x301', '0xaf00000018', '0x8', '0x94', '0x0']] dec_key_data = [[int(x,16) for x in lst] for lst in dec_key_data] for leetbabe_addr in leetbabes: feedcode_addr = FindBinary(leetbabe_addr, SEARCH_DOWN , "DE C0 ED FE") deadcode_addr = FindBinary(leetbabe_addr, SEARCH_DOWN , "DE C0 AD DE") print("1337BABE @ "+hex(leetbabe_addr)) print("FEEDC0DE @ "+hex(feedcode_addr)) print("DEADC0DE @ "+hex(deadcode_addr)) ref_bytes = Qword(leetbabe_addr+4) & 0xffff for qword in dec_key_data: if qword[0] == ref_bytes: patch_addr = leetbabe_addr + 4 + (qword[1] & 0xff) + (qword[1] >> 32) crackme_bytes = Qword(patch_addr) dec_res = decrypt(crackme_bytes, qword) print("Patching " + hex(crackme_bytes) + " with " + hex(dec_res) + " @ " + hex(patch_addr)) ida_bytes.patch_qword(patch_addr, dec_res) print("Patching unnecessary code with NOPS :)") ida_bytes.patch_bytes(leetbabe_addr-1, "\x90"*7) # 0xcc + 1337babe + 2 bytes ida_bytes.patch_bytes(feedcode_addr, "\x90"*4) # feedc0de ida_bytes.patch_bytes(deadcode_addr-1, "\x90"*5) # 0xcc + deadc0de print("======================================")
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))
def patch_word(ea, value, wordsize=WORD_SIZE): """Patch the word at the given address. Words are patched using PatchByte(), PatchWord(), PatchDword(), or PatchQword(), as appropriate. """ if wordsize == 1: ida_bytes.patch_byte(ea, value) elif wordsize == 2: ida_bytes.patch_word(ea, value) elif wordsize == 4: ida_bytes.patch_dword(ea, value) elif wordsize == 8: ida_bytes.patch_qword(ea, value) else: raise ValueError('Invalid argument: wordsize={}'.format(wordsize))
def set_qword(ea, value): """ Static method allowing to set the value of one qwordat an address. :param ea: The address at which changing the value. :param value: The value to set at the address. :raise RuntimeError: If it was not possible to change the value. """ if not ida_bytes.patch_qword(ea, value): raise RuntimeError("Unable to set value {} at {}".format(ea, value))
def value(self, value): """ Property setter which allow to set the value of this object. This property works only if the :meth:`~BipData.is_numerable` property returned True. If this object has no data (:meth:`~BipData.has_data` property return False) or is unknown (:meth:`~BipData.is_unknwon` return True) the value set is considered to be on 1 byte. For setting non numerical value or value on more than 8 bytes use the :meth:`~BipElt.bytes` property setter. This property is link to the type defined or guessed by IDA and it is a good idea to assure you have the proper type before using it. :param int value: An integer to which set the value of the current data element. :raise RuntimeError: If the setting of the value failed or if the value could not be set because of an unknown type. """ if self.value == value: # case where we are setting at the same value return if (not self.has_data) or self.is_unknown or self.is_byte: if not ida_bytes.patch_byte(self.ea, value): raise RuntimeError("Unable to patch value: {}".format(self)) elif self.is_word: if not ida_bytes.patch_word(self.ea, value): raise RuntimeError("Unable to patch value: {}".format(self)) elif self.is_dword: if not ida_bytes.patch_dword(self.ea, value): raise RuntimeError("Unable to patch value: {}".format(self)) elif self.is_qword: if not ida_bytes.patch_qword(self.ea, value): raise RuntimeError("Unable to patch value: {}".format(self)) else: raise RuntimeError("Unable to patch value: {}".format(self))
def patch(patches): for i in patches: print(hex(i[0])) ida_bytes.patch_qword(i[0], i[1])
(0x13bd , 0x28c197b658b3b38d), (0x13c4 , 0x1ebfc4589ffc1d0), (0x13ba , 0x3bc43e2f0001b807), (0x13be , 0xffffffb805eb0000) ] patches_calculate = [ (0x1373 , 0x17e27f613f63871), (0x1376 , 0x1ebfc453a63b257), (0x1372 , 0x89d001e4458bc289) ] # Patch the irrelevant 0xCC bytes rip = [0x17f9, 0x16d4, 0x17cb, 0x1404, 0x13b2, 0x13d2, 0x136b, 0x1384, 0x152d] CC = [0x17dc, 0x16b7, 0x17c6, 0x13E7, 0x1399, 0x13cd, 0x1352, 0x137f, 0x1528] for i in range(len(rip)): ida_bytes.patch_bytes(CC[i], '\x90'*(rip[i] - CC[i]) # Patch the encrypted bytes def patch(patches): for i in patches: print(hex(i[0])) ida_bytes.patch_qword(i[0], i[1]) patch(patches_main) patch(patches_read_file) patch(patches_check_key) patch(patches_compare_char) patch(patches_calculate)