Ejemplo n.º 1
0
def gdb_write_thread_register(thread_id, thread_list, gdb_register_index, buf):
    '''
    Given a GDB register index, write the provided value. Obtain
    the value either from the running CPU or the saved KTRAP_FRAME.
    NOTE: Not all registers are supported, if so, 0's are returned.
    '''
    from utils import ConfigurationManager as conf_m
    from api import r_cpu
    from cpus import RT_SEGMENT
    from cpus import RT_REGULAR

    if conf_m.platform == "i386-softmmu":
        from cpus import gdb_map_i386_softmmu as gdb_map
    elif conf_m.platform == "x86_64-softmmu":
        from cpus import gdb_map_x86_64_softmmu as gdb_map
    else:
        raise NotImplementedError(
            "[gdb_write_thread_register] Architecture not supported yet")

    # If it is not mapped to a CPU register or KTRAP_FRAME value,
    # we just return 0s.
    if gdb_register_index not in gdb_map:
        return 0
    else:
        str_size = gdb_map[gdb_register_index][2]

    cpu_index = None
    thread = None
    # First, check if we can read the register from the CPU object
    for element in thread_list:
        if element['id'] == thread_id:
            cpu_index = element['running']
            thread = element
            break

    if thread is None:
        return None

    if cpu_index is not None:
        val = str_to_val(buf, str_size)
        w_r(cpu_index, gdb_map[gdb_register_index][0], val)
        return str_size
    # If the thread is not running, read it from the KTRAP_FRAME
    else:
        if os_family == OS_FAMILY_WIN:
            from windows_vmi import win_read_thread_register_from_ktrap_frame
            try:
                bytes_written = win_write_thread_register_in_ktrap_frame(
                    thread, gdb_map[gdb_register_index][1], buf, str_size)
            except Exception as e:
                pp_debug(
                    "Exception after win_write_thread_register_in_ktrap_frame: "
                    + str(e))
            if bytes_written < 0:
                bytes_written = 0
            return bytes_written
        elif os_family == OS_FAMILY_LINUX:
            raise NotImplementedError(
                "gdb_write_thread_register not implemented yet on Linux guests"
            )
Ejemplo n.º 2
0
def ntmapviewofsection_ret(params, cm, callback_name, mapped_sec, mapping_proc,
                           base_p, size_p, offset_p, proc, update_vads,
                           long_size):
    from core import SectionMap
    import api
    global interproc_data
    global interproc_config

    TARGET_LONG_SIZE = api.get_os_bits() / 8

    cpu_index = params["cpu_index"]
    cpu = params["cpu"]

    pgd = api.get_running_process(cpu_index)

    # First, remove callback
    cm.rm_callback(callback_name)

    if base_p != 0:
        base = dereference_target_long(base_p, pgd, long_size)
    else:
        base = 0

    if size_p != 0:
        size = dereference_target_long(size_p, pgd, long_size)
    else:
        size = 0

    # Offset is always 8 bytes
    if offset_p != 0:
        try:
            offset = struct.unpack("Q", api.r_va(pgd, offset_p, 8))[0]
        except:
            offset = 0
            pp_debug(
                "Could not dereference offset in NtMapViewOfSection return, in interproc_callbacks.py\n"
            )
    else:
        offset = 0

    mapping_proc.add_section_map(
        SectionMap(mapped_sec, pgd, base, size, offset))

    if interproc_config.interproc_text_log and interproc_config.interproc_text_log_handle is not None:
        f = interproc_config.interproc_text_log_handle
        if TARGET_LONG_SIZE == 4:
            f.write(
                "[PID: %08x] NtMapViewOfSection: Base: %08x Size: %08x Offset: %08x / Section: %s\n"
                % (proc.get_pid(), base, size, offset,
                   mapped_sec.get_backing_file()))
        elif TARGET_LONG_SIZE == 8:
            f.write(
                "[PID: %08x] NtMapViewOfSection: Base: %16x Size: %16x Offset: %08x / Section: %s\n"
                % (proc.get_pid(), base, size, offset,
                   mapped_sec.get_backing_file()))

    if update_vads:
        proc.update_vads()
Ejemplo n.º 3
0
def gdb_set_cpu_pc(thread_id, thread_list, val):
    ''' Set cpu PC '''
    if conf_m.platform == "i386-softmmu":
        from cpus import gdb_map_i386_softmmu as gdb_map
        gdb_register_index = 8
    elif conf_m.platform == "x86_64-softmmu":
        from cpus import gdb_map_x86_64_softmmu as gdb_map
        gdb_register_index = 16
    else:
        raise NotImplementedError(
            "[gdb_write_thread_register] Architecture not supported yet")

    # If it is not mapped to a CPU register or KTRAP_FRAME value,
    # we just return 0s.
    if gdb_register_index not in gdb_map:
        return 0
    else:
        str_size = gdb_map[gdb_register_index][2]

    cpu_index = None
    thread = None
    # First, check if we can read the register from the CPU object
    for element in thread_list:
        if element['id'] == thread_id:
            cpu_index = element['running']
            thread = element
            break

    if thread is None:
        return None

    if cpu_index is not None:
        w_r(cpu_index, gdb_map[gdb_register_index][0], val)
        return str_size
    # If the thread is not running, read it from the KTRAP_FRAME
    else:
        if os_family == OS_FAMILY_WIN:
            from windows_vmi import win_read_thread_register_from_ktrap_frame
            try:
                bytes_written = win_write_thread_register_in_ktrap_frame(
                    thread, gdb_map[gdb_register_index][1],
                    val_to_str(val, str_size), str_size)
            except Exception as e:
                pp_debug(
                    "Exception after win_write_thread_register_in_ktrap_frame: "
                    + str(e))
            if bytes_written < 0:
                bytes_written = 0
            return bytes_written
        elif os_family == OS_FAMILY_LINUX:
            raise NotImplementedError(
                "gdb_set_cpu_pc not implemented yet on Linux guests")
Ejemplo n.º 4
0
def init_plugins():
    try:
        pp_debug("[*] Initializing scripts...\n")
        # Locate python modules that should be loaded by default
        for (module, enable) in conf_m.config.items("MODULES"):
            if enable.strip().lower() == "true" or enable.strip().lower() == "yes":
                import_module(module)

        pp_debug("[*] Finished python module initialization\n")
        return True
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 5
0
def init_plugins():
    try:
        pp_debug("[*] Initializing scripts...\n")
        # Locate python modules that should be loaded by default
        for (module, enable) in conf_m.config.items("MODULES"):
            if enable.strip().lower() == "true" or enable.strip().lower() == "yes":
                import_module(module)

        pp_debug("[*] Finished python module initialization\n")
        return True
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 6
0
def dereference_target_long(addr, pgd, long_size):
    import api
    typ = "<I" if long_size == 4 else "<Q"
    try:
        buff = api.r_va(pgd, addr, long_size)
    except:
        buff = "\x00" * long_size
        pp_debug("Could not dereference TARGET_LONG in interproc_callbacks.py")

    if len(buff) == 0:
        pp_warning(
            "[interproc_callbacks.py:dereference_target_long] Error while dereferencing parameter with address %x"
            % addr)
        return 0
    return struct.unpack(typ, buff)[0]
Ejemplo n.º 7
0
def interproc_start_monitoring_process(params):
    '''
        Given a Process instance, do the magic
        to start monitoring the process for the
        interproc module
    '''
    global cm
    global interproc_data

    import api
    from core import Process
    from api import CallbackManager

    # Get parameters
    pid = params["pid"]
    pgd = params["pgd"]
    name = params["name"]

    proc = Process(name)
    proc.set_pgd(pgd)
    proc.set_pid(pid)

    # Append process to process list
    interproc_data.add_process(proc)

    # add_module, for every module loaded so far for this process. Because
    # this function might be triggered by a call to NtOpenProcess over
    # an already existing process
    try:
        for mod in api.get_module_list(pgd):
            add_module(proc, {"pid": pid,
                              "pgd": pgd,
                              "base": mod["base"],
                              "size": mod["size"],
                              "name": mod["name"],
                              "fullname": mod["fullname"]})
        # Callback for each module loaded
        cm.add_callback(CallbackManager.LOADMODULE_CB, 
                        functools.partial(module_loaded, proc), 
                        pgd = pgd, 
                        name = ("load_module_%x" % pgd))
    except ValueError:
        # Could happen that the process is still not on the list of
        # created processes
        pp_debug("Process still not in the list of created processes, setting CB on TLB exec.\n")
        cm.add_callback(CallbackManager.TLB_EXEC_CB, functools.partial(tlb_exec, proc), name=("tlb_exec_%d" % pgd))
Ejemplo n.º 8
0
def init(platform, root_path, volatility_path):
    global conf
    try:
        # Just configure basic logging
        import logging
        logging.basicConfig()
        # Initialize stuff
        pp_debug("[*] Platform: %s\n" % platform)
        pp_debug("[*] Starting python module initialization\n")
        pp_debug("[*] Reading configuration\n")
        sys.settrace
        config = ConfigParser.RawConfigParser()
        if not os.path.isfile("pyrebox.conf"):
            pp_error(
                "[!] Could not initialize pyrebox, pyrebox.conf file missing!\n"
            )
            return None
        config.read('pyrebox.conf')
        vol_profile = config.get('VOL', 'profile')
        conf = ConfigManager(volatility_path=volatility_path,
                             vol_profile=vol_profile,
                             platform=platform)
        sys.path.append(conf.volatility_path)
        sys.path.append(root_path)
        sys.path.append(os.getcwd())
        # Set global configuration
        conf_m.conf = conf
        if not init_volatility(conf_m.conf):
            return None

        # Initialize the shell now
        from ipython_shell import initialize_shell
        initialize_shell()

        # Locate python modules that should be loaded by default
        for (module, enable) in config.items("MODULES"):
            if enable.strip().lower() == "true" or enable.strip().lower(
            ) == "yes":
                import_module(module)

        pp_debug("[*] Finished python module initialization\n")
        return vol_profile
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 9
0
def init(platform, root_path, volatility_path, conf_name):
    try:
        # Just configure basic logging
        import logging
        logging.basicConfig()
        # Initialize stuff
        pp_debug("[*] Platform: %s\n" % platform)
        pp_debug("[*] Starting python module initialization\n")
        pp_debug("[*] Reading configuration from '%s'\n" % (conf_name))
        sys.settrace
        config = ConfigParser.RawConfigParser()
        # Store configuration information in raw,
        # for plugins to be able to fetch it
        conf_m.config = config
        if not os.path.isfile(conf_name):
            pp_error("[!] Could not initialize pyrebox, conf file '%s' missing!\n" % (conf_name))
            return None
        config.read(conf_name)
        vol_profile = config.get('VOL', 'profile')
        # Set global configuration
        conf_m.volatility_path = volatility_path
        conf_m.vol_profile = vol_profile
        conf_m.platform = platform
        conf_m.pyre_root = root_path

        if platform == "x86_64-softmmu":
            conf_m.bitness = 64
            conf_m.endianess = "l" 
        elif platform == "i386-softmmu":
            conf_m.bitness = 32
            conf_m.endianess = "l" 

        sys.path.append(volatility_path)
        sys.path.append(root_path)
        sys.path.append(os.getcwd())
        if not init_volatility():
            return None

        # Initialize the shell now
        from ipython_shell import initialize_shell
        initialize_shell()

        # Initialize the symbol cache from the file
        if config.has_option('SYMBOL_CACHE', 'path'):
            from vmi import load_symbols_from_cache_file
            from vmi import set_symbol_cache_path
            set_symbol_cache_path(config.get('SYMBOL_CACHE', 'path'))
            load_symbols_from_cache_file()

        return vol_profile
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 10
0
def init(platform, root_path, volatility_path, conf_name):
    try:
        # Just configure basic logging
        import logging
        logging.basicConfig()
        # Initialize stuff
        pp_debug("[*] Platform: %s\n" % platform)
        pp_debug("[*] Starting python module initialization\n")
        pp_debug("[*] Reading configuration from '%s'\n" % (conf_name))
        sys.settrace
        config = ConfigParser.RawConfigParser()
        # Store configuration information in raw,
        # for plugins to be able to fetch it
        conf_m.config = config
        if not os.path.isfile(conf_name):
            pp_error(
                "[!] Could not initialize pyrebox, conf file '%s' missing!\n" %
                (conf_name))
            return None
        config.read(conf_name)
        vol_profile = config.get('VOL', 'profile')
        # Set global configuration
        conf_m.volatility_path = volatility_path
        conf_m.vol_profile = vol_profile
        conf_m.platform = platform
        conf_m.pyre_root = root_path
        sys.path.append(volatility_path)
        sys.path.append(root_path)
        sys.path.append(os.getcwd())
        if not init_volatility():
            return None

        # Initialize the shell now
        from ipython_shell import initialize_shell
        initialize_shell()

        return vol_profile
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 11
0
def init(platform, root_path, volatility_path, conf_name):
    try:
        # Just configure basic logging
        import logging
        logging.basicConfig()
        # Initialize stuff
        pp_debug("[*] Platform: %s\n" % platform)
        pp_debug("[*] Starting python module initialization\n")
        pp_debug("[*] Reading configuration from '%s'\n" % (conf_name))
        sys.settrace
        config = ConfigParser.RawConfigParser()
        # Store configuration information in raw,
        # for plugins to be able to fetch it
        conf_m.config = config
        if not os.path.isfile(conf_name):
            pp_error("[!] Could not initialize pyrebox, conf file '%s' missing!\n" % (conf_name))
            return None
        config.read(conf_name)
        vol_profile = config.get('VOL', 'profile')
        # Set global configuration
        conf_m.volatility_path = volatility_path
        conf_m.vol_profile = vol_profile
        conf_m.platform = platform
        sys.path.append(volatility_path)
        sys.path.append(root_path)
        sys.path.append(os.getcwd())
        if not init_volatility():
            return None

        # Initialize the shell now
        from ipython_shell import initialize_shell
        initialize_shell()

        return vol_profile
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e
Ejemplo n.º 12
0
        # Initialize the shell now
        from ipython_shell import initialize_shell
        initialize_shell()

        return vol_profile
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e


def init_plugins():
    try:
        pp_debug("[*] Initializing scripts...\n")
        # Locate python modules that should be loaded by default
        for (module, enable) in conf_m.config.items("MODULES"):
            if enable.strip().lower() == "true" or enable.strip().lower() == "yes":
                import_module(module)

        pp_debug("[*] Finished python module initialization\n")
        return True
    except Exception as e:
        # Do this to make sure we print the stack trace to help trouble-shooting
        traceback.print_exc()
        raise e


if __name__ == "__main__":
    pp_debug("\n[*] Loading python component initialization script\n")
Ejemplo n.º 13
0
def ntreadfile(params, cm, proc, update_vads, long_size, is_write=False):
    import volatility.win32.tasks as tasks
    from core import FileRead
    from core import FileWrite
    from core import File
    from utils import get_addr_space
    import api
    TARGET_LONG_SIZE = api.get_os_bits() / 8
    global interproc_data
    global interproc_config

    cpu_index = params["cpu_index"]
    cpu = params["cpu"]

    # IN HANDLE   FileHandle,
    # IN HANDLE Event     OPTIONAL,
    # IN PIO_APC_ROUTINE ApcRoutine   OPTIONAL,
    # IN PVOID ApcContext     OPTIONAL,
    # OUT PIO_STATUS_BLOCK    IoStatusBlock,
    # OUT PVOID   Buffer,
    # IN ULONG    Length,
    # IN PLARGE_INTEGER ByteOffset    OPTIONAL,
    # IN PULONG Key   OPTIONAL

    pgd = api.get_running_process(cpu_index)

    # Read the parameters
    ret_addr, file_handle, arg2, arg3, arg4, arg5, buff, length, offset_p, arg9 = read_parameters(
        cpu, 9, long_size)

    # Load volatility address space
    addr_space = get_addr_space(pgd)

    # Get list of processes, and filter out by the process that triggered the
    # call (current process id)
    eprocs = [
        t for t in tasks.pslist(addr_space)
        if t.UniqueProcessId == proc.get_pid()
    ]

    # Initialize file_obj, that will point to the object of the referenced file
    file_obj = None

    # Search handle table for the new created process
    for task in eprocs:
        if task.UniqueProcessId == proc.get_pid(
        ) and task.ObjectTable.HandleTableList:
            for handle in task.ObjectTable.handles():
                if handle.is_valid(
                ) and handle.HandleValue == file_handle and handle.get_object_type(
                ) == "File":
                    file_obj = handle.dereference_as("_FILE_OBJECT")
                    break
            break

    if file_obj is not None:
        file_instance = interproc_data.get_file_by_file_name(
            str(file_obj.FileName))

        # If we have still not recorded the file, add it to files to record
        if file_instance is None:
            file_instance = File(str(file_obj.FileName))
            interproc_data.add_file(file_instance)
        # Now, record the read/write
        # curr_file_offset is never used
        # curr_file_offset = int(file_obj.CurrentByteOffset.QuadPart)
        # FO_SYNCHRONOUS_IO     0x0000002
        is_offset_maintained = ((file_obj.Flags & 0x0000002) != 0)

        # If no offset was specified, and the offset is mantained, the real
        # offset is taken from the file object
        offset = None
        if offset_p == 0 and is_offset_maintained:
            offset = int(file_obj.CurrentByteOffset.QuadPart)
        elif offset_p != 0:
            # If an offset is provided, the current offset in the file_object
            # will be updated, regardless of the flag.
            try:
                offset = struct.unpack("Q", api.r_va(pgd, offset_p, 8))[0]
            except:
                offset = 0
                pp_debug(
                    "Could not dereference offset in NtReadFile call in interproc_callbacks.py\n"
                )
        else:
            # If no offset was specified and the file object does not have the flag set, we may be in front of some kind
            # of corruption error or deliberate manipulation
            pp_debug(
                "[!] The file object flag FO_SYNCHRONOUS_IO is not set, and no offset was provided\n"
            )
            return

        # At this moment we do not record the data
        op = None

        local_proc = proc

        if not is_write:
            op = FileRead(file_instance, local_proc, buff, offset, length,
                          None)
            if interproc_config.interproc_text_log and interproc_config.interproc_text_log_handle is not None:
                f = interproc_config.interproc_text_log_handle
                if TARGET_LONG_SIZE == 4:
                    f.write(
                        "[PID: %08x] NtReadFile: Offset: %08x Size: %08x / %s\n"
                        % (proc.get_pid(), offset, length,
                           str(file_obj.FileName)))
                elif TARGET_LONG_SIZE == 8:
                    f.write(
                        "[PID: %08x] NtReadFile: Offset: %16x Size: %16x / %s\n"
                        % (proc.get_pid(), offset, length,
                           str(file_obj.FileName)))
        else:
            op = FileWrite(file_instance, local_proc, buff, offset, length,
                           None)
            if interproc_config.interproc_text_log and interproc_config.interproc_text_log_handle is not None:
                f = interproc_config.interproc_text_log_handle
                if TARGET_LONG_SIZE == 4:
                    f.write(
                        "[PID: %08x] NtWriteFile: Offset: %08x Size: %08x / %s\n"
                        % (proc.get_pid(), offset, length,
                           str(file_obj.FileName)))
                elif TARGET_LONG_SIZE == 8:
                    f.write(
                        "[PID: %08x] NtWriteFile: Offset: %16x Size: %16x / %s\n"
                        % (proc.get_pid(), offset, length,
                           str(file_obj.FileName)))

        file_instance.add_operation(op)
        local_proc.add_file_operation(op)

    if update_vads:
        proc.update_vads()
Ejemplo n.º 14
0
def ntwritevirtualmemory(params,
                         cm,
                         proc,
                         update_vads,
                         long_size,
                         reverse=False):
    import volatility.win32.tasks as tasks
    from core import Injection
    import api
    from utils import get_addr_space
    global interproc_data
    global interproc_config

    TARGET_LONG_SIZE = api.get_os_bits() / 8

    cpu_index = params["cpu_index"]
    cpu = params["cpu"]

    # _In_ HANDLE     ProcessHandle,
    # _In_ PVOID  BaseAddress,
    # _In_ PVOID  Buffer,
    # _In_ SIZE_T     NumberOfBytesToWrite,
    # _Out_opt_ PSIZE_T   NumberOfBytesWritten

    pgd = api.get_running_process(cpu_index)

    # Read the parameters
    ret_addr, proc_hdl, remote_addr, local_addr, size, size_out = read_parameters(
        cpu, 5, long_size)

    local_proc = proc

    # Try to get remote process from list of monitored processes
    remote_proc = None
    # Load volatility address space
    addr_space = get_addr_space(pgd)

    # Get list of processes, and filter out by the process that triggered the
    # call (current process id)
    eprocs = [
        t for t in tasks.pslist(addr_space)
        if t.UniqueProcessId == proc.get_pid()
    ]

    # Initialize proc_obj, that will point to the eprocess of the new created
    # process
    proc_obj = None

    # Search handle table for the new created process
    for task in eprocs:
        if task.UniqueProcessId == proc.get_pid(
        ) and task.ObjectTable.HandleTableList:
            for handle in task.ObjectTable.handles():
                if handle.is_valid(
                ) and handle.HandleValue == proc_hdl and handle.get_object_type(
                ) == "Process":
                    proc_obj = handle.dereference_as("_EPROCESS")
                    break
            break

    if proc_obj is not None:
        remote_proc = interproc_data.get_process_by_pid(
            int(proc_obj.UniqueProcessId))
    else:
        # Sometimes we get calls to this function over non-proc handles (e.g. type "Desktop")
        return
    if remote_proc is None:
        pp_debug("[!]  Could not obtain remote proc, or it is not monitored\n")
        return
    elif local_proc is None:
        pp_debug("[!]  Could not obtain local proc, or it is not monitored\n")
        return
    else:
        if reverse:
            data = None
            if interproc_config.interproc_text_log and interproc_config.interproc_text_log_handle is not None:
                f = interproc_config.interproc_text_log_handle
                if TARGET_LONG_SIZE == 4:
                    f.write(
                        "[PID: %08x] NtReadVirtualMemory: PID: %x - Addr: %08x <-- PID: %x Addr: %08x / Size: %08x\n"
                        % (proc.get_pid(), local_proc.get_pid(), local_addr,
                           remote_proc.get_pid(), remote_addr, size))
                elif TARGET_LONG_SIZE == 8:
                    f.write(
                        "[PID: %08x] NtReadVirtualMemory: PID: %x - Addr: %16x <-- PID: %x Addr: %16x / Size: %16x\n"
                        % (proc.get_pid(), local_proc.get_pid(), local_addr,
                           remote_proc.get_pid(), remote_addr, size))
        else:
            data = None
            if interproc_config.interproc_text_log and interproc_config.interproc_text_log_handle is not None:
                f = interproc_config.interproc_text_log_handle
                if TARGET_LONG_SIZE == 4:
                    f.write(
                        "[PID: %08x] NtWriteVirtualMemory: PID: %x - Addr: %08x --> PID: %x Addr: %08x / Size: %08x\n"
                        % (proc.get_pid(), local_proc.get_pid(), local_addr,
                           remote_proc.get_pid(), remote_addr, size))
                elif TARGET_LONG_SIZE == 8:
                    f.write(
                        "[PID: %08x] NtWriteVirtualMemory: PID: %x - Addr: %16x --> PID: %x Addr: %16x / Size: %16x\n"
                        % (proc.get_pid(), local_proc.get_pid(), local_addr,
                           remote_proc.get_pid(), remote_addr, size))

        inj = Injection(remote_proc, remote_addr, local_proc, local_addr, size,
                        data, reverse)
        local_proc.add_injection(inj)

    if update_vads:
        proc.update_vads()
Ejemplo n.º 15
0
def windows_insert_module_internal(
        p_pid,
        p_pgd,
        base,
        size,
        fullname,
        basename,
        checksum,
        update_symbols,
        do_stop = False):

    from utils import get_addr_space
    from vmi import add_symbols
    from vmi import get_symbols
    from vmi import has_symbols
    from vmi import Module
    from vmi import add_module
    from vmi import get_module
    from vmi import has_module
    from api_internal import dispatch_module_load_callback
    from api_internal import dispatch_module_remove_callback
    import pefile
    import api

    global filesystem
    global symbol_cache_must_be_saved

    if fullname.startswith("\\??\\"):
        fullname = fullname[4:]
    if fullname.upper().startswith("C:\\"):
        fullname = fullname[3:]
    if fullname.upper().startswith("\\SYSTEMROOT"):
        fullname = "\WINDOWS" + fullname[11:]

    fullname = fullname.replace("\\", "/")

    if fullname[-4:].upper() == ".SYS" and not "/" in fullname:
        fullname = "/WINDOWS/system32/DRIVERS/" + fullname

    fullname = fullname.lower()

    mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname)

    # First, we try to get the symbols from the cache 
    if fullname != "" and has_symbols(fullname):
        mod.set_symbols(get_symbols(fullname))

    # If we are updating symbols (a simple module retrieval would
    # not require symbol extraction), and we don't have any
    # symbols on the cache:
    elif fullname != "" and update_symbols:
        pp_debug("Symbols not found in cache, extracting from %s...\n" % fullname)
        unnamed_function_counter = 0
        syms = {}
    
        # Here, fetch the file using the sleuthkit, and use 
        # PE file to process it
        
        # First select the file system if not selected already
        if filesystem is None:
            for fs in api.get_filesystems():
                file_list = api.open_guest_path(fs["index"], "")
                if isinstance(file_list, list) and len(file_list) > 0:
                    if "windows" in [f.lower() for f in file_list]:
                        filesystem = fs

        if filesystem is not None:
            # Try to read the file
            f = None
            try:
                f = api.open_guest_path(filesystem["index"], fullname)
            except Exception as e:
                pp_error("%s - %s\n" % (str(e), fullname))

            if f is not None:
                data = f.read()
        
                pe = pefile.PE(data=data)

                if hasattr(pe, "DIRECTORY_ENTRY_EXPORT"):
                    for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                        if exp.name is not None:
                            syms[exp.name] = exp.address
                        else:
                            syms["unnamed_funcion_%d" % unnamed_function_counter] = exp.address
                            unnamed_function_counter += 1

        add_symbols(fullname, syms)
        mod.set_symbols(syms)
        # Even if it is empty, the module symbols are set
        # to an empty list, and thus are 'resolved'.
        # Anyway, in future updates, they could be resolved,
        # as we allow this in the first condition.
        symbol_cache_must_be_saved = True
 
    #Module load/del notification
    if has_module(p_pid, p_pgd, base):
        ex_mod = get_module(p_pid, p_pgd, base)
        # Module replacement, only if it is a different module, and also
        # take into consideration wow64 redirection. Never substitute the
        # wow64 version by the system32 version of the same dll
        if (ex_mod.get_fullname().lower() != fullname.lower()) and not ((ex_mod.get_name().lower() == basename.lower()) and ("windows/syswow64".lower() in ex_mod.get_fullname().lower()) and ("windows/system32" in fullname.lower())):
            # Notify of module deletion and module load
            dispatch_module_remove_callback(p_pid, p_pgd, base,
                                            ex_mod.get_size(),
                                            ex_mod.get_name(),
                                            ex_mod.get_fullname())
            add_module(p_pid, p_pgd, base, mod)
            mod.set_present()
            dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname)

        # If we updated the symbols and have a bigger list now, dont substitute the module
        # but update its symbols instead
        elif len(mod.get_symbols()) > len(ex_mod.get_symbols()):
            ex_mod.set_symbols(mod.get_symbols())
        # In any case, mark as present 
        ex_mod.set_present()
    else:
        # Just notify of module load
        add_module(p_pid, p_pgd, base, mod)
        # Mark the module as present
        mod.set_present()
        dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname)
Ejemplo n.º 16
0
def gdb_read_thread_register(thread_id, thread_list, gdb_register_index):
    '''
    Given a GDB register index, return an str with its value. Obtain
    the value either from the running CPU or the saved KTRAP_FRAME.
    NOTE: Not all registers are supported, if so, 0's are returned.
    '''
    from utils import ConfigurationManager as conf_m
    from api import r_cpu
    from cpus import RT_SEGMENT
    from cpus import RT_REGULAR

    if conf_m.platform == "i386-softmmu":
        from cpus import gdb_map_i386_softmmu as gdb_map
    elif conf_m.platform == "x86_64-softmmu":
        from cpus import gdb_map_x86_64_softmmu as gdb_map
    else:
        raise NotImplementedError(
            "[gdb_read_thread_register] Architecture not supported yet")

    # If it is not mapped to a CPU register or KTRAP_FRAME value,
    # we just return 0s.
    if gdb_register_index not in gdb_map:
        return "\0" * (conf_m.bitness / 8)
    else:
        str_size = gdb_map[gdb_register_index][2]

    cpu_index = None
    thread = None

    some_thread_running = False
    # First, check if we can read the register from the CPU object
    for element in thread_list:
        if element['id'] == thread_id:
            thread = element
            cpu_index = element['running']
            if cpu_index:
                some_thread_running = True

    if thread is None:
        return None

    if cpu_index is None and not some_thread_running:
        cpu_index = 0

    if cpu_index is not None:
        cpu = r_cpu(cpu_index)
        val = 0
        try:
            if gdb_map[gdb_register_index][3] == RT_SEGMENT:
                val = getattr(cpu, gdb_map[gdb_register_index][0])['base']
            else:
                val = getattr(cpu, gdb_map[gdb_register_index][0])
        except:
            val = 0
        if val == -1:
            val = 0
        return val_to_str(val, str_size)
    # If the thread is not running, read it from the KTRAP_FRAME
    else:
        if os_family == OS_FAMILY_WIN:
            from windows_vmi import win_read_thread_register_from_ktrap_frame
            val = 0
            try:
                val = win_read_thread_register_from_ktrap_frame(
                    thread, gdb_map[gdb_register_index][1])
            except Exception as e:
                pp_debug(
                    "Exception after win_read_thread_register_from_ktrap_frame: "
                    + str(e))
            if val == -1:
                val = 0
            return val_to_str(val, str_size)
        elif os_family == OS_FAMILY_LINUX:
            raise NotImplementedError(
                "gdb_read_thread_register not implemented yet on Linux guests")
Ejemplo n.º 17
0
        pp_error("[!] Could not initialize pyrebox, pyrebox.conf file missing!\n")
        return None
    config.read('pyrebox.conf')
    vol_profile = config.get('VOL', 'profile')
    conf = ConfigManager(
        volatility_path=volatility_path,
        vol_profile=vol_profile,
        platform=platform)
    sys.path.append(conf.volatility_path)
    sys.path.append(root_path)
    sys.path.append(os.getcwd())
    # Set global configuration
    conf_m.conf = conf
    init_volatility(conf_m.conf)

    # Initialize the shell now
    from ipython_shell import initialize_shell
    initialize_shell()

    # Locate python modules that should be loaded by default
    for (module, enable) in config.items("MODULES"):
        if enable.strip().lower() == "true" or enable.strip().lower() == "yes":
            import_module(module)

    pp_debug("[*] Finished python module initialization\n")
    return vol_profile


if __name__ == "__main__":
    pp_debug("\n[*] Loading python component initialization script\n")
Ejemplo n.º 18
0
def read_parameters(cpu, num_params, long_size):
    '''
        Reads parameters from the registers/stack
    '''
    import api
    TARGET_LONG_SIZE = api.get_os_bits() / 8
    if long_size == 4:
        # All the parameters are on the stack
        # We need to read num_params values + the return address
        try:
            if TARGET_LONG_SIZE == 4:
                buff = api.r_va(cpu.CR3, cpu.ESP, (num_params + 1) * 4)
            else:
                buff = api.r_va(cpu.CR3, cpu.RSP, (num_params + 1) * 4)
        except:
            buff = "\x00" * ((num_params + 1) * 4)
            if TARGET_LONG_SIZE == 4:
                pp_debug(
                    "Could not read properly the parameters in interproc_callbacks.py at address %x - size %x"
                    % (cpu.ESP, (num_params + 1) * 4))
            else:
                pp_debug(
                    "Could not read properly the parameters in interproc_callbacks.py at address %x - size %x"
                    % (cpu.RSP, (num_params + 1) * 4))
        params = struct.unpack("<" + "I" * (1 + num_params), buff)
        return params
    elif long_size == 8:
        params_regs = []
        params_stack = ()

        # Add the return address as parameter 0
        try:
            buff = api.r_va(cpu.CR3, cpu.RSP, 8)
        except:
            buff = "\x00" * 8
            pp_debug(
                "Could not read properly the parameters in interproc_callbacks.py"
            )

        params_regs.append(struct.unpack("<Q", buff)[0])

        if num_params >= 1:
            params_regs.append(cpu.RCX)
        if num_params >= 2:
            params_regs.append(cpu.RDX)
        if num_params >= 3:
            params_regs.append(cpu.R8)
        if num_params >= 4:
            params_regs.append(cpu.R9)
        if num_params > 4:
            # We need to read num_params (-4 parameters read from
            # registers) + the return address + 0x20
            # 0x20 is for the 4 slots (of 8 bytes) allocated to store
            # register parameters (allocated by caller, used by callee)
            try:
                buff = api.r_va(cpu.CR3, cpu.RSP, (num_params + 5 - 4) * 8)
            except:
                buff = "\x00" * ((num_params + 5 - 4) * 8)
                pp_debug(
                    "Could not read properly the parameters in interproc_callbacks.py"
                )

            params_stack = struct.unpack("<" + "Q" * (5 + num_params - 4),
                                         buff)
            params_stack = params_stack[5:]
        return (tuple(params_regs) + params_stack)
    else:
        raise Exception(
            "[interproc::read_return_parameter(cpu)] : Non-supported TARGET_LONG_SIZE: %d"
            % long_size)