コード例 #1
0
def module_entry_point(params):
    '''
        Callback on the entry point of the main module being monitored
    '''
    global cm
    global UNPACKER_LOG_PATH
    global UNPACKER_DUMP_PATH
    global pyrebox_print
    global ntdll_space

    from api import CallbackManager
    import api

    # Get pameters
    cpu_index = params["cpu_index"]
    cpu = params["cpu"]

    # Get running process
    pgd = api.get_running_process(cpu_index)

    pyrebox_print("Reached entry point of new process: %x" % pgd)

    # Add memory write / memory execute callbacks, and their triggers
    cm.add_callback(CallbackManager.MEM_WRITE_CB,
                    mem_write,
                    name="mem_write_%x" % pgd)
    cm.add_callback(CallbackManager.BLOCK_BEGIN_CB,
                    block_exec,
                    name="block_begin_%x" % pgd)

    cm.add_trigger("mem_write_%x" % pgd, "triggers/trigger_memwrite_wx.so")
    cm.set_trigger_var("mem_write_%x" % pgd, "begin", 0x0)
    if TARGET_LONG_SIZE == 4:
        cm.set_trigger_var("mem_write_%x" % pgd, "end", 0x80000000)
    else:
        cm.set_trigger_var("mem_write_%x" % pgd, "end", 0x000007FFFFFFFFFF)
    cm.set_trigger_var("mem_write_%x" % pgd, "pgd", pgd)

    cm.add_trigger("block_begin_%x" % pgd, "triggers/trigger_blockbegin_wx.so")
    cm.set_trigger_var("block_begin_%x" % pgd, "begin", 0x0)
    if TARGET_LONG_SIZE == 4:
        cm.set_trigger_var("block_begin_%x" % pgd, "end", 0x80000000)
    else:
        cm.set_trigger_var("block_begin_%x" % pgd, "end", 0x000007FFFFFFFFFF)
    cm.set_trigger_var("block_begin_%x" % pgd, "pgd", pgd)

    # Start monitoring process
    api.start_monitoring_process(pgd)

    # Create a dump, on process entry point for every process
    generate_dump(pgd, "Dump at process entry point for PGD 0x%x" % pgd)

    # Get the address space for ntdll
    for mod in api.get_module_list(pgd):
        if "ntdll.dll" in mod["name"].lower():
            ntdll_space = (mod["base"], mod["size"])
コード例 #2
0
    def update_symbols(self):
        import api
        from api import CallbackManager
        global mods_pending_symbol_resolution

        if self.unpickled:
            return

        syms = api.get_symbol_list()

        # Check if we can remove the module from the list of modules with
        # pending symbol resolution
        for mod in api.get_module_list(self.get_pgd()):
            if mod["symbols_resolved"] and mod["name"] in mods_pending_symbol_resolution.get(self.get_pgd(), []):
                del mods_pending_symbol_resolution[self.get_pgd()][mod["name"]]

        for d in syms:
            mod = d["mod"]
            fun = d["name"]
            addr = d["addr"]

            pos = bisect.bisect_left(self.symbols, Symbol("", "", addr))
            if pos >= 0 and pos < len(self.symbols) and self.symbols[pos].get_addr() == addr:
                continue
            if mod in self.modules:
                for pair in self.modules[mod]:
                    # Update the (include/exclude addresses in apitracer)
                    if mwmon.include_apis is not None:
                        if (mod.lower(), fun.lower()) in mwmon.include_apis:
                            if (pair[0] + addr) not in mwmon.include_apis_addrs:
                                mwmon.include_apis_addrs.append(pair[0] + addr)

                    if mwmon.exclude_apis is not None:
                        if (mod.lower(), fun.lower()) in mwmon.exclude_apis:
                            if (pair[0] + addr) not in mwmon.exclude_apis_addrs:
                                mwmon.exclude_apis_addrs.append(pair[0] + addr)

                    bisect.insort(
                        self.symbols, Symbol(mod, fun, pair[0] + addr))
                    if mwmon.interproc or mwmon.api_tracer or mwmon.dumper:
                        # Add breakpoint if necessary
                        if (mod, fun) in self.breakpoints and self.breakpoints[(mod, fun)] is None:
                            f_callback = self.bp_funcs[(mod, fun)][0]
                            update_vads = self.bp_funcs[(mod, fun)][1]
                            callback = functools.partial(
                                f_callback, pid=self.pid, proc=self, update_vads=update_vads)
                            bp = mwmon.cm.add_callback(CallbackManager.INSN_BEGIN_CB,
                                                       callback,
                                                       name="api_bp_%x_%s" % (self.pid, fun),
                                                       addr=pair[0] + addr,
                                                       pgd=self.pgd)
                            self.breakpoints[(mod, fun)] = (bp, pair[0] + addr)
                            mwmon.printer("Adding breakpoint at %s:%s %x:%x from process with PID %x" %
                                          (mod, fun, pair[0] + addr, self.pgd, self.pid))
コード例 #3
0
    def update_symbols(self):
        import api
        from api import CallbackManager
        global mods_pending_symbol_resolution

        if self.unpickled:
            return

        syms = api.get_symbol_list()

        # Check if we can remove the module from the list of modules with
        # pending symbol resolution
        for mod in api.get_module_list(self.get_pgd()):
            if mod["symbols_resolved"] and mod["name"] in mods_pending_symbol_resolution.get(self.get_pgd(), []):
                del mods_pending_symbol_resolution[self.get_pgd()][mod["name"]]

        for d in syms:
            mod = d["mod"]
            fun = d["name"]
            addr = d["addr"]

            pos = bisect.bisect_left(self.symbols, Symbol("", "", addr))
            if pos >= 0 and pos < len(self.symbols) and self.symbols[pos].get_addr() == addr:
                continue
            if mod in self.modules:
                for pair in self.modules[mod]:
                    # Update the (include/exclude addresses in apitracer)
                    if mwmon.include_apis is not None:
                        if (mod.lower(), fun.lower()) in mwmon.include_apis:
                            if (pair[0] + addr) not in mwmon.include_apis_addrs:
                                mwmon.include_apis_addrs.append(pair[0] + addr)

                    if mwmon.exclude_apis is not None:
                        if (mod.lower(), fun.lower()) in mwmon.exclude_apis:
                            if (pair[0] + addr) not in mwmon.exclude_apis_addrs:
                                mwmon.exclude_apis_addrs.append(pair[0] + addr)

                    bisect.insort(
                        self.symbols, Symbol(mod, fun, pair[0] + addr))
                    if mwmon.interproc or mwmon.api_tracer or mwmon.dumper:
                        # Add breakpoint if necessary
                        if (mod, fun) in self.breakpoints and self.breakpoints[(mod, fun)] is None:
                            f_callback = self.bp_funcs[(mod, fun)][0]
                            update_vads = self.bp_funcs[(mod, fun)][1]
                            callback = functools.partial(
                                f_callback, pid=self.pid, proc=self, update_vads=update_vads)
                            bp = mwmon.cm.add_callback(CallbackManager.INSN_BEGIN_CB,
                                                       callback,
                                                       name="api_bp_%x_%s" % (self.pid, fun),
                                                       addr=pair[0] + addr,
                                                       pgd=self.pgd)
                            self.breakpoints[(mod, fun)] = (bp, pair[0] + addr)
                            mwmon.printer("Adding breakpoint at %s:%s %x:%x from process with PID %x" %
                                          (mod, fun, pair[0] + addr, self.pgd, self.pid))
コード例 #4
0
def context_change(new_proc, target_mod_name, params):
    '''Callback triggered for every context change'''
    global ntdll_breakpoint
    from mw_monitor_classes import mwmon
    from api import BP
    import api
    from api import CallbackManager
    from functools import partial

    old_pgd = params["old_pgd"]
    new_pgd = params["new_pgd"]

    if new_proc.get_pgd() == new_pgd:
        ep = find_ep(new_proc, target_mod_name)
        if ep is not None:
            mwmon.printer("The entry point for %s is %x\n" %
                          (target_mod_name, ep))
            mwmon.cm.rm_callback("context_change_%x" % new_proc.get_pgd())

            try:
                # Load modules and symbols for the process
                mods = api.get_module_list(new_proc.get_pgd())
                if mods is not None:
                    for m in mods:
                        name = m["name"]
                        base = m["base"]
                        size = m["size"]
                        new_proc.set_module(name, base, size)
                        # NTDLL is a special case, and we set a breakpoint
                        # on the code of the main module to trigger the symbol resolution
                        # as soon as we execute one instruction in its
                        # region
                        if target_mod_name in name:
                            ntdll_breakpoint[new_proc.get_pgd()] = BP(
                                base,
                                new_proc.get_pgd(),
                                size=size,
                                func=partial(ntdll_breakpoint_func, new_proc),
                                new_style=True)
                            ntdll_breakpoint[new_proc.get_pgd()].enable()

            except ValueError as e:
                # The process has not been created yet, so we need to
                # wait for symbol resolution
                pass

            # Callback for each module loaded
            mwmon.cm.add_callback(CallbackManager.LOADMODULE_CB,
                                  module_loaded,
                                  pgd=new_proc.get_pgd(),
                                  name=("load_module_%x" % new_proc.get_pgd()))
コード例 #5
0
def context_change(new_proc, target_mod_name, params):
    '''Callback triggered for every context change'''
    global ntdll_breakpoint
    from mw_monitor_classes import mwmon
    from api import BP
    import api
    from api import CallbackManager
    from functools import partial

    old_pgd = params["old_pgd"]
    new_pgd = params["new_pgd"]

    if new_proc.get_pgd() == new_pgd:
        ep = find_ep(new_proc, target_mod_name)
        if ep is not None:
            mwmon.printer("The entry point for %s is %x\n" % (target_mod_name, ep))
            mwmon.cm.rm_callback("context_change_%x" % new_proc.get_pgd())

            try:
                # Load modules and symbols for the process
                mods = api.get_module_list(new_proc.get_pgd())
                if mods is not None:
                    for m in mods:
                        name = m["name"]
                        base = m["base"]
                        size = m["size"]
                        new_proc.set_module(name, base, size)
                        # NTDLL is a special case, and we set a breakpoint
                        # on the code of the main module to trigger the symbol resolution
                        # as soon as we execute one instruction in its 
                        # region
                        if target_mod_name in name:
                            ntdll_breakpoint[new_proc.get_pgd()] = BP(base, 
                                                  new_proc.get_pgd(), 
                                                  size = size,
                                                  func = partial(ntdll_breakpoint_func, new_proc),
                                                  new_style = True)
                            ntdll_breakpoint[new_proc.get_pgd()].enable()

            except ValueError as e:
                # The process has not been created yet, so we need to 
                # wait for symbol resolution
                pass

            # Callback for each module loaded
            mwmon.cm.add_callback(CallbackManager.LOADMODULE_CB, 
                                  module_loaded, 
                                  pgd = new_proc.get_pgd(), 
                                  name = ("load_module_%x" % new_proc.get_pgd()))
コード例 #6
0
ファイル: interproc.py プロジェクト: yanshu911/pyrebox
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))
コード例 #7
0
def find_ep(pgd, proc_name):
    '''Given an address space and a process name, uses pefile module
       to get its entry point
    '''
    global cm
    global loaded_processes
    import api
    for m in api.get_module_list(pgd):
        name = m["name"]
        base = m["base"]
        # size = m["size"]
        if name == proc_name:
            try:
                pe_data = api.r_va(pgd, base, 0x1000)
                pe = pefile.PE(data=pe_data)
                ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint
                return (base + ep)
            except Exception:
                pyrebox_print("Unable to run pefile on loaded module %s" % name)
コード例 #8
0
ファイル: script_example.py プロジェクト: CRYP706URU/pyrebox
def find_ep(pgd, proc_name):
    '''Given an address space and a process name, uses pefile module
       to get its entry point
    '''
    global cm
    global loaded_processes
    import api
    for m in api.get_module_list(pgd):
        name = m["name"]
        base = m["base"]
        # size = m["size"]
        if name == proc_name:
            try:
                pe_data = api.r_va(pgd, base, 0x1000)
                pe = pefile.PE(data=pe_data)
                ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint
                return (base + ep)
            except Exception:
                pyrebox_print("Unable to run pefile on loaded module %s" % name)
コード例 #9
0
    def __context_change_callback(self, target_pgd, target_mod_name, params):
        """
            Updates the module base (to have the absolute agent buffer address) as soon
            as it is available.
        """
        global cm
        old_pgd = params["old_pgd"]
        new_pgd = params["new_pgd"]
        try:
            if target_pgd == new_pgd and self.__status == GuestAgentPlugin.__AGENT_RUNNING:
                lowest_addr = None

                for m in api.get_module_list(target_pgd):
                    name = m["name"]
                    base = m["base"]
                    # size = m["size"]
                    if name == target_mod_name or target_mod_name in name:
                        if lowest_addr is None:
                            lowest_addr = base
                        elif base < lowest_addr:
                            lowest_addr = base

                if self.__agent_buffer_offset is not None and \
                    lowest_addr is not None:

                    self.__agent_buffer_address = lowest_addr + \
                        self.__agent_buffer_offset
                    # Now, our agent is fully up and running
                    self.__status = GuestAgentPlugin.__AGENT_READY
                    # Now, we add the opcode hook and start monitoring the
                    # process
                    self.__cb.add_callback(
                        api.CallbackManager.REMOVEPROC_CB,
                        self.__remove_process_callback,
                        name="host_file_plugin_process_REMOVE")

                    self.__cb.rm_callback("context_change_guest_agent")
        except Exception as e:
            self.__printer(
                "Exception occurred on context change callback: %s" % str(e))
コード例 #10
0
def find_ep(proc, proc_name):
    '''Given an address space and a process name, uses pefile module
       to get its entry point
    '''
    import api
    import pefile
    from mw_monitor_classes import mwmon

    try:
        for m in api.get_module_list(proc.get_pgd()):
            name = m["name"]
            base = m["base"]
            # size = m["size"]
            if name == proc_name:
                    pe_data = api.r_va(proc.get_pgd(), base, 0x1000)
                    pe = pefile.PE(data=pe_data)
                    ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint
                    return (base + ep)
    except Exception as e:
        mwmon.printer("Unable to run pefile on loaded module %s (%s)" % (proc_name, str(e)))
        pass
    return None
コード例 #11
0
def find_ep(proc, proc_name):
    '''Given an address space and a process name, uses pefile module
       to get its entry point
    '''
    import api
    import pefile
    from mw_monitor_classes import mwmon

    try:
        for m in api.get_module_list(proc.get_pgd()):
            name = m["name"]
            base = m["base"]
            # size = m["size"]
            if proc_name in name:
                    pe_data = api.r_va(proc.get_pgd(), base, 0x1000)
                    pe = pefile.PE(data=pe_data)
                    ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint
                    return (base + ep)
    except Exception as e:
        mwmon.printer("Unable to run pefile on loaded module %s (%s)" % (proc_name, str(e)))
        pass
    return None
コード例 #12
0
ファイル: guest_agent.py プロジェクト: CRYP706URU/pyrebox
    def __context_change_callback(self, target_pgd, target_mod_name, params):
        """
            Updates the module base (to have the absolute agent buffer address) as soon
            as it is available.
        """
        global cm
        old_pgd = params["old_pgd"]
        new_pgd = params["new_pgd"]
        try:
            if target_pgd == new_pgd and self.__status == GuestAgentPlugin.__AGENT_RUNNING:
                lowest_addr = None

                for m in api.get_module_list(target_pgd):
                    name = m["name"]
                    base = m["base"]
                    # size = m["size"]
                    if name == target_mod_name or target_mod_name in name:
                        if lowest_addr is None:
                            lowest_addr = base
                        elif base < lowest_addr:
                            lowest_addr = base

                if self.__agent_buffer_offset is not None and \
                    lowest_addr is not None:

                    self.__agent_buffer_address = lowest_addr + \
                        self.__agent_buffer_offset
                    # Now, our agent is fully up and running
                    self.__status = GuestAgentPlugin.__AGENT_READY
                    # Now, we add the opcode hook and start monitoring the
                    # process
                    self.__cb.add_callback(
                        api.CallbackManager.REMOVEPROC_CB, self.__remove_process_callback,
                        name="host_file_plugin_process_REMOVE")

                    self.__cb.rm_callback("context_change_guest_agent")
        except Exception as e:
            self.__printer("Exception occurred on context change callback: %s" % str(e))