def windows_update_modules(pgd, update_symbols=False): ''' Use volatility to get the modules and symbols for a given process, and update the cache accordingly ''' import api from utils import get_addr_space from vmi import modules if pgd != 0: addr_space = get_addr_space(pgd) else: addr_space = get_addr_space() if addr_space is None: pp_error("Volatility address space not loaded\n") return # Get EPROC directly from its offset procs = api.get_process_list() inserted_bases = [] # Parse/update kernel modules: if last_kdbg is not None: kdbg = obj.Object( "_KDDEBUGGER_DATA64", offset=last_kdbg, vm=addr_space) for module in kdbg.modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(0, 0, module, update_symbols) for proc in procs: p_pid = proc["pid"] p_pgd = proc["pgd"] # p_name = proc["name"] p_kernel_addr = proc["kaddr"] if p_pgd == pgd: task = obj.Object("_EPROCESS", offset=p_kernel_addr, vm=addr_space) # Note: we do not erase the modules we have information for from the list, # unless we have a different module loaded at the same base address. # In this way, if at some point the module gets unmapped from the PEB list # but it is still in memory, we do not loose the information. if (p_pid, p_pgd) not in modules: modules[(p_pid, p_pgd)] = {} for module in task.get_init_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) for module in task.get_mem_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) for module in task.get_load_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) return
def do_set_target_shellcode(line): '''Set target process - Custom command Set a target process name. When a process with this name is created, the script will start monitoring context changes and retrieve the module entry point as soon as it is available in memory. Then it will place a breakpoint on the entry point. ''' global pyrebox_print global target_procname import api target_procname = line.strip().lower() for p in api.get_process_list(): if target_procname in p["name"].lower(): new_proc(p) return pyrebox_print("Waiting for process %s to start\n" % target_procname)
def find_procs(param): import api nb = None name = None try: nb = int(param, 16) except BaseException: name = param proc_list = api.get_process_list() found = [] for proc in proc_list: pid = proc["pid"] pgd = proc["pgd"] pname = proc["name"] # k_addr = proc["kaddr"] if (nb is not None and (nb == pid or nb == pgd)) or ( name is not None and (fnmatch.fnmatch(pname, name) or name in pname)): found.append((pid, pgd, pname)) return found
def windows_update_modules(pgd, update_symbols=False): ''' Use volatility to get the modules and symbols for a given process, and update the cache accordingly ''' global last_kdbg import api from utils import get_addr_space from vmi import modules from vmi import set_modules_non_present from vmi import clean_non_present_modules if pgd != 0: addr_space = get_addr_space(pgd) else: addr_space = get_addr_space() if addr_space is None: pp_error("Volatility address space not loaded\n") return [] # Get EPROC directly from its offset procs = api.get_process_list() inserted_bases = [] # Parse/update kernel modules if pgd 0 is requested: if pgd == 0 and last_kdbg is not None: if (0, 0) not in modules: modules[(0, 0)] = {} kdbg = obj.Object("_KDDEBUGGER_DATA64", offset=last_kdbg, vm=addr_space) # List entries are returned, so that # we can monitor memory writes to these # entries and detect when a module is added # or removed list_entry_size = None list_entry_regions = [] # Add the initial list pointer as a list entry list_entry_regions.append( (kdbg.obj_offset, kdbg.PsLoadedModuleList.obj_offset, kdbg.PsLoadedModuleList.size())) # Mark all modules as non-present set_modules_non_present(0, 0) for module in kdbg.modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(0, 0, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append( (module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) # Remove all the modules that are not marked as present clean_non_present_modules(0, 0) return list_entry_regions for proc in procs: p_pid = proc["pid"] p_pgd = proc["pgd"] # p_name = proc["name"] p_kernel_addr = proc["kaddr"] if p_pgd == pgd: task = obj.Object("_EPROCESS", offset=p_kernel_addr, vm=addr_space) # List entries are returned, so that # we can monitor memory writes to these # entries and detect when a module is added # or removed list_entry_size = None list_entry_regions = [] if task.Peb is None or not task.Peb.is_valid(): if isinstance(task.Peb.obj_offset, int): list_entry_regions.append( (task.obj_offset, task.Peb.obj_offset, task.Peb.size())) return list_entry_regions if task.Peb.Ldr is None or not task.Peb.Ldr.is_valid(): list_entry_regions.append( (task.Peb.v(), task.Peb.Ldr.obj_offset, task.Peb.Ldr.size())) return list_entry_regions # Add the initial list pointer as a list entry if we already have a PEB and LDR list_entry_regions.append( (task.Peb.Ldr.dereference().obj_offset, task.Peb.Ldr.InLoadOrderModuleList.obj_offset, task.Peb.Ldr.InLoadOrderModuleList.size() * 3)) # Note: we do not erase the modules we have information for from the list, # unless we have a different module loaded at the same base address. # In this way, if at some point the module gets unmapped from the PEB list # but it is still in memory, we do not loose the information. if (p_pid, p_pgd) not in modules: modules[(p_pid, p_pgd)] = {} # Mark all modules as non-present set_modules_non_present(p_pid, p_pgd) for module in task.get_init_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append( (module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) for module in task.get_mem_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append( (module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) for module in task.get_load_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append( (module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) # Remove all the modules that are not marked as present clean_non_present_modules(p_pid, p_pgd) return list_entry_regions return None
def initialize_callbacks(module_hdl, printer): ''' Initilize callbacks for this module. This function will be triggered whenever import_module command is triggered. ''' from mw_monitor_classes import Process from mw_monitor_classes import mwmon import dumper import api from ipython_shell import add_command from plugins.guest_agent import guest_agent # Update printer mwmon.printer = printer # Read configuration mwmon.printer("Reading mw_monitor configuration...") # Config parser for main static configuration file config = ConfigParser.RawConfigParser() config.read('mw_monitor.conf') # Read run configuration from json file f = open("mw_monitor_run.json","r") config_run = json.load(f) f.close() # GENERAL CONFIGURATION if "files_path" not in config_run["general"] or \ "main_executable" not in config_run["general"] or \ "files_bundle" not in config_run["general"]: raise ValueError("File to run not properly specified") mwmon.output_bundle_name = config.get('general', 'output_bundle') mwmon.files_path = config_run['general']['files_path'] mwmon.main_executable = config_run['general']['main_executable'] mwmon.files_bundle = config_run['general']['files_bundle'] mwmon.api_database_path = config.get('general', 'api_database') # Set up process copy and execution mwmon.printer("Copying host file to guest, using agent...") #Extract files in a temporary directory extracted_files_path = tempfile.mkdtemp() mwmon.extracted_files_path = extracted_files_path zip_ref = zipfile.ZipFile(mwmon.files_bundle, 'r') zip_ref.extractall(extracted_files_path) zip_ref.close() onlyfiles = [f for f in os.listdir(extracted_files_path) if os.path.isfile(os.path.join(extracted_files_path, f))] #Copy the files to the guest for f in onlyfiles: guest_agent.copy_file(os.path.join(extracted_files_path,f),os.path.join(mwmon.files_path,f)) ex_path = str(ntpath.join(mwmon.files_path,mwmon.main_executable)) # Instruct file execution guest_agent.execute_file(ex_path) # Stop agent # guest_agent.stop_agent() # MODULE CONFIGURATION mwmon.api_tracer = config_run['modules']['api_tracer'] mwmon.interproc = config_run['modules']['interproc'] mwmon.coverage = config_run['modules']['coverage'] mwmon.dumper = config_run['modules']['dumper'] # API TRACER CONFIGURATION if mwmon.api_tracer and "api_tracer" in config_run: # Static config mwmon.api_tracer_text_log_name = config.get( 'api_tracer', 'text_log_name') mwmon.api_tracer_bin_log_name = config.get( 'api_tracer', 'bin_log_name') # Run config mwmon.api_tracer_light_mode = config_run['api_tracer']['light_mode'] mwmon.api_tracer_text_log = config_run['api_tracer']['text_log'] mwmon.api_tracer_bin_log = config_run['api_tracer']['bin_log'] if "include_apis" in config_run["api_tracer"]: mwmon.include_apis = [] mwmon.include_apis_addrs = [] for api_call in config_run["api_tracer"]["include_apis"]: try: mod, fun = api_call.split("!") mwmon.include_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.include_apis = None if "exclude_apis" in config_run["api_tracer"]: mwmon.exclude_apis = [] mwmon.exclude_apis_addrs = [] for api_call in config_run["api_tracer"]["exclude_apis"]: try: mod, fun = api_call.split("!") mwmon.exclude_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.excludeapis = None if "procs" in config_run["api_tracer"]: mwmon.api_tracer_procs = config_run["api_tracer"]["procs"] else: mwmon.api_tracer_procs = None if "exclude_modules" in config_run["api_tracer"]: mwmon.exclude_modules_addrs = [] mwmon.exclude_modules = [s.lower() for s in config_run["api_tracer"]["exclude_modules"]] else: mwmon.exclude_modules = None if "exclude_origin_modules" in config_run["api_tracer"]: mwmon.exclude_origin_modules_addrs = [] mwmon.exclude_origin_modules = [s.lower() for s in config_run["api_tracer"]["exclude_origin_modules"]] else: mwmon.exclude_origin_modules = None mwmon.exclude_origin_modules_addrs = None # interproc configuration if mwmon.interproc: # Static config mwmon.interproc_bin_log_name = config.get('interproc', 'bin_log_name') mwmon.interproc_text_log_name = config.get( 'interproc', 'text_log_name') mwmon.interproc_basic_stats_name = config.get( 'interproc', 'basic_stats_name') # Run config mwmon.interproc_bin_log = config_run['interproc']['bin_log'] mwmon.interproc_text_log = config_run['interproc']['text_log'] mwmon.interproc_basic_stats = config_run['interproc']['basic_stats'] if mwmon.interproc_text_log: mwmon.interproc_text_log_handle = open( mwmon.interproc_text_log_name, "w") if mwmon.coverage: # Static config mwmon.coverage_log_name = config.get('coverage', 'cov_log_name') mwmon.coverage_text_name = config.get('coverage', 'cov_text_name') # Run config if "procs" in config_run["coverage"]: mwmon.coverage_procs = config_run["coverage"]["procs"] else: mwmon.coverage_procs = None # Static config mwmon.dumper_path = config.get('dumper', 'path') # DUMPER CONFIGURATION if mwmon.dumper: if os.path.isdir(mwmon.dumper_path): shutil.rmtree(mwmon.dumper_path) os.makedirs(mwmon.dumper_path) # Run config mwmon.dumper_onexit = config_run['dumper']['dump_on_exit'] # Possible formats for dump_at: # 0x00400000 # user32.dll!CharNextW # user32.dll!CharNextW!0x00400000 if "dump_at" in config_run["dumper"]: mwmon.dumper_dumpat = config_run['dumper']['dump_at'] mwmon.printer("Initializing callbacks") mwmon.cm = CallbackManager(module_hdl, new_style = True) # Initialize first process proc_name = mwmon.main_executable mwmon.data.procs = [Process(proc_name)] procs = api.get_process_list() match_procs = [] for proc in procs: name = proc["name"] pid = proc["pid"] pgd = proc["pgd"] if proc_name is not None and (proc_name in name or name in proc_name): match_procs.append((pid, pgd, name)) if len(match_procs) == 0: mwmon.printer( "No process matching that process name, deferring process detection") mwmon.printer("Initializing process creation callback") # Monitor creation of new processes, to start tracing the first one. mwmon.cm.add_callback( CallbackManager.CREATEPROC_CB, new_process, name="vmi_new_proc") elif len(match_procs) == 1: mwmon.printer( "Process found with the name specified, monitoring process...") new_process({"pid": match_procs[0][0], "pgd": match_procs[0][1], "name": match_procs[0][2]}) else: mwmon.printer( "Too many procs matching that name, please narrow down!!") if mwmon.dumper: mwmon.printer("Adding dumper commands") # Create and activate new command (dump_mwmon) add_command("dump_mwmon", dumper.dump_command) # Add a callback on process remove, to know when # we dont have any monitored process left. mwmon.cm.add_callback( CallbackManager.REMOVEPROC_CB, remove_process, name="mwmon_vmi_remove_proc") mwmon.printer("Initialized callbacks")
def windows_update_modules(pgd, update_symbols=False): ''' Use volatility to get the modules and symbols for a given process, and update the cache accordingly ''' global last_kdbg global symbol_cache_must_be_saved import api from utils import get_addr_space from vmi import set_modules_non_present from vmi import clean_non_present_modules from vmi import add_module from vmi import get_module from vmi import has_module if pgd != 0: addr_space = get_addr_space(pgd) else: addr_space = get_addr_space() if addr_space is None: pp_error("Volatility address space not loaded\n") return [] # Get EPROC directly from its offset procs = api.get_process_list() inserted_bases = [] # Parse/update kernel modules if pgd 0 is requested: if pgd == 0 and last_kdbg is not None: kdbg = obj.Object( "_KDDEBUGGER_DATA64", offset=last_kdbg, vm=addr_space) # List entries are returned, so that # we can monitor memory writes to these # entries and detect when a module is added # or removed list_entry_size = None list_entry_regions = [] # Add the initial list pointer as a list entry list_entry_regions.append((kdbg.obj_offset, kdbg.PsLoadedModuleList.obj_offset, kdbg.PsLoadedModuleList.size())) # Mark all modules as non-present set_modules_non_present(0, 0) for module in kdbg.modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(0, 0, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append((module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) # Remove all the modules that are not marked as present clean_non_present_modules(0, 0) if symbol_cache_must_be_saved: from vmi import save_symbols_to_cache_file save_symbols_to_cache_file() symbol_cache_must_be_saved = False return list_entry_regions for proc in procs: p_pid = proc["pid"] p_pgd = proc["pgd"] # p_name = proc["name"] p_kernel_addr = proc["kaddr"] if p_pgd == pgd: task = obj.Object("_EPROCESS", offset=p_kernel_addr, vm=addr_space) # List entries are returned, so that # we can monitor memory writes to these # entries and detect when a module is added # or removed list_entry_size = None list_entry_regions = [] scan_peb = True if task.Peb is None or not task.Peb.is_valid(): if isinstance(task.Peb.obj_offset, int): list_entry_regions.append((task.obj_offset, task.Peb.obj_offset, task.Peb.size())) scan_peb = False if task.Peb.Ldr is None or not task.Peb.Ldr.is_valid(): list_entry_regions.append((task.Peb.v(), task.Peb.Ldr.obj_offset, task.Peb.Ldr.size())) scan_peb = False if scan_peb: # Add the initial list pointer as a list entry if we already have a PEB and LDR list_entry_regions.append((task.Peb.Ldr.dereference().obj_offset, task.Peb.Ldr.InLoadOrderModuleList.obj_offset, task.Peb.Ldr.InLoadOrderModuleList.size() * 3)) # Note: we do not erase the modules we have information for from the list, # unless we have a different module loaded at the same base address. # In this way, if at some point the module gets unmapped from the PEB list # but it is still in memory, we do not loose the information. # Mark all modules as non-present set_modules_non_present(p_pid, p_pgd) for module in task.get_init_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append((module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) for module in task.get_mem_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append((module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) for module in task.get_load_modules(): if module.DllBase not in inserted_bases: inserted_bases.append(module.DllBase) windows_insert_module(p_pid, p_pgd, module, update_symbols) if list_entry_size is None: list_entry_size = module.InLoadOrderLinks.size() list_entry_regions.append((module.obj_offset, module.InLoadOrderLinks.obj_offset, list_entry_size * 3)) # Now, if we are a 64bit system and the process is a Wow64 process, traverse VAD # to find the 32 bit modules if api.get_os_bits() == 64 and task.IsWow64: for vad in task.VadRoot.traverse(): if vad is not None: if hasattr(vad, "FileObject"): f = vad.FileObject if f is not None: fname = f.file_name_with_device() if fname and "Windows\\SysWOW64".lower() in fname.lower() and ".dll" == fname[-4:].lower(): fname_starts = fname.find("Windows\\SysWOW64") fname = fname[fname_starts:] windows_insert_module_internal(p_pid, p_pgd, vad.Start, vad.End - vad.Start, fname, fname.split("\\")[-1], "", update_symbols, do_stop = True) # Remove all the modules that are not marked as present clean_non_present_modules(p_pid, p_pgd) if symbol_cache_must_be_saved: from vmi import save_symbols_to_cache_file save_symbols_to_cache_file() symbol_cache_must_be_saved = False return list_entry_regions return None
def initialize_callbacks(module_hdl, printer): ''' Initilize callbacks for this module. This function will be triggered whenever import_module command is triggered. ''' from mw_monitor_classes import Process from mw_monitor_classes import mwmon import dumper import api from ipython_shell import add_command from plugins.guest_agent import guest_agent # Update printer mwmon.printer = printer # Read configuration mwmon.printer("Reading mw_monitor configuration...") # Config parser for main static configuration file config = ConfigParser.RawConfigParser() config.read('mw_monitor.conf') # Read run configuration from json file f = open("mw_monitor_run.json", "r") config_run = json.load(f) f.close() # GENERAL CONFIGURATION if "files_path" not in config_run["general"] or \ "main_executable" not in config_run["general"] or \ "files_bundle" not in config_run["general"]: raise ValueError("File to run not properly specified") mwmon.output_bundle_name = config.get('general', 'output_bundle') mwmon.files_path = config_run['general']['files_path'] mwmon.main_executable = config_run['general']['main_executable'] mwmon.files_bundle = config_run['general']['files_bundle'] mwmon.api_database_path = config.get('general', 'api_database') # Set up process copy and execution mwmon.printer("Copying host file to guest, using agent...") #Extract files in a temporary directory extracted_files_path = tempfile.mkdtemp() mwmon.extracted_files_path = extracted_files_path zip_ref = zipfile.ZipFile(mwmon.files_bundle, 'r') zip_ref.extractall(extracted_files_path) zip_ref.close() onlyfiles = [ f for f in os.listdir(extracted_files_path) if os.path.isfile(os.path.join(extracted_files_path, f)) ] #Copy the files to the guest for f in onlyfiles: guest_agent.copy_file(os.path.join(extracted_files_path, f), os.path.join(mwmon.files_path, f)) ex_path = str(ntpath.join(mwmon.files_path, mwmon.main_executable)) # Instruct file execution guest_agent.execute_file(ex_path) # Stop agent # guest_agent.stop_agent() # MODULE CONFIGURATION mwmon.api_tracer = config_run['modules']['api_tracer'] mwmon.interproc = config_run['modules']['interproc'] mwmon.coverage = config_run['modules']['coverage'] mwmon.dumper = config_run['modules']['dumper'] # API TRACER CONFIGURATION if mwmon.api_tracer and "api_tracer" in config_run: # Static config mwmon.api_tracer_text_log_name = config.get('api_tracer', 'text_log_name') mwmon.api_tracer_bin_log_name = config.get('api_tracer', 'bin_log_name') # Run config mwmon.api_tracer_light_mode = config_run['api_tracer']['light_mode'] mwmon.api_tracer_text_log = config_run['api_tracer']['text_log'] mwmon.api_tracer_bin_log = config_run['api_tracer']['bin_log'] if "include_apis" in config_run["api_tracer"]: mwmon.include_apis = [] mwmon.include_apis_addrs = [] for api_call in config_run["api_tracer"]["include_apis"]: try: mod, fun = api_call.split("!") mwmon.include_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.include_apis = None if "exclude_apis" in config_run["api_tracer"]: mwmon.exclude_apis = [] mwmon.exclude_apis_addrs = [] for api_call in config_run["api_tracer"]["exclude_apis"]: try: mod, fun = api_call.split("!") mwmon.exclude_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.excludeapis = None if "procs" in config_run["api_tracer"]: mwmon.api_tracer_procs = config_run["api_tracer"]["procs"] else: mwmon.api_tracer_procs = None if "exclude_modules" in config_run["api_tracer"]: mwmon.exclude_modules_addrs = [] mwmon.exclude_modules = [ s.lower() for s in config_run["api_tracer"]["exclude_modules"] ] else: mwmon.exclude_modules = None if "exclude_origin_modules" in config_run["api_tracer"]: mwmon.exclude_origin_modules_addrs = [] mwmon.exclude_origin_modules = [ s.lower() for s in config_run["api_tracer"]["exclude_origin_modules"] ] else: mwmon.exclude_origin_modules = None mwmon.exclude_origin_modules_addrs = None # interproc configuration if mwmon.interproc: # Static config mwmon.interproc_bin_log_name = config.get('interproc', 'bin_log_name') mwmon.interproc_text_log_name = config.get('interproc', 'text_log_name') mwmon.interproc_basic_stats_name = config.get('interproc', 'basic_stats_name') # Run config mwmon.interproc_bin_log = config_run['interproc']['bin_log'] mwmon.interproc_text_log = config_run['interproc']['text_log'] mwmon.interproc_basic_stats = config_run['interproc']['basic_stats'] if mwmon.interproc_text_log: mwmon.interproc_text_log_handle = open( mwmon.interproc_text_log_name, "w") if mwmon.coverage: # Static config mwmon.coverage_log_name = config.get('coverage', 'cov_log_name') mwmon.coverage_text_name = config.get('coverage', 'cov_text_name') # Run config if "procs" in config_run["coverage"]: mwmon.coverage_procs = config_run["coverage"]["procs"] else: mwmon.coverage_procs = None # Static config mwmon.dumper_path = config.get('dumper', 'path') # DUMPER CONFIGURATION if mwmon.dumper: if os.path.isdir(mwmon.dumper_path): shutil.rmtree(mwmon.dumper_path) os.makedirs(mwmon.dumper_path) # Run config mwmon.dumper_onexit = config_run['dumper']['dump_on_exit'] # Possible formats for dump_at: # 0x00400000 # user32.dll!CharNextW # user32.dll!CharNextW!0x00400000 if "dump_at" in config_run["dumper"]: mwmon.dumper_dumpat = config_run['dumper']['dump_at'] mwmon.printer("Initializing callbacks") mwmon.cm = CallbackManager(module_hdl, new_style=True) # Initialize first process proc_name = mwmon.main_executable mwmon.data.procs = [Process(proc_name)] procs = api.get_process_list() match_procs = [] for proc in procs: name = proc["name"] pid = proc["pid"] pgd = proc["pgd"] if proc_name is not None and (proc_name in name or name in proc_name): match_procs.append((pid, pgd, name)) if len(match_procs) == 0: mwmon.printer( "No process matching that process name, deferring process detection" ) mwmon.printer("Initializing process creation callback") # Monitor creation of new processes, to start tracing the first one. mwmon.cm.add_callback(CallbackManager.CREATEPROC_CB, new_process, name="vmi_new_proc") elif len(match_procs) == 1: mwmon.printer( "Process found with the name specified, monitoring process...") new_process({ "pid": match_procs[0][0], "pgd": match_procs[0][1], "name": match_procs[0][2] }) else: mwmon.printer( "Too many procs matching that name, please narrow down!!") if mwmon.dumper: mwmon.printer("Adding dumper commands") # Create and activate new command (dump_mwmon) add_command("dump_mwmon", dumper.dump_command) # Add a callback on process remove, to know when # we dont have any monitored process left. mwmon.cm.add_callback(CallbackManager.REMOVEPROC_CB, remove_process, name="mwmon_vmi_remove_proc") mwmon.printer("Initialized callbacks")