Ejemplo n.º 1
0
def funcap(cpu_index, cpu, pc, next_pc):
    '''
		Function to monitor API calls and to resolve symbols. Receives 4 parameters (OPCODE CALLBACK):
		:param addr: Address from instruction to disassemble
		:type addr: int
		:param cpu_index: CPU index 
		:type cpu_index: int
	'''

    global num_ins
    global logger
    global pgd_target
    global process_is_created

    if process_is_created == 1 and api.is_kernel_running(cpu_index) == False:

        pgd = api.get_running_process(cpu_index)

        if pgd_target == pgd:
            disassemble(pc, cpu_index)

        if num_ins == MAX_INSTRUCTIONS:
            api.stop_monitoring_process(pgd)
            pyrebox_print("[*] Stopped monitoring process")
            num_ins = 0
def mem_write(cpu_index, vaddr, size, haddr, data):
    global cm
    global page_status
    import api
    if not api.is_kernel_running(cpu_index):
        page = vaddr & 0xFFFFF000
        page_status[page] = "w"
Ejemplo n.º 3
0
def opcodes(cpu_index, cpu, pc, next_pc):
    global pyrebox_print
    global target_pgd

    if api.is_kernel_running(cpu_index) == False:
        pgd = api.get_running_process(cpu_index)
        if pgd == target_pgd and pc < 0x500000:
            if cpu.EBX == 0x54474354:
                api.w_r(0, "EBX", 0x72657661)
                api.w_r(0, "ECX", 0x33333179)
                api.w_r(0, "EDX", 0x70796837)
                pyrebox_print("[*] Hypervisor name check %x" % pc)
                #start_shell()
            elif cpu.EBX == 0x756e6547:
                pyrebox_print("[*] GenuineIntel check %x" % pc)
            elif cpu.EBX == 0x72695620:
                api.w_r(0, "EAX", 0x65746e49)
                api.w_r(0, "EBX", 0x6f63206c)
                api.w_r(0, "ECX", 0x49206572)
                api.w_r(0, "EDX", 0x00003936)
                pyrebox_print("[*] CPU Name check %x" % pc)
                #start_shell()
            elif cpu.ECX == 0x80000001:  #Not pretty elegant
                api.w_r(0, "ECX", 0x00000000)
                pyrebox_print("[*] Hypervisor bit check %x" % pc)
            else:
                pyrebox_print("[*] Unknown Check (TODO) %x" % pc)
Ejemplo n.º 4
0
def block_exec(cpu_index, cpu, tb):
    global cm
    global page_status
    import api
    if not api.is_kernel_running(cpu_index):
        pc, size, icount = tb
        page = pc & 0xFFFFF000
        if page in page_status:
            if page_status[page] == "w":
                proc = api.get_running_process(cpu_index)
                pyrebox_print("Written & Executed page PID: %08x PAGE: %08x" % (proc, page))
        page_status[page] = "x"
Ejemplo n.º 5
0
def mem_write(params):
    global cm
    global page_status
    import api

    cpu_index = params["cpu_index"]
    vaddr = params["vaddr"]
    size = params["size"]
    haddr = params["haddr"]
    data = params["data"]

    if not api.is_kernel_running(cpu_index):
        page = vaddr & 0xFFFFF000
        page_status[page] = "w"
Ejemplo n.º 6
0
def rdtsc_opcode_call(cpu_index, cpu, pc, next_pc):
    global pyrebox_print
    global target_pgd
    global rdtsc_val_lo
    global rdtsc_val_hi

    if api.is_kernel_running(cpu_index) == False:
        pgd = api.get_running_process(cpu_index)
        if pgd == target_pgd and pc < 0x500000:
            if rdtsc_val_lo == 0:
                pyrebox_print("[*] first rdtsc call %x" % pc)
                rdtsc_val_lo = cpu.EAX
                rdtsc_val_hi = cpu.EDX
            else:
                pyrebox_print("[*] new rdtsc check! %x" % pc)
                rdtsc_val_lo = rdtsc_val_lo + 500  # this just works for pafish ~cos it has a sleep(500), need to find a more general aproach
                api.w_r(0, "EAX", rdtsc_val_lo)
                api.w_r(0, "EDX", rdtsc_val_hi)
Ejemplo n.º 7
0
def mem_write(params):
    '''
        Callback for memory writes.
    '''
    global cm
    global page_status
    global current_layer
    global UNPACKER_LOG_PATH
    global UNPACKER_DUMP_PATH

    import api
    from cpus import X64CPU, X86CPU

    # Get callback parameters
    cpu_index = params["cpu_index"]
    vaddr = params["vaddr"]
    size = params["size"]
    haddr = params["haddr"]
    data = params["data"]

    # Get running process, as well as CPU object
    pgd = api.get_running_process(cpu_index)
    cpu = api.r_cpu(cpu_index)

    if not api.is_kernel_running(cpu_index):
        mask = 0xFFFFF000 if TARGET_LONG_SIZE == 4 else 0xFFFFFFFFFFFFF000
        page = vaddr & mask

        # Set page write status (update with current layer)
        page_status_w[page] = current_layer

        # Log the page write
        pc = cpu.RIP if isinstance(cpu, X64CPU) else cpu.EIP
        if TARGET_LONG_SIZE == 4:
            append_log("[W]  - PGD [%08x] - PAGE [%08x] - FROM [%08x]" %
                       (pgd, page, pc))
        else:
            append_log("[W]  - PGD [%016x] - PAGE [%016x] - FROM [%016x]" %
                       (pgd, page, pc))
Ejemplo n.º 8
0
def mem_write(params):
    '''
        Callback for memory writes.
    '''
    global cm
    global page_status_x
    global page_status_w
    global current_layer
    global UNPACKER_LOG_PATH
    global UNPACKER_DUMP_PATH
    global section_maps
    global written_files
    global ntdll_space

    import api
    from cpus import X64CPU, X86CPU

    # Get callback parameters
    cpu_index = params["cpu_index"]
    vaddr = params["vaddr"]
    size = params["size"]
    haddr = params["haddr"]
    data = params["data"]

    # Get running process, as well as CPU object
    pgd = api.get_running_process(cpu_index)
    cpu = api.r_cpu(cpu_index)
    pc = cpu.RIP if isinstance(cpu, X64CPU) else cpu.EIP

    if pgd not in page_status_w:
        page_status_w[pgd] = {}

    if not api.is_kernel_running(cpu_index):
        mask = 0xFFFFF000 if TARGET_LONG_SIZE == 4 else 0xFFFFFFFFFFFFF000
        page = vaddr & mask

        overlapping_section_maps = []
        # Check if the memory was mapped to file, so we record a file write for such file
        for base, size, file_offset, file_name in section_maps:
            if page >= (base & mask) and page < ((
                (base + size) & mask) + 0x1000):
                overlapping_section_maps.append(
                    (base, size, file_offset, file_name))

        # If it comes from ntdll and affects to a mapped file, just ignore it,
        # it is likely due to relocations or loader/stuff and is prone to FPs.
        if (pc >= ntdll_space[0] and pc < (ntdll_space[0] + ntdll_space[1])
            ) and len(overlapping_section_maps) > 0:
            return

        # Set page write status (update with current layer)
        page_status_w[pgd][page] = current_layer

        # Log the page write
        if TARGET_LONG_SIZE == 4:
            append_log("[W]  - PGD [%08x] - PAGE [%08x] - FROM [%08x]" %
                       (pgd, page, pc))
        else:
            append_log("[W]  - PGD [%016x] - PAGE [%016x] - FROM [%016x]" %
                       (pgd, page, pc))

        # Only reflect on mapped file if it doesn't come from ntdll, to avoid FPs due to relocation
        # fixing.
        # Finally, check if the memory was mapped to file, so we record a file write for such file
        for base, size, file_offset, file_name in overlapping_section_maps:
            if file_name not in written_files:
                written_files[file_name] = [
                    ((page - (base & mask)) + file_offset, 0x1000)
                ]
            else:
                written_files[file_name].append(
                    ((page - (base & mask)) + file_offset, 0x1000))
            append_log(
                "^^^---> PAGE is section mapped, FILE [%s] - Offset %x - Size %x"
                % (file_name, (page - (base & mask)) + file_offset, size))