def build_peb(jitter, peb_address):
    """
    Build PEB informations using following structure:

    +0x000 InheritedAddressSpace    : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged            : UChar
    +0x003 SpareBool                : UChar
    +0x004 Mutant                   : Ptr32 Void
    +0x008 ImageBaseAddress         : Ptr32 Void
    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
    +0x010 processparameter

    @jitter: jitter instance
    @peb_address: the PEB address
    """

    offset = peb_address + 8
    o = ""
    if main_pe:
        o += pck32(main_pe.NThdr.ImageBase)
    else:
        offset += 4
    o += pck32(peb_ldr_data_address)
    o += pck32(process_parameters_address)
    jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o)
Example #2
0
def fix_InInitializationOrderModuleList(myjit, module_info):
    # first binary is ntdll
    # second binary is kernel32
    olist = []
    ntdll_e = None
    kernel_e = None
    for bname, (addr, e) in module_info.items():
        if bname[::2].lower() == "ntdll.dll":
            ntdll_e = (e, bname, addr)
            continue
        elif bname[::2].lower() == "kernel32.dll":
            kernel_e = (e, bname, addr)
            continue
        elif e == dummy_e:
            d_e = (e, bname, addr)
            continue
        elif e == main_pe:
            continue
        olist.append((e, bname, addr))
    if not ntdll_e or not kernel_e or not d_e:
        log.warn('No kernel ntdll, ldr data will be unconsistant')
    else:
        olist[0:0] = [ntdll_e]
        olist[1:1] = [kernel_e]

    olist.append(d_e)

    last_addr = 0
    for i in xrange(len(olist)):
        e, bname, addr = olist[i]
        p_e, p_bname, p_addr = olist[(i - 1) % len(olist)]
        n_e, n_bname, n_addr = olist[(i + 1) % len(olist)]
        myjit.vm.set_mem(
            addr + 0x10, pck32(n_addr + 0x10) + pck32(p_addr + 0x10))
def fix_InInitializationOrderModuleList(jitter, modules_info):
    """Fix InInitializationOrderModuleList double link list. First module is the
    ntdll, then kernel32. dummy is last pe.

    @jitter: the jitter instance
    @modules_info: the LoadedModules instance

    """

    log.debug("Fix InInitializationOrderModuleList")
    main_pe = modules_info.name2module.get(main_pe_name, None)
    kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
    dummy_pe = modules_info.name2module.get("", None)
    special_modules = [main_pe, kernel32_pe, ntdll_pe, dummy_pe]
    if not all(special_modules):
        log.warn('No main pe, ldr data will be unconsistant')
        loaded_modules = modules_info.modules
    else:
        loaded_modules = [module for module in modules_info.modules
                          if module not in special_modules]
        loaded_modules[0:0] = [ntdll_pe]
        loaded_modules[1:1] = [kernel32_pe]
        loaded_modules.append(dummy_pe)

    for i, module in enumerate(loaded_modules):
        cur_module_entry = modules_info.module2entry[module]
        prev_module = loaded_modules[(i - 1) % len(loaded_modules)]
        next_module = loaded_modules[(i + 1) % len(loaded_modules)]
        prev_module_entry = modules_info.module2entry[prev_module]
        next_module_entry = modules_info.module2entry[next_module]
        jitter.vm.set_mem(cur_module_entry + 0x10,
                          (pck32(next_module_entry + 0x10) +
                           pck32(prev_module_entry + 0x10)))
Example #4
0
def add_process_parameters(myjit):
    o = ""
    o += pck32(0x1000)  # size
    o += "E" * (0x48 - len(o))
    o += pck32(process_environment_address)
    myjit.vm.add_memory_page(process_parameters_address,
                             PAGE_READ | PAGE_WRITE, o)
def init_seh(jitter):
    """
    Build the modules entries and create double links
    @jitter: jitter instance
    """

    global seh_count
    seh_count = 0
    build_teb(jitter, FS_0_AD)
    build_peb(jitter, peb_address)

    modules_info = create_modules_chain(jitter, name2module)
    fix_InLoadOrderModuleList(jitter, modules_info)
    fix_InMemoryOrderModuleList(jitter, modules_info)
    fix_InInitializationOrderModuleList(jitter, modules_info)

    build_ldr_data(jitter, modules_info)
    add_process_env(jitter)
    add_process_parameters(jitter)

    jitter.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
        0xffffffff) + pck32(0x41414141) + pck32(0x42424242))

    jitter.vm.add_memory_page(
        context_address, PAGE_READ | PAGE_WRITE, '\x00' * 0x2cc)
    jitter.vm.add_memory_page(
        exception_record_address, PAGE_READ | PAGE_WRITE, '\x00' * 200)

    jitter.vm.add_memory_page(
        FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE, 0x10000 * "\x00")
Example #6
0
def init_seh(myjit):
    global seh_count
    seh_count = 0
    build_teb(myjit, FS_0_AD)
    build_peb(myjit, peb_address)

    module_info = create_modules_chain(myjit, loaded_modules)
    fix_InLoadOrderModuleList(myjit, module_info)
    fix_InMemoryOrderModuleList(myjit, module_info)
    fix_InInitializationOrderModuleList(myjit, module_info)

    build_ldr_data(myjit, module_info)
    add_process_env(myjit)
    add_process_parameters(myjit)

    myjit.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
        0xffffffff) + pck32(0x41414141) + pck32(0x42424242))

    myjit.vm.add_memory_page(
        context_address, PAGE_READ | PAGE_WRITE, '\x00' * 0x2cc)
    myjit.vm.add_memory_page(
        exception_record_address, PAGE_READ | PAGE_WRITE, '\x00' * 200)

    myjit.vm.add_memory_page(
        FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE, 0x10000 * "\x00")
Example #7
0
def init_seh(jitter):
    """
    Build the modules entries and create double links
    @jitter: jitter instance
    """

    global seh_count
    seh_count = 0
    build_teb(jitter, FS_0_AD)
    build_peb(jitter, peb_address)

    modules_info = create_modules_chain(jitter, name2module)
    fix_InLoadOrderModuleList(jitter, modules_info)
    fix_InMemoryOrderModuleList(jitter, modules_info)
    fix_InInitializationOrderModuleList(jitter, modules_info)

    build_ldr_data(jitter, modules_info)
    add_process_env(jitter)
    add_process_parameters(jitter)

    jitter.vm.add_memory_page(
        default_seh, PAGE_READ | PAGE_WRITE,
        pck32(0xffffffff) + pck32(0x41414141) + pck32(0x42424242))

    jitter.vm.add_memory_page(context_address, PAGE_READ | PAGE_WRITE,
                              '\x00' * 0x2cc)
    jitter.vm.add_memory_page(exception_record_address, PAGE_READ | PAGE_WRITE,
                              '\x00' * 200)

    jitter.vm.add_memory_page(FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE,
                              0x10000 * "\x00")
def build_teb(jitter, teb_address):
    """
    Build TEB informations using following structure:

    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    @jitter: jitter instance
    @teb_address: the TEB address
    """

    o = ""
    o += pck32(default_seh)
    o += (0x18 - len(o)) * "\x00"
    o += pck32(tib_address)

    o += (0x30 - len(o)) * "\x00"
    o += pck32(peb_address)
    o += pck32(0x11223344)

    jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o)
Example #9
0
def build_peb(jitter, peb_address):
    """
    Build PEB informations using following structure:

    +0x000 InheritedAddressSpace    : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged            : UChar
    +0x003 SpareBool                : UChar
    +0x004 Mutant                   : Ptr32 Void
    +0x008 ImageBaseAddress         : Ptr32 Void
    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
    +0x010 processparameter

    @jitter: jitter instance
    @peb_address: the PEB address
    """

    offset = peb_address + 8
    o = ""
    if main_pe:
        o += pck32(main_pe.NThdr.ImageBase)
    else:
        offset += 4
    o += pck32(peb_ldr_data_address)
    o += pck32(process_parameters_address)
    jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o)
Example #10
0
def fix_InInitializationOrderModuleList(myjit, module_info):
    # first binary is ntdll
    # second binary is kernel32
    olist = []
    ntdll_e = None
    kernel_e = None
    for bname, (addr, e) in module_info.items():
        if bname[::2].lower() == "ntdll.dll":
            ntdll_e = (e, bname, addr)
            continue
        elif bname[::2].lower() == "kernel32.dll":
            kernel_e = (e, bname, addr)
            continue
        elif e == dummy_e:
            d_e = (e, bname, addr)
            continue
        elif e == main_pe:
            continue
        olist.append((e, bname, addr))
    if not ntdll_e or not kernel_e or not d_e:
        log.warn('no kernel ntdll, ldr data will be unconsistant')
    else:
        olist[0:0] = [ntdll_e]
        olist[1:1] = [kernel_e]

    olist.append(d_e)

    last_addr = 0
    for i in xrange(len(olist)):
        e, bname, addr = olist[i]
        p_e, p_bname, p_addr = olist[(i - 1) % len(olist)]
        n_e, n_bname, n_addr = olist[(i + 1) % len(olist)]
        myjit.vm.set_mem(addr + 0x10,
                         pck32(n_addr + 0x10) + pck32(p_addr + 0x10))
Example #11
0
def build_teb(jitter, teb_address):
    """
    Build TEB informations using following structure:

    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    @jitter: jitter instance
    @teb_address: the TEB address
    """

    o = ""
    o += pck32(default_seh)
    o += (0x18 - len(o)) * "\x00"
    o += pck32(tib_address)

    o += (0x30 - len(o)) * "\x00"
    o += pck32(peb_address)
    o += pck32(0x11223344)

    jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o)
Example #12
0
def add_process_parameters(myjit):
    o = ""
    o += pck32(0x1000)  # size
    o += "E" * (0x48 - len(o))
    o += pck32(process_environment_address)
    myjit.vm.add_memory_page(process_parameters_address,
                             PAGE_READ | PAGE_WRITE,
                             o)
Example #13
0
def add_process_parameters(jitter):
    """
    Build a process parameters structure
    @jitter: jitter instance
    """

    o = ""
    o += pck32(0x1000)  # size
    o += "E" * (0x48 - len(o))
    o += pck32(process_environment_address)
    jitter.vm.add_memory_page(process_parameters_address,
                              PAGE_READ | PAGE_WRITE, o, "Process parameters")
def add_process_parameters(jitter):
    """
    Build a process parameters structure
    @jitter: jitter instance
    """

    o = ""
    o += pck32(0x1000)  # size
    o += "E" * (0x48 - len(o))
    o += pck32(process_environment_address)
    jitter.vm.add_memory_page(process_parameters_address,
                              PAGE_READ | PAGE_WRITE,
                              o)
Example #15
0
def set_link_list_entry(jitter, loaded_modules, modules_info, offset):
    for i, module in enumerate(loaded_modules):
        cur_module_entry = modules_info.module2entry[module]
        prev_module = loaded_modules[(i - 1) % len(loaded_modules)]
        next_module = loaded_modules[(i + 1) % len(loaded_modules)]
        prev_module_entry = modules_info.module2entry[prev_module]
        next_module_entry = modules_info.module2entry[next_module]
        if i == 0:
            prev_module_entry = peb_ldr_data_address + 0xC
        if i == len(loaded_modules) - 1:
            next_module_entry = peb_ldr_data_address + 0xC
        jitter.vm.set_mem(cur_module_entry + offset,
                          (pck32(next_module_entry + offset) +
                           pck32(prev_module_entry + offset)))
Example #16
0
def set_link_list_entry(jitter, loaded_modules, modules_info, offset):
    for i, module in enumerate(loaded_modules):
        cur_module_entry = modules_info.module2entry[module]
        prev_module = loaded_modules[(i - 1) % len(loaded_modules)]
        next_module = loaded_modules[(i + 1) % len(loaded_modules)]
        prev_module_entry = modules_info.module2entry[prev_module]
        next_module_entry = modules_info.module2entry[next_module]
        if i == 0:
            prev_module_entry = peb_ldr_data_address + 0xC
        if i == len(loaded_modules) - 1:
            next_module_entry = peb_ldr_data_address + 0xC
        jitter.vm.set_mem(cur_module_entry + offset,
                          (pck32(next_module_entry + offset) +
                           pck32(prev_module_entry + offset)))
Example #17
0
def regs2ctxt(jitter):
    """
    Build x86_32 cpu context for exception handling
    @jitter: jitload instance
    """

    ctxt = []
    # ContextFlags
    ctxt += [pck32(0x0)]
    # DRX
    ctxt += [pck32(0x0)] * 6
    # Float context
    ctxt += ['\x00' * 112]
    # Segment selectors
    ctxt += [
        pck32(reg)
        for reg in (jitter.cpu.GS, jitter.cpu.FS, jitter.cpu.ES, jitter.cpu.DS)
    ]
    # Gpregs
    ctxt += [
        pck32(reg) for reg in (jitter.cpu.EDI, jitter.cpu.ESI, jitter.cpu.EBX,
                               jitter.cpu.EDX, jitter.cpu.ECX, jitter.cpu.EAX,
                               jitter.cpu.EBP, jitter.cpu.EIP)
    ]
    # CS
    ctxt += [pck32(jitter.cpu.CS)]
    # Eflags
    # XXX TODO real eflag
    ctxt += [pck32(0x0)]
    # ESP
    ctxt += [pck32(jitter.cpu.ESP)]
    # SS
    ctxt += [pck32(jitter.cpu.SS)]
    return "".join(ctxt)
def regs2ctxt(jitter):
    """
    Build x86_32 cpu context for exception handling
    @jitter: jitload instance
    """

    ctxt = []
    # ContextFlags
    ctxt += [pck32(0x0)]
    # DRX
    ctxt += [pck32(0x0)] * 6
    # Float context
    ctxt += ['\x00' * 112]
    # Segment selectors
    ctxt += [pck32(reg) for reg in (jitter.cpu.GS, jitter.cpu.FS,
                                    jitter.cpu.ES, jitter.cpu.DS)]
    # Gpregs
    ctxt += [pck32(reg) for reg in (jitter.cpu.EDI, jitter.cpu.ESI,
                                    jitter.cpu.EBX, jitter.cpu.EDX,
                                    jitter.cpu.ECX, jitter.cpu.EAX,
                                    jitter.cpu.EBP, jitter.cpu.EIP)]
    # CS
    ctxt += [pck32(jitter.cpu.CS)]
    # Eflags
    # XXX TODO real eflag
    ctxt += [pck32(0x0)]
    # ESP
    ctxt += [pck32(jitter.cpu.ESP)]
    # SS
    ctxt += [pck32(jitter.cpu.SS)]
    return "".join(ctxt)
def return_from_seh(jitter):
    """Handle the return from an exception handler
    @jitter: jitter instance"""

    # Get current context
    context_address = upck32(jitter.vm.get_mem(jitter.cpu.ESP + 0x8, 4))
    log.info('Context address: %x', context_address)
    jitter.cpu.ESP = upck32(jitter.vm.get_mem(context_address + 0xc4, 4))
    log.info('New esp: %x', jitter.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(jitter.vm.get_mem(tib_address, 4))
    new_seh = upck32(jitter.vm.get_mem(old_seh, 4))
    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
    jitter.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(jitter)

    if jitter.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        ctxt_ptr = context_address
        log.info('Seh continues Context: %x', ctxt_ptr)

        # Get registers changes
        ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc)
        ctxt2regs(ctxt_str, jitter)
        jitter.pc = jitter.cpu.EIP
        log.info('Context::Eip: %x', jitter.pc)

    elif jitter.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif jitter.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
Example #20
0
def return_from_seh(jitter):
    """Handle the return from an exception handler
    @jitter: jitter instance"""

    # Get current context
    context_address = upck32(jitter.vm.get_mem(jitter.cpu.ESP + 0x8, 4))
    log.info('Context address: %x', context_address)
    jitter.cpu.ESP = upck32(jitter.vm.get_mem(context_address + 0xc4, 4))
    log.info('New esp: %x', jitter.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(jitter.vm.get_mem(tib_address, 4))
    new_seh = upck32(jitter.vm.get_mem(old_seh, 4))
    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
    jitter.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(jitter)

    if jitter.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        ctxt_ptr = context_address
        log.info('Seh continues Context: %x', ctxt_ptr)

        # Get registers changes
        ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc)
        ctxt2regs(ctxt_str, jitter)
        jitter.pc = jitter.cpu.EIP
        log.info('Context::Eip: %x', jitter.pc)

    elif jitter.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif jitter.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
Example #21
0
def return_from_seh(myjit):
    "Handle return after a call to fake seh handler"

    # Get current context
    context_address = upck32(myjit.vm.get_mem(myjit.cpu.ESP + 0x8, 4))
    log.info('Context address: %x', context_address)
    myjit.cpu.ESP = upck32(myjit.vm.get_mem(context_address + 0xc4, 4))
    log.info('New esp: %x', myjit.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(myjit.vm.get_mem(tib_address, 4))
    new_seh = upck32(myjit.vm.get_mem(old_seh, 4))
    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
    myjit.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(myjit)

    if myjit.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        ctxt_ptr = context_address
        log.info('Seh continues Context: %x', ctxt_ptr)

        # Get registers changes
        ctxt_str = myjit.vm.get_mem(ctxt_ptr, 0x2cc)
        ctxt2regs(ctxt_str, myjit)
        myjit.pc = myjit.cpu.EIP
        log.info('Context::Eip: %x', myjit.pc)

    elif myjit.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif myjit.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
Example #22
0
def init_seh(myjit):
    global seh_count
    seh_count = 0
    # myjit.vm.add_memory_page(tib_address, PAGE_READ | PAGE_WRITE,
    # p(default_seh) + p(0) * 11 + p(peb_address))
    myjit.vm.add_memory_page(
        FS_0_AD, PAGE_READ | PAGE_WRITE, build_fake_teb())
    # myjit.vm.add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, p(0) *
    # 3 + p(peb_ldr_data_address))
    myjit.vm.add_memory_page(
        peb_address, PAGE_READ | PAGE_WRITE, build_fake_peb())
    # myjit.vm.add_memory_page(peb_ldr_data_address, PAGE_READ |
    # PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) *
    # 0x20)

    """
    ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data))
    ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules)
    ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data))
    ldr_data += build_fake_InLoadOrderModuleList(loaded_modules)
    """
    myjit.vm.add_memory_page(
        LDR_AD, PAGE_READ | PAGE_WRITE, "\x00" * MAX_MODULES * 0x1000)
    module_info = create_modules_chain(myjit, loaded_modules)
    fix_InLoadOrderModuleList(myjit, module_info)
    fix_InMemoryOrderModuleList(myjit, module_info)
    fix_InInitializationOrderModuleList(myjit, module_info)

    ldr_data = build_fake_ldr_data(module_info)
    myjit.vm.set_mem(LDR_AD, ldr_data)
    add_process_env(myjit)
    add_process_parameters(myjit)

    # myjit.vm.add_memory_page(in_load_order_module_list_address,
    #     PAGE_READ | PAGE_WRITE, p(0) * 40)
    # myjit.vm.add_memory_page(in_load_order_module_list_address,
    #     PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules))
    myjit.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
        0xffffffff) + pck32(0x41414141) + pck32(0x42424242))

    myjit.vm.add_memory_page(
        context_address, PAGE_READ | PAGE_WRITE, '\x00' * 0x2cc)
    myjit.vm.add_memory_page(
        exception_record_address, PAGE_READ | PAGE_WRITE, '\x00' * 200)

    myjit.vm.add_memory_page(
        FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE, 0x10000 * "\x00")
Example #23
0
 def test_init(self):
     init_regs(self)
     self.buf = ""
     for reg_name in reversed(["EAX", "ECX",
                               "EDX", "EBX",
                               "ESP", "EBP",
                               "ESI", "EDI"]):
         self.buf += pck32(getattr(self.myjit.cpu, reg_name))
Example #24
0
def init_seh(myjit):
    global seh_count
    seh_count = 0
    # myjit.vm.add_memory_page(tib_address, PAGE_READ | PAGE_WRITE,
    # p(default_seh) + p(0) * 11 + p(peb_address))
    myjit.vm.add_memory_page(FS_0_AD, PAGE_READ | PAGE_WRITE, build_fake_teb())
    # myjit.vm.add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, p(0) *
    # 3 + p(peb_ldr_data_address))
    myjit.vm.add_memory_page(peb_address, PAGE_READ | PAGE_WRITE,
                             build_fake_peb())
    # myjit.vm.add_memory_page(peb_ldr_data_address, PAGE_READ |
    # PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) *
    # 0x20)
    """
    ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data))
    ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules)
    ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data))
    ldr_data += build_fake_InLoadOrderModuleList(loaded_modules)
    """
    myjit.vm.add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE,
                             "\x00" * MAX_MODULES * 0x1000)
    module_info = create_modules_chain(myjit, loaded_modules)
    fix_InLoadOrderModuleList(myjit, module_info)
    fix_InMemoryOrderModuleList(myjit, module_info)
    fix_InInitializationOrderModuleList(myjit, module_info)

    ldr_data = build_fake_ldr_data(module_info)
    myjit.vm.set_mem(LDR_AD, ldr_data)
    add_process_env(myjit)
    add_process_parameters(myjit)

    # myjit.vm.add_memory_page(in_load_order_module_list_address,
    #     PAGE_READ | PAGE_WRITE, p(0) * 40)
    # myjit.vm.add_memory_page(in_load_order_module_list_address,
    #     PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules))
    myjit.vm.add_memory_page(
        default_seh, PAGE_READ | PAGE_WRITE,
        pck32(0xffffffff) + pck32(0x41414141) + pck32(0x42424242))

    myjit.vm.add_memory_page(context_address, PAGE_READ | PAGE_WRITE,
                             '\x00' * 0x2cc)
    myjit.vm.add_memory_page(exception_record_address, PAGE_READ | PAGE_WRITE,
                             '\x00' * 200)

    myjit.vm.add_memory_page(FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE,
                             0x10000 * "\x00")
Example #25
0
def msvcrt___p___argc(jitter):
    global argc_init
    ret_ad, _ = jitter.func_args_cdecl(0)
    addr_argc = 0x13370000
    if not argc_init:
        jitter.vm.add_memory_page(addr_argc, PAGE_READ | PAGE_WRITE, pck32(1), "argc")
        argc_init = True
    jitter.func_ret_stdcall(ret_ad, addr_argc)
Example #26
0
def fix_InMemoryOrderModuleList(myjit, module_info):
    log.debug("Fix InMemoryOrderModuleList")
    # first binary is PE
    # last is dumm_e
    olist = []
    m_e = None
    d_e = None
    for m in [main_pe_name, ""] + loaded_modules:

        if isinstance(m, tuple):
            fname, e = m
        else:
            fname, e = m, None

        if "/" in fname:
            fname = fname[fname.rfind("/") + 1:]
        bname_str = fname
        bname = '\x00'.join(bname_str) + '\x00'
        if not bname.lower() in module_info:
            log.warn('Module not found, ldr data will be unconsistant')
            continue
        addr, e = module_info[bname.lower()]
        log.debug(bname_str)
        if e == main_pe:
            m_e = (e, bname, addr)
            continue
        elif e == dummy_e:
            d_e = (e, bname, addr)
            continue
        olist.append((e, bname, addr))
    if not m_e or not d_e:
        log.warn('No main pe, ldr data will be unconsistant')
    else:
        olist[0:0] = [m_e]
    olist.append(d_e)

    last_addr = 0

    for i in xrange(len(olist)):
        e, bname, addr = olist[i]
        p_e, p_bname, p_addr = olist[(i - 1) % len(olist)]
        n_e, n_bname, n_addr = olist[(i + 1) % len(olist)]
        myjit.vm.set_mem(
            addr + 0x8, pck32(n_addr + 0x8) + pck32(p_addr + 0x8))
Example #27
0
def regs2ctxt(regs):
    ctxt = ""
    ctxt += '\x00\x00\x00\x00'  # ContextFlags
    ctxt += '\x00\x00\x00\x00' * 6  # drX
    ctxt += '\x00' * 112  # float context
    ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + \
        '\x23\x00\x00\x00' + '\x23\x00\x00\x00'  # segment selectors
    ctxt += pck32(regs['EDI']) + pck32(regs['ESI']) + pck32(regs['EBX']) + \
        pck32(regs['EDX']) + pck32(regs['ECX']) + pck32(regs['EAX']) + \
        pck32(regs['EBP']) + pck32(regs['EIP'])  # gpregs
    ctxt += '\x23\x00\x00\x00'  # cs
    ctxt += '\x00\x00\x00\x00'  # eflags
    ctxt += pck32(regs['ESP'])  # esp
    ctxt += '\x23\x00\x00\x00'  # ss segment selector
    return ctxt
Example #28
0
def regs2ctxt(regs):
    ctxt = ""
    ctxt += '\x00\x00\x00\x00'  # ContextFlags
    ctxt += '\x00\x00\x00\x00' * 6  # drX
    ctxt += '\x00' * 112  # float context
    ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + \
        '\x23\x00\x00\x00' + '\x23\x00\x00\x00'  # segment selectors
    ctxt += pck32(regs['EDI']) + pck32(regs['ESI']) + pck32(regs['EBX']) + \
        pck32(regs['EDX']) + pck32(regs['ECX']) + pck32(regs['EAX']) + \
        pck32(regs['EBP']) + pck32(regs['EIP'])  # gpregs
    ctxt += '\x23\x00\x00\x00'  # cs
    ctxt += '\x00\x00\x00\x00'  # eflags
    ctxt += pck32(regs['ESP'])  # esp
    ctxt += '\x23\x00\x00\x00'  # ss segment selector
    return ctxt
Example #29
0
def fix_InLoadOrderModuleList(myjit, module_info):
    print "fix inloadorder"
    # first binary is PE
    # last is dumm_e
    olist = []
    m_e = None
    d_e = None
    for m in [main_pe_name, ""] + loaded_modules:

        if isinstance(m, tuple):
            fname, e = m
        else:
            fname, e = m, None

        if "/" in fname:
            fname = fname[fname.rfind("/") + 1:]
        bname = '\x00'.join(fname) + '\x00'
        if not bname.lower() in module_info:
            log.warn('module not found, ldr data will be unconsistant')
            continue

        addr, e = module_info[bname.lower()]
        # for bname, (addr, e) in module_info.items():
        print bname
        if e == main_pe:
            m_e = (e, bname, addr)
            continue
        elif e == dummy_e:
            d_e = (e, bname, addr)
            continue
        olist.append((e, bname, addr))
    if not m_e or not d_e:
        log.warn('no main pe, ldr data will be unconsistant')
    else:
        olist[0:0] = [m_e]
    olist.append(d_e)

    last_addr = 0
    for i in xrange(len(olist)):
        e, bname, addr = olist[i]
        p_e, p_bname, p_addr = olist[(i - 1) % len(olist)]
        n_e, n_bname, n_addr = olist[(i + 1) % len(olist)]
        myjit.vm.set_mem(addr + 0, pck32(n_addr) + pck32(p_addr))
Example #30
0
def build_ldr_data(jitter, modules_info):
    """
    Build Loader informations using following structure:

    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    # dummy dll base
    +0x024 DllBase : Ptr32 Void

    @jitter: jitter instance
    @modules_info: LoadedModules instance

    """
    # ldr offset pad
    offset = 0xC
    addr = LDR_AD + peb_ldr_data_offset
    ldrdata = PEB_LDR_DATA(jitter.vm, addr)

    main_pe = modules_info.name2module.get(main_pe_name, None)
    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)


    size = 0
    if main_pe:
        size += ListEntry.sizeof() * 2
        main_addr_entry = modules_info.module2entry[main_pe]
    if ntdll_pe:
        size += ListEntry.sizeof()
        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]

    jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE,
                              "\x00" * size,
                              "Loader struct")  # (ldrdata.get_size() - offset))

    if main_pe:
        ldrdata.InLoadOrderModuleList.flink = main_addr_entry
        ldrdata.InLoadOrderModuleList.blink = 0

        ldrdata.InMemoryOrderModuleList.flink = main_addr_entry + \
            LdrDataEntry.get_type().get_offset("InMemoryOrderLinks")
        ldrdata.InMemoryOrderModuleList.blink = 0

    if ntdll_pe:
        ldrdata.InInitializationOrderModuleList.flink = ntdll_addr_entry + \
            LdrDataEntry.get_type().get_offset("InInitializationOrderLinks")
        ldrdata.InInitializationOrderModuleList.blink = 0

    # Add dummy dll base
    jitter.vm.add_memory_page(peb_ldr_data_address + 0x24,
                              PAGE_READ | PAGE_WRITE, pck32(0),
                              "Loader struct dummy dllbase")
Example #31
0
def build_ldr_data(jitter, modules_info):
    """
    Build Loader informations using following structure:

    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    # dummy dll base
    +0x024 DllBase : Ptr32 Void

    @jitter: jitter instance
    @modules_info: LoadedModules instance

    """
    # ldr offset pad
    offset = 0xC
    addr = LDR_AD + peb_ldr_data_offset
    ldrdata = PEB_LDR_DATA(jitter.vm, addr)

    main_pe = modules_info.name2module.get(main_pe_name, None)
    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)


    size = 0
    if main_pe:
        size += ListEntry.sizeof() * 2
        main_addr_entry = modules_info.module2entry[main_pe]
    if ntdll_pe:
        size += ListEntry.sizeof()
        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]

    jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE,
                              "\x00" * size,
                              "Loader struct")  # (ldrdata.get_size() - offset))

    if main_pe:
        ldrdata.InLoadOrderModuleList.flink = main_addr_entry
        ldrdata.InLoadOrderModuleList.blink = 0

        ldrdata.InMemoryOrderModuleList.flink = main_addr_entry + \
            LdrDataEntry.get_type().get_offset("InMemoryOrderLinks")
        ldrdata.InMemoryOrderModuleList.blink = 0

    if ntdll_pe:
        ldrdata.InInitializationOrderModuleList.flink = ntdll_addr_entry + \
            LdrDataEntry.get_type().get_offset("InInitializationOrderLinks")
        ldrdata.InInitializationOrderModuleList.blink = 0

    # Add dummy dll base
    jitter.vm.add_memory_page(peb_ldr_data_address + 0x24,
                              PAGE_READ | PAGE_WRITE, pck32(0),
                              "Loader struct dummy dllbase")
Example #32
0
def build_fake_teb():
    """
    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    """
    o = ""
    o += pck32(default_seh)
    o += (0x18 - len(o)) * "\x00"
    o += pck32(tib_address)

    o += (0x30 - len(o)) * "\x00"
    o += pck32(peb_address)
    o += pck32(0x11223344)

    return o
Example #33
0
def build_fake_teb():
    """
    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    """
    o = ""
    o += pck32(default_seh)
    o += (0x18 - len(o)) * "\x00"
    o += pck32(tib_address)

    o += (0x30 - len(o)) * "\x00"
    o += pck32(peb_address)
    o += pck32(0x11223344)

    return o
Example #34
0
def build_peb(myjit, peb_address):
    """
    +0x000 InheritedAddressSpace    : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged            : UChar
    +0x003 SpareBool                : UChar
    +0x004 Mutant                   : Ptr32 Void
    +0x008 ImageBaseAddress         : Ptr32 Void
    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
    +0x010 processparameter
    """

    offset = peb_address + 8
    o = ""
    if main_pe:
        o += pck32(main_pe.NThdr.ImageBase)
    else:
        offset += 4
    o += pck32(peb_ldr_data_address)
    o += pck32(process_parameters_address)
    myjit.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o)
Example #35
0
def build_teb(myjit, teb_address):
    """
    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    """
    o = ""
    o += pck32(default_seh)
    o += (0x18 - len(o)) * "\x00"
    o += pck32(tib_address)

    o += (0x30 - len(o)) * "\x00"
    o += pck32(peb_address)
    o += pck32(0x11223344)

    myjit.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o)
Example #36
0
def advapi32_CryptImportKey(jitter):
    ret_ad, args = jitter.func_args_stdcall(['hprov','data','dataLen','pubKey','flags','hKeyRet'])
    print("Import key: data=%x, len=%d, pubKey=%x, flags=%x, pkeyRet=%x" % (
        args.data, args.dataLen, args.pubKey, args.flags, args.hKeyRet))
    key = jitter.vm.get_mem(args.data, args.dataLen)
    key = wincrypt2.CryptImportKey(key)
    if key is None:
        jitter.func_ret_stdcall(ret_ad, 0)
        return

    handle = winobjs.handle_pool.add("CryptKey", key)
    jitter.vm.set_mem(args.hKeyRet, pck32(handle))
    jitter.func_ret_stdcall(ret_ad, 1)
Example #37
0
def init_seh(jitter):
    """
    Build the modules entries and create double links
    @jitter: jitter instance
    """

    global seh_count
    seh_count = 0
    build_teb(jitter, FS_0_AD)
    build_peb(jitter, peb_address)

    modules_info = create_modules_chain(jitter, name2module)
    fix_InLoadOrderModuleList(jitter, modules_info)
    fix_InMemoryOrderModuleList(jitter, modules_info)
    fix_InInitializationOrderModuleList(jitter, modules_info)

    build_ldr_data(jitter, modules_info)
    add_process_env(jitter)
    add_process_parameters(jitter)

    jitter.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
        0xffffffff) + pck32(0x41414141) + pck32(0x42424242),
        "Default seh handler")
Example #38
0
def fix_InLoadOrderModuleList(jitter, modules_info):
    """Fix InLoadOrderModuleList double link list. First module is the main pe,
    then ntdll, kernel32. dummy is last pe.

    @jitter: the jitter instance
    @modules_info: the LoadedModules instance
    """

    log.debug("Fix InLoadOrderModuleList")
    main_pe = modules_info.name2module.get(main_pe_name, None)
    kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
    dummy_pe = modules_info.name2module.get("", None)
    special_modules = [main_pe, kernel32_pe, ntdll_pe, dummy_pe]
    if not all(special_modules):
        log.warn('No main pe, ldr data will be unconsistant %r',
                 special_modules)
        loaded_modules = modules_info.modules
    else:
        loaded_modules = [
            module for module in modules_info.modules
            if module not in special_modules
        ]
        loaded_modules[0:0] = [main_pe]
        loaded_modules[1:1] = [ntdll_pe]
        loaded_modules[2:2] = [kernel32_pe]
        loaded_modules.append(dummy_pe)

    for i, module in enumerate(loaded_modules):
        cur_module_entry = modules_info.module2entry[module]
        prev_module = loaded_modules[(i - 1) % len(loaded_modules)]
        next_module = loaded_modules[(i + 1) % len(loaded_modules)]
        prev_module_entry = modules_info.module2entry[prev_module]
        next_module_entry = modules_info.module2entry[next_module]
        jitter.vm.set_mem(
            cur_module_entry,
            (pck32(next_module_entry) + pck32(prev_module_entry)))
Example #39
0
def init_seh(jitter):
    """
    Build the modules entries and create double links
    @jitter: jitter instance
    """

    global seh_count
    seh_count = 0
    build_teb(jitter, FS_0_AD)
    build_peb(jitter, peb_address)

    modules_info = create_modules_chain(jitter, name2module)
    fix_InLoadOrderModuleList(jitter, modules_info)
    fix_InMemoryOrderModuleList(jitter, modules_info)
    fix_InInitializationOrderModuleList(jitter, modules_info)

    build_ldr_data(jitter, modules_info)
    add_process_env(jitter)
    add_process_parameters(jitter)

    jitter.vm.add_memory_page(
        default_seh, PAGE_READ | PAGE_WRITE,
        pck32(0xffffffff) + pck32(0x41414141) + pck32(0x42424242),
        "Default seh handler")
Example #40
0
    def test_SystemInformationFunctions(self):

        # DWORD WINAPI GetVersion(void);
        jit.push_uint32_t(0)      # @return
        winapi.kernel32_GetVersion(jit)
        dwVer = jit.cpu.EAX
        self.assertTrue(dwVer)

        # BOOL WINAPI GetVersionEx(_Inout_ LPOSVERSIONINFO lpVersionInfo);
        jit.vm.set_mem(jit.stack_base, pck32(0x9c))
        jit.push_uint32_t(jit.stack_base)      # lpVersionInfo
        jit.push_uint32_t(0)                   # @return
        winapi.kernel32_GetVersionExA(jit)
        vBool = jit.cpu.EAX
        self.assertTrue(vBool)
Example #41
0
def kernel32_GetComputerNameW(jitter):
    # https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms724295(v=vs.85).aspx
    ret_ad, args = jitter.func_args_stdcall(['lpBuffer', 'lpnSize'])

    # Get buffer size from memory
    size = upck32(jitter.vm.get_mem(args.lpnSize, 4))

    # Removing one character to size, as it includes the terminal null character
    size = min(size-1, 10)
    name = "A"*(size)
    jitter.set_str_unic(args.lpBuffer, name)

    # Returned size must not include the null terminating character
    jitter.vm.set_mem(args.lpnSize, pck32(size))

    # Returns true
    jitter.func_ret_stdcall(ret_ad, 1)
Example #42
0
def build_ldr_data(jitter, modules_info):
    """
    Build Loader informations using following structure:

    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    # dummy dll base
    +0x024 DllBase : Ptr32 Void

    @jitter: jitter instance
    @modules_info: LoadedModules instance

    """
    # ldr offset pad
    offset = peb_ldr_data_address + 0xC

    # get main pe info
    main_pe = modules_info.name2module.get(main_pe_name, None)
    if not main_pe:
        log.warn('No main pe, ldr data will be unconsistant')
        offset, data = offset + 8, ""
    else:
        main_addr_entry = modules_info.module2entry[main_pe]
        log.info('Ldr %x', main_addr_entry)
        data = pck32(main_addr_entry) + pck32(0)
        data += pck32(main_addr_entry + 0x8) + pck32(0)  # XXX TODO fix prev

    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
    if not ntdll_pe:
        log.warn('No ntdll, ldr data will be unconsistant')
    else:
        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
        data += pck32(ntdll_addr_entry + 0x10) + pck32(0)  # XXX TODO fix prev

    if data:
        jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data,
                                  "Loader struct")

    # Add dummy dll base
    jitter.vm.add_memory_page(peb_ldr_data_address + 0x24,
                              PAGE_READ | PAGE_WRITE, pck32(0),
                              "Loader struct dummy dllbase")
Example #43
0
def advapi32_CryptDecrypt(jitter):
    ret_ad, args = jitter.func_args_stdcall(["hkey", "hhash", "final",
                                          "dwflags", "pbdata",
                                          "pdwdatalen"])
    dataLen = upck32(jitter.vm.get_mem(args.pdwdatalen, 4))
    print("CryptDecrypt: hkey = %x, data=%x, dataLen=%d" % (args.hkey, args.pbdata, dataLen))
    if not args.hkey in winobjs.handle_pool:
        jitter.func_ret_stdcall(ret_ad, 0)
        return
    key = winobjs.handle_pool[args.hkey].info

    D = jitter.vm.get_mem(args.pbdata, dataLen)
    D = wincrypt2.CryptDecrypt(key, D)
    if D is None:
        jitter.func_ret_stdcall(ret_ad, 0)
        return
    D = str(D)
    print("Decrypted data: %s" % D.encode("hex"))
    jitter.vm.set_mem(args.pbdata, D)
    jitter.vm.set_mem(args.pdwdatalen, pck32(len(D)))
    jitter.func_ret_stdcall(ret_ad, 1)
Example #44
0
def return_from_seh(myjit):
    "Handle return after a call to fake seh handler"

    # Get current context
    myjit.cpu.ESP = upck32(myjit.vm.get_mem(context_address + 0xc4, 4))
    logging.info('-> new esp: %x', myjit.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(myjit.vm.get_mem(tib_address, 4))
    new_seh = upck32(myjit.vm.get_mem(old_seh, 4))
    logging.info('-> old seh: %x', old_seh)
    logging.info('-> new seh: %x', new_seh)
    myjit.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(myjit)

    # Release SEH
    free_seh_place(old_seh)

    if myjit.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        print '-> seh continues'
        ctxt_ptr = context_address
        print '-> context:', hex(ctxt_ptr)

        # Get registers changes
        ctxt_str = myjit.vm.get_mem(ctxt_ptr, 0x2cc)
        regs = ctxt2regs(ctxt_str)
        myjit.pc = regs["EIP"]
        for reg_name, reg_value in regs.items():
            setattr(myjit.cpu, reg_name, reg_value)

        logging.info('-> context::Eip: %x', myjit.pc)

    elif myjit.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif myjit.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
Example #45
0
def return_from_seh(myjit):
    "Handle return after a call to fake seh handler"

    # Get current context
    myjit.cpu.ESP = upck32(myjit.vm.get_mem(context_address + 0xc4, 4))
    logging.info('-> new esp: %x', myjit.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(myjit.vm.get_mem(tib_address, 4))
    new_seh = upck32(myjit.vm.get_mem(old_seh, 4))
    logging.info('-> old seh: %x', old_seh)
    logging.info('-> new seh: %x', new_seh)
    myjit.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(myjit)

    # Release SEH
    free_seh_place(old_seh)

    if myjit.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        print '-> seh continues'
        ctxt_ptr = context_address
        print '-> context:', hex(ctxt_ptr)

        # Get registers changes
        ctxt_str = myjit.vm.get_mem(ctxt_ptr, 0x2cc)
        regs = ctxt2regs(ctxt_str)
        myjit.pc = regs["EIP"]
        for reg_name, reg_value in regs.items():
            setattr(myjit.cpu, reg_name, reg_value)

        logging.info('-> context::Eip: %x', myjit.pc)

    elif myjit.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif myjit.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
Example #46
0
def build_fake_ldr_data(modules_info):
    """
    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    """
    o = ""
    # ldr offset pad
    o += "\x00" * peb_ldr_data_offset
    o += "\x00" * 0xc
    # text XXX

    # get main pe info
    m_e = None
    for bname, (addr, e) in modules_info.items():
        if e == main_pe:
            m_e = (e, bname, addr)
            break
    if not m_e:
        log.warn('no main pe, ldr data will be unconsistant')
    else:
        print 'inloadorder first', hex(m_e[2])
        o += pck32(m_e[2]) + pck32(0)

    # get ntdll
    ntdll_e = None
    for bname, (addr, e) in modules_info.items():
        if bname[::2].lower() == "ntdll.dll":
            ntdll_e = (e, bname, addr)
            continue
    if not ntdll_e:
        log.warn('no ntdll, ldr data will be unconsistant')
    else:
        print 'ntdll', hex(ntdll_e[2])
        o += pck32(ntdll_e[2] + 0x8) + pck32(0)  # XXX TODO
        o += pck32(ntdll_e[2] + 0x10) + pck32(0)

    return o
Example #47
0
def build_fake_ldr_data(modules_info):
    """
    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    """
    o = ""
    # ldr offset pad
    o += "\x00" * peb_ldr_data_offset
    o += "\x00" * 0xc
    # text XXX

    # get main pe info
    m_e = None
    for bname, (addr, e) in modules_info.items():
        if e == main_pe:
            m_e = (e, bname, addr)
            break
    if not m_e:
        log.warn('no main pe, ldr data will be unconsistant')
    else:
        print 'inloadorder first', hex(m_e[2])
        o += pck32(m_e[2]) + pck32(0)

    # get ntdll
    ntdll_e = None
    for bname, (addr, e) in modules_info.items():
        if bname[::2].lower() == "ntdll.dll":
            ntdll_e = (e, bname, addr)
            continue
    if not ntdll_e:
        log.warn('no ntdll, ldr data will be unconsistant')
    else:
        print 'ntdll', hex(ntdll_e[2])
        o += pck32(ntdll_e[2] + 0x8) + pck32(0)  # XXX TODO
        o += pck32(ntdll_e[2] + 0x10) + pck32(0)

    return o
Example #48
0
def build_ldr_data(myjit, modules_info):
    """
    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    """
    o = ""
    # ldr offset pad
    offset = LDR_AD + peb_ldr_data_offset + 0xC

    # get main pe info
    m_e = None
    for bname, (addr, e) in modules_info.items():
        if e == main_pe:
            m_e = (e, bname, addr)
            break
    if not m_e:
        log.warn('No main pe, ldr data will be unconsistant')
        offset, data = offset + 8, ""
    else:
        log.info('Ldr %x', m_e[2])
        data = pck32(m_e[2]) + pck32(0)

    # get ntdll
    ntdll_e = None
    for bname, (addr, e) in modules_info.items():
        if bname[::2].lower() == "ntdll.dll":
            ntdll_e = (e, bname, addr)
            continue
    if not ntdll_e:
        log.warn('No ntdll, ldr data will be unconsistant')
    else:
        data += pck32(ntdll_e[2] + 0x8) + pck32(0)  # XXX TODO
        data += pck32(ntdll_e[2] + 0x10) + pck32(0)

    if data:
        myjit.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data)
Example #49
0
def build_ldr_data(jitter, modules_info):
    """
    Build Loader informations using following structure:

    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY

    @jitter: jitter instance
    @modules_info: LoadedModules instance

    """
    # ldr offset pad
    offset = LDR_AD + peb_ldr_data_offset + 0xC

    # get main pe info
    main_pe = modules_info.name2module.get(main_pe_name, None)
    if not main_pe:
        log.warn('No main pe, ldr data will be unconsistant')
        offset, data = offset + 8, ""
    else:
        main_addr_entry = modules_info.module2entry[main_pe]
        log.info('Ldr %x', main_addr_entry)
        data = pck32(main_addr_entry) + pck32(0)
        data += pck32(main_addr_entry + 0x8) + pck32(0)  # XXX TODO fix prev

    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
    if not ntdll_pe:
        log.warn('No ntdll, ldr data will be unconsistant')
    else:
        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
        data += pck32(ntdll_addr_entry + 0x10) + pck32(0)  # XXX TODO fix prev

    if data:
        jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data,
                                  "Loader struct")
Example #50
0
 def push_uint32_t(self, value):
     self.cpu.SP -= 4
     self.vm.set_mem(self.cpu.SP, pck32(value))
Example #51
0
 def push_uint32_t(self, value):
     setattr(self.cpu, self.ira.sp.name,
             getattr(self.cpu, self.ira.sp.name) - self.ira.sp.size / 8)
     self.vm.set_mem(getattr(self.cpu, self.ira.sp.name), pck32(value))
Example #52
0
 def push_uint32_t(self, value):
     self.cpu.ESP -= self.ir_arch.sp.size / 8
     self.vm.set_mem(self.cpu.ESP, pck32(value))
Example #53
0
def create_modules_chain(jitter, name2module):
    """
    Create the modules entries. Those modules are not linked in this function.

    kd> dt nt!_LDR_DATA_TABLE_ENTRY
    +0x000 InLoadOrderLinks : _LIST_ENTRY
    +0x008 InMemoryOrderLinks : _LIST_ENTRY
    +0x010 InInitializationOrderLinks : _LIST_ENTRY
    +0x018 DllBase : Ptr32 Void
    +0x01c EntryPoint : Ptr32 Void
    +0x020 SizeOfImage : Uint4B
    +0x024 FullDllName : _UNICODE_STRING
    +0x02c BaseDllName : _UNICODE_STRING
    +0x034 Flags : Uint4B
    +0x038 LoadCount : Uint2B
    +0x03a TlsIndex : Uint2B
    +0x03c HashLinks : _LIST_ENTRY
    +0x03c SectionPointer : Ptr32 Void
    +0x040 CheckSum : Uint4B
    +0x044 TimeDateStamp : Uint4B
    +0x044 LoadedImports : Ptr32 Void
    +0x048 EntryPointActivationContext : Ptr32 Void
    +0x04c PatchInformation : Ptr32 Void

    @jitter: jitter instance
    @name2module: dict containing association between name and its pe instance
    """

    modules_info = LoadedModules()
    base_addr = LDR_AD + modules_list_offset  # XXXX
    offset_name = 0x500
    offset_path = 0x600

    dummy_e = pe_init.PE()
    dummy_e.NThdr.ImageBase = 0
    dummy_e.Opthdr.AddressOfEntryPoint = 0
    dummy_e.NThdr.sizeofimage = 0

    out = ""
    for i, (fname, pe_obj) in enumerate([("", dummy_e)] + name2module.items()):
        if pe_obj is None:
            log.warning("Unknown module: ommited from link list (%r)", fname)
            continue
        addr = base_addr + i * 0x1000
        bpath = fname.replace('/', '\\')
        bname_str = os.path.split(fname)[1].lower()
        bname = "\x00".join(bname_str) + "\x00"
        log.info("Add module %x %r", pe_obj.NThdr.ImageBase, bname_str)

        modules_info.add(bname_str, pe_obj, addr)

        m_o = ""
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(pe_obj.NThdr.ImageBase)
        m_o += pck32(pe_obj.rva2virt(pe_obj.Opthdr.AddressOfEntryPoint))
        m_o += pck32(pe_obj.NThdr.sizeofimage)
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(addr + offset_path)
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(addr + offset_name)
        jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, m_o)

        m_o = ""
        m_o += bname
        m_o += "\x00" * 3
        jitter.vm.add_memory_page(addr + offset_name, PAGE_READ | PAGE_WRITE,
                                  m_o)

        m_o = ""
        m_o += "\x00".join(bpath) + "\x00"
        m_o += "\x00" * 3
        jitter.vm.add_memory_page(addr + offset_path, PAGE_READ | PAGE_WRITE,
                                  m_o)

    return modules_info
def fake_seh_handler(jitter, except_code):
    """
    Create an exception context
    @jitter: jitter instance
    @except_code: x86 exception code
    """

    global seh_count, context_address
    regs = jitter.cpu.get_gpreg()
    log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count)
    seh_count += 1

    # Help lambda
    p = lambda s: struct.pack('I', s)

    # Forge a CONTEXT
    ctxt = regs2ctxt(jitter)

    # Get current seh (fs:[0])
    seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    old_seh, eh, safe_place = struct.unpack(
        'III', jitter.vm.get_mem(seh_ptr, 0xc))

    # Get space on stack for exception handling
    jitter.cpu.ESP -= 0x3c8
    exception_base_address = jitter.cpu.ESP
    exception_record_address = exception_base_address + 0xe8
    context_address = exception_base_address + 0xfc
    fake_seh_address = exception_base_address + 0x14

    log.info('seh_ptr %x { old_seh %x eh %x safe_place %x} ctx_addr %x',
             seh_ptr, old_seh, eh, safe_place, context_address)

    # Write context
    jitter.vm.set_mem(context_address, ctxt)

    # Write exception_record

    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
    """

    jitter.vm.set_mem(exception_record_address,
                      pck32(except_code) + pck32(0) + pck32(0) +
                      pck32(jitter.cpu.EIP) + pck32(0))

    # Prepare the stack
    jitter.push_uint32_t(context_address)               # Context
    jitter.push_uint32_t(seh_ptr)                       # SEH
    jitter.push_uint32_t(exception_record_address)      # ExceptRecords
    jitter.push_uint32_t(return_from_exception)         # Ret address

    # Set fake new current seh for exception
    log.info("Fake seh ad %x", fake_seh_address)
    jitter.vm.set_mem(fake_seh_address, pck32(seh_ptr) + pck32(
        0xaaaaaaaa) + pck32(0xaaaaaabb) + pck32(0xaaaaaacc))
    jitter.vm.set_mem(tib_address, pck32(fake_seh_address))

    dump_seh(jitter)

    log.info('Jumping at %x', eh)
    jitter.vm.set_exception(0)
    jitter.cpu.set_exception(0)

    # XXX set ebx to nul?
    jitter.cpu.EBX = 0

    return eh
Example #55
0
def build_fake_InLoadOrderModuleList(modules_name):
    """
    +0x000 Flink : Ptr32                                 -+ This distance
    +0x004 Blink : Ptr32                                  | is eight bytes
    +0x018 DllBase                        : Ptr32 Void   -+ DllBase -> _IMAGE_DOS_HEADER
    +0x01c EntryPoint                     : Ptr32 Void
    +0x020 SizeOfImage                    : Uint4B
    +0x024 FullDllName                    : _UNICODE_STRING
    +0x02c BaseDllName                    : _UNICODE_STRING
    +0x034 Flags                          : Uint4B
    +0x038 LoadCount                      : Uint2B
    +0x03a TlsIndex                       : Uint2B
    +0x03c HashLinks                      : _LIST_ENTRY
    +0x03c SectionPointer                 : Ptr32 Void
    +0x040 CheckSum                       : Uint4B
    +0x044 TimeDateStamp                  : Uint4B
    +0x044 LoadedImports                  : Ptr32 Void
    +0x048 EntryPointActivationContext    : Ptr32 Void
    +0x04c PatchInformation               : Ptr32 Void
    """

    o = ""
    offset_name = 0x700
    first_name = "\x00".join(main_pe_name + "\x00\x00")

    o = ""
    o += pck32(InLoadOrderModuleList_address)
    o += pck32(InLoadOrderModuleList_address +
               (len(modules_name) - 1) * 0x1000)
    o += pck32(InLoadOrderModuleList_address + 8)
    o += pck32(InLoadOrderModuleList_address +
               (len(modules_name) - 1) * 0x1000 + 8)
    o += pck32(InLoadOrderModuleList_address + 0x10)
    o += pck32(InLoadOrderModuleList_address +
               (len(modules_name) - 1) * 0x1000 + 0x10)

    if main_pe:
        o += pck32(main_pe.NThdr.ImageBase)
        o += pck32(main_pe.rva2virt(main_pe.Opthdr.AddressOfEntryPoint))
    else:
        # no fixed values
        pass

    o += (0x24 - len(o)) * "A"
    o += struct.pack('HH', len(first_name), len(first_name))
    o += pck32(InLoadOrderModuleList_address + offset_name)

    o += (0x2C - len(o)) * "A"
    o += struct.pack('HH', len(first_name), len(first_name))
    o += pck32(InLoadOrderModuleList_address + offset_name)

    o += (offset_name - len(o)) * "B"
    o += first_name
    o += (0x1000 - len(o)) * "C"
    for i, m in enumerate(modules_name):
        # fname = os.path.join('win_dll', m)
        if isinstance(m, tuple):
            fname, e = m
        else:
            fname, e = m, None
        bname = os.path.split(fname)[1].lower()
        bname = "\x00".join(bname) + "\x00"
        print hex(InLoadOrderModuleList_address + i * 0x1000)
        if e is None:
            e = pe_init.PE(open(fname, 'rb').read())

        print "add module", hex(e.NThdr.ImageBase), repr(bname)

        next_ad = InLoadOrderModuleList_address + (i + 1) * 0x1000
        if i == len(modules_name) - 1:
            next_ad = InLoadOrderModuleList_address
        m_o = ""
        m_o += pck32(next_ad)
        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000)
        m_o += pck32(next_ad + 8)
        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000 + 8)
        m_o += pck32(next_ad + 0x10)
        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000 + 0x10)
        m_o += pck32(e.NThdr.ImageBase)
        m_o += pck32(e.rva2virt(e.Opthdr.AddressOfEntryPoint))
        m_o += pck32(e.NThdr.sizeofimage)

        m_o += (0x24 - len(m_o)) * "A"
        print hex(len(bname)), repr(bname)
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(InLoadOrderModuleList_address + i * 0x1000 + offset_name)

        m_o += (0x2C - len(m_o)) * "A"
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(InLoadOrderModuleList_address + i * 0x1000 + offset_name)

        m_o += (offset_name - len(m_o)) * "B"
        m_o += bname
        m_o += "\x00" * 3

        m_o += (0x1000 - len(m_o)) * "J"

        print "module", "%.8X" % e.NThdr.ImageBase, fname

        o += m_o
    return o
Example #56
0
def fake_seh_handler(jitter, except_code):
    """
    Create an exception context
    @jitter: jitter instance
    @except_code: x86 exception code
    """

    global seh_count, context_address
    regs = jitter.cpu.get_gpreg()
    log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count)
    seh_count += 1

    # Help lambda
    p = lambda s: struct.pack('I', s)

    # Forge a CONTEXT
    ctxt = regs2ctxt(jitter)

    # Get current seh (fs:[0])
    seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    old_seh, eh, safe_place = struct.unpack('III',
                                            jitter.vm.get_mem(seh_ptr, 0xc))

    # Get space on stack for exception handling
    jitter.cpu.ESP -= 0x3c8
    exception_base_address = jitter.cpu.ESP
    exception_record_address = exception_base_address + 0xe8
    context_address = exception_base_address + 0xfc
    fake_seh_address = exception_base_address + 0x14

    log.info('seh_ptr %x { old_seh %x eh %x safe_place %x} ctx_addr %x',
             seh_ptr, old_seh, eh, safe_place, context_address)

    # Write context
    jitter.vm.set_mem(context_address, ctxt)

    # Write exception_record
    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
    """

    jitter.vm.set_mem(
        exception_record_address,
        pck32(except_code) + pck32(0) + pck32(0) + pck32(jitter.cpu.EIP) +
        pck32(0))

    # Prepare the stack
    jitter.push_uint32_t(context_address)  # Context
    jitter.push_uint32_t(seh_ptr)  # SEH
    jitter.push_uint32_t(exception_record_address)  # ExceptRecords
    jitter.push_uint32_t(return_from_exception)  # Ret address

    # Set fake new current seh for exception
    log.info("Fake seh ad %x", fake_seh_address)
    jitter.vm.set_mem(
        fake_seh_address,
        pck32(seh_ptr) + pck32(0xaaaaaaaa) + pck32(0xaaaaaabb) +
        pck32(0xaaaaaacc))
    jitter.vm.set_mem(tib_address, pck32(fake_seh_address))

    dump_seh(jitter)

    log.info('Jumping at %x', eh)
    jitter.vm.set_exception(0)
    jitter.cpu.set_exception(0)

    # XXX set ebx to nul?
    jitter.cpu.EBX = 0

    return eh
def create_modules_chain(jitter, name2module):
    """
    Create the modules entries. Those modules are not linked in this function.

    kd> dt nt!_LDR_DATA_TABLE_ENTRY
    +0x000 InLoadOrderLinks : _LIST_ENTRY
    +0x008 InMemoryOrderLinks : _LIST_ENTRY
    +0x010 InInitializationOrderLinks : _LIST_ENTRY
    +0x018 DllBase : Ptr32 Void
    +0x01c EntryPoint : Ptr32 Void
    +0x020 SizeOfImage : Uint4B
    +0x024 FullDllName : _UNICODE_STRING
    +0x02c BaseDllName : _UNICODE_STRING
    +0x034 Flags : Uint4B
    +0x038 LoadCount : Uint2B
    +0x03a TlsIndex : Uint2B
    +0x03c HashLinks : _LIST_ENTRY
    +0x03c SectionPointer : Ptr32 Void
    +0x040 CheckSum : Uint4B
    +0x044 TimeDateStamp : Uint4B
    +0x044 LoadedImports : Ptr32 Void
    +0x048 EntryPointActivationContext : Ptr32 Void
    +0x04c PatchInformation : Ptr32 Void

    @jitter: jitter instance
    @name2module: dict containing association between name and its pe instance
    """

    modules_info = LoadedModules()
    base_addr = LDR_AD + modules_list_offset  # XXXX
    offset_name = 0x500
    offset_path = 0x600

    dummy_e = pe_init.PE()
    dummy_e.NThdr.ImageBase = 0
    dummy_e.Opthdr.AddressOfEntryPoint = 0
    dummy_e.NThdr.sizeofimage = 0

    out = ""
    for i, (fname, pe_obj) in enumerate([("", dummy_e)] + name2module.items()):
        if pe_obj is None:
            log.warning("Unknown module: ommited from link list (%r)",
                        fname)
            continue
        addr = base_addr + i * 0x1000
        bpath = fname.replace('/', '\\')
        bname_str = os.path.split(fname)[1].lower()
        bname = "\x00".join(bname_str) + "\x00"
        log.info("Add module %x %r", pe_obj.NThdr.ImageBase, bname_str)

        modules_info.add(bname_str, pe_obj, addr)

        m_o = ""
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(0)
        m_o += pck32(pe_obj.NThdr.ImageBase)
        m_o += pck32(pe_obj.rva2virt(pe_obj.Opthdr.AddressOfEntryPoint))
        m_o += pck32(pe_obj.NThdr.sizeofimage)
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(addr + offset_path)
        m_o += struct.pack('HH', len(bname), len(bname) + 2)
        m_o += pck32(addr + offset_name)
        jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, m_o)

        m_o = ""
        m_o += bname
        m_o += "\x00" * 3
        jitter.vm.add_memory_page(
            addr + offset_name, PAGE_READ | PAGE_WRITE, m_o)

        m_o = ""
        m_o += "\x00".join(bpath) + "\x00"
        m_o += "\x00" * 3
        jitter.vm.add_memory_page(
            addr + offset_path, PAGE_READ | PAGE_WRITE, m_o)

    return modules_info
Example #58
0
 def func_prepare_stdcall(self, ret_addr, *args):
     for index in xrange(min(len(args), 4)):
         setattr(self.cpu, 'R%d' % index, args[index])
     for index in xrange(4, len(args)):
         self.vm.set_mem(self.cpu.SP + 4 * (index - 4), pck32(args[index]))
     self.cpu.LR = ret_addr
Example #59
0
def fake_seh_handler(myjit, except_code):
    global seh_count
    regs = myjit.cpu.get_gpreg()
    print '-> exception at', hex(myjit.cpu.EIP), seh_count
    seh_count += 1

    # Help lambda
    p = lambda s: struct.pack('I', s)

    # dump_gpregs_py()
    # jitarch.dump_gpregs()
    # Forge a CONTEXT
    ctxt = '\x00\x00\x00\x00' + '\x00\x00\x00\x00' * 6 + '\x00' * 112
    ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + '\x23\x00\x00\x00'
    ctxt += '\x23\x00\x00\x00'
    ctxt += pck32(myjit.cpu.EDI) + pck32(myjit.cpu.ESI) + \
            pck32(myjit.cpu.EBX) + pck32(myjit.cpu.EDX) + \
            pck32(myjit.cpu.ECX) + pck32(myjit.cpu.EAX) + \
            pck32(myjit.cpu.EBP) + pck32(myjit.cpu.EIP)
    ctxt += '\x23\x00\x00\x00' + '\x00\x00\x00\x00' + pck32(myjit.cpu.ESP)
    ctxt += '\x23\x00\x00\x00'
    # ctxt = regs2ctxt(regs)

    # Find a room for seh
    # seh = (get_memory_page_max_address_py()+0x1000)&0xfffff000

    # Get current seh (fs:[0])
    seh_ptr = upck32(myjit.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    old_seh, eh, safe_place = struct.unpack('III',
                                            myjit.vm.get_mem(seh_ptr, 0xc))

    print '-> seh_ptr', hex(seh_ptr), '-> { old_seh',
    print hex(old_seh), 'eh', hex(eh), 'safe_place', hex(safe_place), '}'
    # print '-> write SEH at', hex(seh&0xffffffff)

    # Write current seh
    # myjit.vm.add_memory_page(seh, PAGE_READ | PAGE_WRITE, p(old_seh) +
    # p(eh) + p(safe_place) + p(0x99999999))

    # Write context
    myjit.vm.set_mem(context_address, ctxt)

    # Write exception_record
    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
    """

    myjit.vm.set_mem(
        exception_record_address,
        pck32(except_code) + pck32(0) + pck32(0) + pck32(myjit.cpu.EIP) +
        pck32(0) + pck32(0))

    # Prepare the stack
    myjit.push_uint32_t(context_address)  # Context
    myjit.push_uint32_t(seh_ptr)  # SEH
    myjit.push_uint32_t(exception_record_address)  # ExceptRecords
    myjit.push_uint32_t(return_from_exception)  # Ret address

    # Set fake new current seh for exception
    fake_seh_ad = get_free_seh_place()
    print hex(fake_seh_ad)
    myjit.vm.set_mem(
        fake_seh_ad,
        pck32(seh_ptr) + pck32(0xaaaaaaaa) + pck32(0xaaaaaabb) +
        pck32(0xaaaaaacc))
    myjit.vm.set_mem(tib_address, pck32(fake_seh_ad))

    dump_seh(myjit)

    print '-> jumping at', hex(eh)
    myjit.vm.set_exception(0)
    myjit.cpu.set_exception(0)

    # XXX set ebx to nul?
    myjit.cpu.EBX = 0

    return eh