Exemplo n.º 1
0
 def patch_segment(self, seg_name):
     for seg in self.segments:
         if seg_name in seg['name']:
             print("patch %s: 0x%x - 0x%x" %
                   (seg['name'], seg['start'], seg['end']))
             for i in range(len(seg['data'])):
                 idc.patch_byte(seg['start'] + i, seg['data'][i])
def deobfuscate_rets(ea):
    if idc.get_wide_byte(ea) == 0x83:
        fill_with_nops(ea, ea + 7)
    else:
        fill_with_nops(ea, ea + 8)

    idc.patch_byte(ea, 0xC3)
    idc.create_insn(ea)

    return True
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
Exemplo n.º 4
0
    def dbg_process_start(self, pid, tid, ea, name, base, size):

        self.mem_for_inline_hooks = 0
        self.virtualalloc = 0

        ntdll = DllHook('ntdll.dll')
        ntdll.add_func(
            FuncHook('ntdll_NtClose', NtClose_inline_hook_code_32,
                     NtClose_bpt_cond_hook_code_32))
        ntdll.add_func(
            FuncHook('ntdll_NtQueryInformationProcess',
                     NtQueryInformationProcess_inline_hook_code_32,
                     NtQueryInformationProcess_bpt_cond_hook_code_32))

        self.dlls = [ntdll]

        # IDA creates a segment named "TIB[XXXXXXXX]", which points to
        # wow_peb64 antually. We can get peb from wow_peb64 with 0x1000 offset.
        #               peb_addr = wow_peb64_addr + 0x1000
        # Note: IDA has not created segment "TIB[XXXXXXXX]" at this point.

        # tid = get_current_thread()
        # tib_segm_name = "TIB[%08X]" % tid
        # print tib_segm_name
        # tib_segm = get_segm_by_name(tib_segm_name)
        # wow_peb64 = tib_segm.start_ea
        # peb = tib_segm.start_ea + 0x1000

        # on debugging start, ebx points to peb
        # get addrs of peb and wow_peb64
        ebx = idc.get_reg_value("ebx")
        peb = ebx
        wow_peb64 = peb - 0x1000

        # patch peb->BeingDebugged
        # solving peb->NtGlobalFlag and "Heap Magic" anti-debug method
        # at the same time.
        idc.patch_byte(peb + 2, 0)
        idc.patch_byte(wow_peb64 + 2, 0)

        # patching peb process paramters
        peb_process_parameters = idaapi.get_dword(peb + 0x10)
        flag = idaapi.get_dword(peb_process_parameters + 0x8)
        idc.patch_dword(peb_process_parameters + 0x8, flag | 0x4000)

        # patching peb64 process paramters
        peb64_process_parameters = idaapi.get_qword(wow_peb64 + 0x20)
        flag = idaapi.get_dword(peb64_process_parameters + 0x8)
        idc.patch_dword(peb64_process_parameters + 0x8, flag | 0x4000)
def resolve_calls_through_register(ea):
    next_instr_addr = idc.get_wide_dword(ea + 1)

    # Check if that's just a parameter passing through stack
    if ea & 0xFFFF0000 != next_instr_addr & 0xFFFF0000:
        return

    if next_instr_addr - ea > 0x100:
        return

    if idc.get_wide_byte(ea + 6) & 0xF0 in [0x20, 0xE0]:
        call_param = 0x9000 + idc.get_wide_byte(ea + 6) ^ 0x30
    else:
        call_param = idc.get_wide_word(ea + 6) ^ 0x30

    fill_with_nops(ea, next_instr_addr)
    idc.patch_byte(ea, 0xFF)
    idc.patch_word(ea + 1, call_param)
    idc.create_insn(ea)

    return True
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
Exemplo n.º 7
0
 def cmd_patch_byte(self, a, v):
     if idc.patch_byte(int(a, 0), int(v, 0)):
         return "ok"
     return ""
Exemplo n.º 8
0
def memset_seg(ea, size):
    for i in range(0, size):
        idc.patch_byte(ea + i, 0)