Exemplo n.º 1
0
    def apply(self):
        """
        Apply patches to found opaque branch
        :return: None
        """

        for src, dst in self._flow_patches_map.items():
            ir_block: IRBlock = self._ir_cfg.get_block(src)

            asm_instr = ir_block.assignblks[ir_block.dst_linenb].instr

            if asm_instr.name not in conditional_branch:
                log(f"Unsupported asm pattern at {hex(src)}", code='!')
                continue

            patch_addr = asm_instr.offset

            opcode1 = ida_bytes.get_byte(patch_addr)

            # Fast and Furious
            if opcode1 == 0x0F:
                ida_bytes.patch_bytes(
                    patch_addr,
                    b"\xe9" + pack("<I",
                                   (dst - (patch_addr + 5)) & (2**32 - 1)))
            elif ((opcode1 & 0xe0) == 0xe0) or ((opcode1 & 0x70) == 0x70):
                ida_bytes.patch_byte(patch_addr, 0xeb)
                ida_bytes.patch_byte(patch_addr + 1,
                                     (dst - (patch_addr + 2)) & 0xFF)
            else:
                log(f"Unknown first part of opcode at {hex(patch_addr)}",
                    code='!')
                continue

            log(f"Apply patch JCC -> JMP at {hex(patch_addr)}")
Exemplo n.º 2
0
def main():
    print('[*] start debfuscation')

    for s in get_code_segments():
        print('[*] try to deobfuscate {} section'.format(
            ida_segment.get_segm_name(s)))

        if s.use32():
            junk_patterns = junk_patterns_x86
        elif s.use64():
            junk_patterns = junk_patterns_x64
        else:
            print('[!] unsupported arch')

        print('[*] replace junk code to nop')
        for pattern, pattern_len in junk_patterns:
            addr_from = idc.find_binary(s.start_ea, ida_search.SEARCH_DOWN,
                                        pattern)
            while addr_from != idaapi.BADADDR and addr_from < s.end_ea:
                ida_bytes.patch_bytes(addr_from, '\x90' * pattern_len)
                addr_from = idc.find_binary(addr_from + pattern_len,
                                            ida_search.SEARCH_DOWN, pattern)

        print('[*] hide nop code')
        addr_from = ida_search.find_text(
            s.start_ea, 0, 0, 'nop',
            ida_search.SEARCH_CASE | ida_search.SEARCH_DOWN)
        while addr_from != idaapi.BADADDR and addr_from < s.end_ea:
            func_offset = idc.get_func_off_str(addr_from)
            if type(func_offset) == str and func_offset.find('+') == -1:
                addr_from = ida_search.find_text(
                    idc.next_head(addr_from), 0, 0, 'nop',
                    ida_search.SEARCH_CASE | ida_search.SEARCH_DOWN)
            else:
                i = 0
                while True:
                    if ida_bytes.get_byte(addr_from + i) == 0x90:
                        i += 1
                    else:
                        break
                if i >= 3:
                    idc.add_hidden_range(addr_from, addr_from + i, 'nop', None,
                                         None, 0xFFFFFFFF)
                    print("%08X" % addr_from)
                addr_from = ida_search.find_text(
                    idc.next_head(addr_from + i), 0, 0, 'nop',
                    ida_search.SEARCH_CASE | ida_search.SEARCH_DOWN)

        #print('[*] renanlyze')
        #idc.del_items(s.start_ea, size=s.size())
        #time.sleep(1)
        #idc.plan_and_wait(s.start_ea, s.end_ea)
    print('[*] done')
Exemplo n.º 3
0
def main():
    # generated by create_patch.py
    # test_tamper.exe
    patches = [(5368713922L, '\xeb\x05'), (5368713991L, '\x90\x90')]
    # patches = [(5368713887L, '\x90\x90\x90'), (5368713890L, '\x90\x90\x90'), (5368714371L, '\x90'), (5368713914L, '\x90\x90'), (5368713893L, '\x90\x90\x90'), (5368714256L, '\x90'), (5368713896L, '\x90\x90\x90\x90\x90'), (5368713910L, '\x90\x90\x90\x90'), (5368713901L, '\x90\x90\x90'), (5368713916L, '\xeb\x05'), (5368713904L, '\x90\x90\x90'), (5368713907L, '\x90\x90\x90'), (5368713878L, '\x90\x90\x90\x90'), (5368713882L, '\x90\x90'), (5368713979L, '\x90\x90\x90'), (5368713884L, '\x90\x90\x90')]

    # test_medium.exe
    # patches = [(5368713486L, '\xeb\x05'), (5368714020L, '\x90\x90'), (5368713951L, '\xeb\x05'), (5368713555L, '\x90\x90'), (5368713833L, '\x90\x90\x90\x90\x90\x90')]

    # test_large_debug.exe
    # patches = [(5368714301L, '\xeb\x05'), (5368714826L, '\xeb\x05'), (5368713575L, '\xeb\x05'), (5368714370L, '\x90\x90\x90\x90\x90\x90'), (5368713348L, '\x90\x90\x90\x90\x90\x90'), (5368714893L, '\x90\x90\x90\x90\x90\x90'), (140724005432014L, '\x90\x90'), (5368713425L, '\x90\x90\x90\x90\x90\x90'), (5368713644L, '\x90\x90'), (5368714678L, '\x90\x90\x90\x90\x90\x90'), (140724005415877L, '\xeb\x12')]
    for addr, val in patches:
        print('patching {:#x} with {}'.format(addr, hexlify(val)))
        ida_bytes.patch_bytes(addr, val)
Exemplo n.º 4
0
def patch(ea, data):
    if ida_api_is_new:
        return ida_bytes.patch_bytes(ea, data)
    else:
        for b in data:
            idc.PatchByte(ea, struct.unpack('B', b)[0])
            ea += 1
Exemplo n.º 5
0
    def bytes(self, value):
        """
            Setter allowing to change the bytes value of the element.

            .. warning::

                No check is made on the size of the array of the setter and
                it can rewrite more than the size of the element,

            :param value: A list of int corresponding to the bytes to change.
        """
        if isinstance(value, bytes):
            ida_bytes.patch_bytes(self.ea, value)
        elif isinstance(value, list):
            i = 0
            for e in value:
                ida_bytes.patch_byte(self.ea + i, e)
                i += 1
        else:
            raise TypeError(
                "Invalid arg {} for BipElt.bytes setter".format(value))
Exemplo n.º 6
0
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("======================================")
Exemplo n.º 7
0
patches_compare_char = [(0x13b9, 0xb04a5b749d359b75),
                        (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], b'\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)
Exemplo n.º 8
0
                  buf[dst:dst + 3].encode('hex'))
    else:
        pass
    p = buf.find(pattern, p + 1)

# stx / jx
fake_jcc = ['\xF8\x73', '\xF9\x72']
for pattern in fake_jcc:
    p = buf.find(pattern)
    while p != -1:
        if ord(buf[p + 2]) < 0x80:
            dst = p + 3 + ord(buf[p + 2])
            ln = dst - p
            patch_at(p, ln)
        else:
            print("CLC", hex(p + addr))
        p = buf.find(pattern, p + 1)

fake_jcc = ['\x7C\x03\xEB\x03']
for pattern in fake_jcc:
    p = buf.find(pattern)
    while p != -1:
        if buf[p + 5:p + 5 + 2] == '\x74\xFB':
            ln = 7
            patch_at(p, ln)
        else:
            print("CLC", hex(p + addr))
        p = buf.find(pattern, p + 1)

patch_bytes(addr, buf)
print('done')
Exemplo n.º 9
0
buf = get_bytes(addr, 0x4E837D - addr)


def patch_at(p, ln):
    global buf
    buf = buf[:p] + "\x90" * ln + buf[p + ln:]


pattern = 'B00184C00F85'.decode('hex')
p = buf.find(pattern)
while p != -1:
    if buf[p + 6 + 4:p + 6 + 4 + 5] == '\xE9\x00\x00\x00\x00':
        dst = p + 6 + 4 + get_dword(addr + p + 6)
        off = dst - p - 5
        t = '\xE9' + pack('<I', off)
        t = t.ljust(6 + 4 + 5, '\x90')
        patch_bytes(addr + p, t)
        print(hex(addr + p), hex(addr + dst))
    else:
        pass
    p = buf.find(pattern, p + 1)

pattern = '31C088C184C90F85'.decode('hex')
p = buf.find(pattern)
while p != -1:
    if buf[p + 8 + 4:p + 8 + 4 + 5] == '\xE9\x00\x00\x00\x00':
        patch_bytes(addr + p, '\x90' * (8 + 4 + 5))
        print(hex(addr + p), hex(addr + dst))
    else:
        pass
    p = buf.find(pattern, p + 1)
Exemplo n.º 10
0
 def on_patchnop(self, code=0):
     from ida_bytes import patch_bytes
     patch_bytes(here(), '\x90' * get_item_size(here()))
     self.Close(0)
Exemplo n.º 11
0
import ida_bytes


#decryption of encrypted bytes
def decrypt_data(encrypted_bytes):
    xor_key = b'f424'
    decrypted_bytes = b""
    for i in encrypted_bytes:  #be careful each byte is process through round as integer, dont want to process null bytes
        if i != 0:  #result of "not" operation "~" is signed int and must be converted to unsigned (& 0xff)
            decrypted_bytes += ((~(((
                (i ^ xor_key[0]) ^ xor_key[1]) ^ xor_key[2]) ^ xor_key[3]))
                                & 0xff).to_bytes(1,
                                                 byteorder='big',
                                                 signed=False)
        else:
            decrypted_bytes += i.to_bytes(1, byteorder='big', signed=False)
    return decrypted_bytes


start_address = 0x405068  #start address of encrypted bytes
end_address = 0x405388  #end address of encrypted bytes
size = end_address - start_address  #size of encrypted bytes
original_bytes = ida_bytes.get_bytes(start_address,
                                     size)  #getting all encrypted bytes
decrypted_bytes = decrypt_data(original_bytes)
ida_bytes.patch_bytes(
    start_address,
    decrypted_bytes)  #patching original bytes with decrypted bytes

print("Bytes decrypted - start address: 0x%x" % (start_address))
Exemplo n.º 12
0
def handler(s):
    global REG_D, REG_S
    print("-------------Found-----------")
    g0 = s.group(0)
    print("---->Orig bytes and assemble")
    print_bytes(g0)
    dism(g0)

    print(REG_D, REG_S)
    print("---->Replace bytes and assemble")
    dism_str = "mov {},{}".format(REG_D, REG_S)
    print(dism_str + '\nnop')
    mov_encode = asm(dism_str)
    nop_encode = asm('nop')
    replace_encode = mov_encode + nop_encode

    print[hex(b) for b in replace_encode]
    r = bytearray(replace_encode)
    print(r, type(r))
    return str(r)


pattern = r'[\x00-\xFF]\xB4[\x00-\xFF]\xBC'

buf = re.sub(pattern, handler, buf, flags=re.I)

#print_bytes(buf)

# patch
patch_bytes(startAddr, buf)