### VmmRegKey Examples Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmRegKey.html Examples demonstrating how to retrieve registry keys using VmmRegKey. ```APIDOC ## Examples ### Retrieve a regkey by full path: ```rust let regkey = vmm.reg_key("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run")?; println!("{regkey"); ``` ### Retrieve a regkey by hive path: ```rust // (SOFTWARE hive example address: 0xffffba061a908000). let regkey = vmm.reg_key("0xffffba061a908000\\ROOT\\Microsoft\\Windows\\CurrentVersion\\Run")?; println!("{regkey"); ``` ### Retrieve parent key: ```rust let regkey_parent = regkey.parent()?; println!("{regkey_parent"); ``` ### Retrieve subkeys (as Vec): ```rust let subkeys = regkey.subkeys()?; for key in subkeys { println!("{{key}}") } ``` ### Retrieve subkeys (as HashMap): ```rust let subkeys = regkey.subkeys_map()?; for e in subkeys { println!("{{}},{{}}", e.0, e.1) } ``` ### Retrieve values (as Vec): ```rust let values = regkey.values()?; for value in values { println!("{{value}}") } ``` ### Retrieve values (as HashMap): ```rust let values = regkey.values_map()?; for e in values { println!("{{}},{{}}", e.0, e.1) } ``` ``` -------------------------------- ### YARA Search Example Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmYara.html Fetches a YARA search struct for the entire process virtual address space. This example demonstrates setting up a YARA rule, configuring search parameters (max hits, no cache), starting the search asynchronously, and retrieving the results. ```rust let yara_rule = " rule mz_header { strings: $mz = \"MZ\" condition: $mz at 0 } "; let yara_rules = vec![yara_rule]; let mut vmmyara = vmmprocess.search_yara(yara_rules, 0, 0, 256, FLAG_NOCACHE); // Start search in async mode. vmmyara.start(); // Search is now running - it's possible to do other actions here. // It's possible to poll() to see current progress (or if finished). // It's possible to abort() to stop search. // It's possible to fetch result() which will block until search is finished. let yara_result = vmmyara.result(); ``` -------------------------------- ### Initialize VmmPlugin Example Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmPluginInitializationInfo.html Example of how to retrieve system information and the plugin initialization context within the InitializeVmmPlugin function. This is crucial for checking system compatibility. ```rust // Retrieve the system_info and plugin_init_ctx in InitializeVmmPlugin() let (system_info, mut plugin_init_ctx) = match new_plugin_initialization::(native_h, native_reginfo) { Ok(r) => r, Err(_) => return, }; ``` -------------------------------- ### Initialize VmmSearch and perform a search Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmSearch.html Acquire a search object, add a search term with specific alignment, start the search asynchronously, and retrieve the results. This example demonstrates searching for 'MZ' with a 0x1000 byte alignment. ```rust let mut vmmsearch = vmmprocess.search(0, 0, 256, FLAG_NOCACHE); let search_term = ['M' as u8, 'Z' as u8]; let _search_term_id = vmmsearch.add_search_ex(&search_term, None, 0x1000); vmmsearch.start(); let search_result = vmmsearch.result(); ``` -------------------------------- ### Example Usage of VmmProcessMapHeapEntry Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapHeapEntry.html This example demonstrates how to retrieve and iterate over heap entries using `vmmprocess.map_heap()`. ```APIDOC ## Examples ```rust if let Ok(heap_all) = vmmprocess.map_heap() { println!("Number of heap entries: {}.", heap_all.len()); for heap in &*heap_all { println!("{heap}"); } } ``` ``` -------------------------------- ### Example: Get Configuration Value Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Prints the maximum native address configuration value. Defaults to 0 if the value cannot be retrieved. ```rust println!("max addr: {:#x}", vmm.get_config(CONFIG_OPT_CORE_MAX_NATIVE_ADDRESS).unwrap_or(0)); ``` -------------------------------- ### PCIe TLP Callback Setup Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.LeechCore.html Starts a PCIe TLP (Transaction Layer Protocol) callback for PCIe devices. A user-provided callback function is executed when a TLP is captured, receiving the TLP data and its string representation. ```rust let _r = lc.pcie_tlp_callback(ctx, fn_tlp_callback)?; ``` -------------------------------- ### Example Usage of vmmprocess.map_thread() Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapThreadEntry.html This example demonstrates how to use the `vmmprocess.map_thread()` function to retrieve a list of all threads for a process and iterate through them, printing basic information. ```APIDOC ## §Examples ```rust if let Ok(thread_all) = vmmprocess.map_thread() { println!("Number of process threads: {}.", thread_all.len()); for thread in &*thread_all { println!("{thread}"); } } ``` ``` -------------------------------- ### vmmprocess.info() Example Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessInfo.html Example usage of the `vmmprocess.info()` function to retrieve the VmmProcessInfo struct for a process. ```APIDOC ## §Created By * `vmmprocess.info()` ## §Examples ```rust // Retrieve the VmmProcess info struct from a process. // It's better to retrieve this struct once and query its fields rather // than calling `vmmprocess.info()` repetedly since there is a small // native overhead doing so. if let Ok(procinfo) = vmmprocess.info() { println!("struct -> {procinfo}"); println!("pid -> {}", procinfo.pid); println!("ppid -> {}", procinfo.pid); println!("peb -> {{:x}}", procinfo.va_peb); println!("eprocess -> {{:x}}", procinfo.va_eprocess); println!("name -> {}", procinfo.name); println!("longname -> {}", procinfo.name_long); println!("SID -> {}", procinfo.sid); } ``` ``` -------------------------------- ### Retrieve Registry Key by Full Path Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmRegKey.html Example of retrieving a registry key using its complete path, starting from the root (e.g., HKLM). ```rust // Retrieve a regkey by full path. let regkey = vmm.reg_key("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run")?; println!("{regkey"); ``` -------------------------------- ### Example Usage of map_module Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapModuleEntry.html This example demonstrates how to retrieve a list of all loaded modules for processes using the `vmmprocess.map_module()` function and iterate through them, printing their details. ```APIDOC ## Example ```rust if let Ok(module_all) = vmmprocess.map_module(true, true) { println!("Number of process modules: {}.", module_all.len()); for module in &*module_all { println!("{module}"); } } ``` ``` -------------------------------- ### Initialize and Configure Plugin Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmPluginInitializationContext.html Example of how to initialize a plugin context, set its name, user-defined context, visibility flags, and callback functions. ```rust // Retrieve the system_info and plugin_init_ctx in InitializeVmmPlugin() let (system_info, mut plugin_init_ctx) = match new_plugin_initialization::(native_h, native_reginfo) { Ok(r) => r, Err(_) => return, }; // set plugin name: plugin_init_ctx.path_name = String::from("/rust/example"); // Set user-defined generic plugin context: let ctx = PluginContext { ... }; plugin_init_ctx.ctx = Some(ctx); // Set visiblity: plugin_init_ctx.is_root_module = true; plugin_init_ctx.is_process_module = true; // Set callback functions: plugin_init_ctx.fn_list = Some(plugin_list_cb); plugin_init_ctx.fn_read = Some(plugin_read_cb); plugin_init_ctx.fn_write = Some(plugin_write_cb); // Register the plugin with the MemProcFS plugin manager: let _r = plugin_init_ctx.register(); ``` -------------------------------- ### Example: Iterate Network Connections Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Iterates through the network connections and prints each entry. ```rust let net_all vmm.map_net()?; for net in &*net_all { println!("{net}"); } ``` -------------------------------- ### Get Process Command Line Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcess.html Retrieves the command line arguments used to launch the process. This is useful for understanding how a process was started. ```rust if let Ok(s_cmdline) = vmmprocess.get_cmdline() { println!("-> {s_cmdline}"); } ``` -------------------------------- ### Map Module Section Example Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessSectionEntry.html Demonstrates how to map a module section by its name and iterate over its entries. Requires the `vmmprocess` module. ```rust if let Ok(section_all) = vmmprocess.map_module_section("kernel32.dll") { println!("Number of module sections: {}.", section_all.len()); for section in &*section_all { println!("{section}"); } } ``` -------------------------------- ### Example Usage of vmmprocess.map_module_eat() Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapEatEntry.html This example demonstrates how to use the `map_module_eat` function to retrieve exported function entries for a given module and iterate through them. ```APIDOC ## §Examples ```rust if let Ok(eat_all) = vmmprocess.map_module_eat("kernel32.dll") { println!("Number of module exported functions: {}.", eat_all.len()); for eat in &*eat_all { println!("{eat} :: {}", eat.forwarded_function); } } ``` ``` -------------------------------- ### Example: Get Kernel Build Number Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Prints the kernel build number using the `kernel()` accessor. ```rust println!("{}", vmm.kernel().build()); ``` -------------------------------- ### Map Module Data Directory Example Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapDirectoryEntry.html Demonstrates how to map module data directories for a given DLL and print the number of entries found. ```rust if let Ok(data_directory_all) = vmmprocess.map_module_data_directory("kernel32.dll") { println!("Number of module data directories: {}.", data_directory_all.len()); for data_directory in &*data_directory_all { println!("{data_directory}"); } } ``` -------------------------------- ### Example: Iterate Kernel Devices Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Iterates through the kernel devices and prints the total number of devices found, followed by each device's details. ```rust if let Ok(kdevices) = vmm.map_kdevice() { println!("Number of devices: {{}}.", kdevices.len()); for kdevice in &*kdevices { println!("{{kdevice}} "); } println!(""); } ``` -------------------------------- ### Example: Iterate Kernel Drivers Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Iterates through the kernel drivers and prints the total number of drivers found, followed by each driver's details. ```rust if let Ok(kdrivers) = vmm.map_kdriver() { println!("Number of drivers: {{}}.", kdrivers.len()); for kdriver in &*kdrivers { println!("{{kdriver}} "); } println!(""); } ``` -------------------------------- ### VmmSearch::start Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmSearch.html Starts a search operation in an asynchronous background thread. ```APIDOC ## pub fn start(&mut self) ### Description Start a search in asynchronous background thread. This is useful since the search may take some time and other work may be done while waiting for the result. The search will start immediately and the progress (and result, if finished) may be polled by calling `poll()`. The result may be retrieved by a call to `poll()` or by a blocking call to `result()` which will return when the search is completed. ``` -------------------------------- ### get_cmdline Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves the command line arguments used to start the process. This can provide insights into how the process was launched and its initial configuration. ```APIDOC ## get_cmdline ### Description Get the process command line. ### Method Signature `pub fn get_cmdline(&self) -> ResultEx` ### Returns A `ResultEx` containing the command line string of the process if successful, or an error. ### Example ```rust if let Ok(s_cmdline) = vmmprocess.get_cmdline() { println!("-> {s_cmdline}"); } ``` ``` -------------------------------- ### Retrieve and Display VmmProcessInfo Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessInfo.html Example of how to retrieve the VmmProcessInfo struct for a process and print its fields. It is recommended to fetch this struct once to avoid repeated overhead. ```rust // Retrieve the VmmProcess info struct from a process. // It's better to retrieve this struct once and query its fields rather // than calling `vmmprocess.info()` repetedly since there is a small // native overhead doing so. if let Ok(procinfo) = vmmprocess.info() { println!("struct -> {procinfo}"); println!("pid -> {}", procinfo.pid); println!("ppid -> {}", procinfo.pid); println!("peb -> {:x}", procinfo.va_peb); println!("eprocess -> {:x}", procinfo.va_eprocess); println!("name -> {}", procinfo.name); println!("longname -> {}", procinfo.name_long); println!("SID -> {}", procinfo.sid); } ``` -------------------------------- ### Example: Force Full Refresh Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Forces MemProcFS to perform a full refresh of processes, memory, and other data structures by setting the `CONFIG_OPT_REFRESH_ALL` option. ```rust let _r = vmm.set_config(CONFIG_OPT_REFRESH_ALL, 1); ``` -------------------------------- ### Retrieve Parent Registry Key Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmRegValue.html Example of how to get the parent registry key of a given VmmRegValue. ```rust let regkey_parent = regvalue.parent()?; println!("{regkey_parent"); ``` -------------------------------- ### Initialize Plugin with System and Context Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html This example demonstrates how to retrieve system information and initialize a plugin context within the `InitializeVmmPlugin` function. It shows error handling and setting basic plugin properties like path name, context, and visibility. ```rust // Retrieve the system_info and plugin_init_ctx in InitializeVmmPlugin() let (system_info, mut plugin_init_ctx) = match new_plugin_initialization::(native_h, native_reginfo) { Ok(r) => r, Err(_) => return, }; // set plugin name: plugin_init_ctx.path_name = String::from("/rust/example"); // Set user-defined generic plugin context: let ctx = PluginContext { ... }; plugin_init_ctx.ctx = Some(ctx); // Set visiblity: plugin_init_ctx.is_root_module = true; plugin_init_ctx.is_process_module = true; ``` -------------------------------- ### Initialize Plugin Initialization Info and Context Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Creates `VmmPluginInitializationInfo` and `VmmPluginInitializationContext` from native C structures. It validates the magic and version of the native registration info before proceeding. ```rust fn impl_new_plugin_initialization(native_h : usize, native_reginfo : usize) -> ResultEx<(VmmPluginInitializationInfo, VmmPluginInitializationContext)> { unsafe { let reginfo = native_reginfo as *mut CVMMDLL_PLUGIN_REGINFO; if (*reginfo).magic != VMMDLL_PLUGIN_REGINFO_MAGIC || (*reginfo).wVersion != VMMDLL_PLUGIN_REGINFO_VERSION { return Err(anyhow!("Bad reginfo magic/version.")); } let info = VmmPluginInitializationInfo { tp_system : VmmSystemType::from((*reginfo).tpSystem), tp_memorymodel : VmmMemoryModelType::from((*reginfo).tpMemoryModel), version_major : (*reginfo).sysinfo_dwVersionMajor, version_minor : (*reginfo).sysinfo_dwVersionMinor, version_build : (*reginfo).sysinfo_dwVersionBuild, }; let ctx = VmmPluginInitializationContext { h_vmm : native_h, h_reginfo : native_reginfo, ctx : None, path_name : String::from(""), is_root_module : false, is_root_module_hidden : false, is_process_module : false, is_process_module_hidden : false, fn_list : None, fn_read : None, fn_write : None, fn_notify : None, fn_visible : None, }; return Ok((info, ctx)); } } ``` -------------------------------- ### Retrieve Kernel PDB Struct Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmPdb.html Get the PDB struct associated with the kernel module (nt). This is a common starting point for symbol lookups. ```rust let kernel = vmm.kernel(); let pdb = kernel.pdb(); ``` -------------------------------- ### VmmPluginInitializationInfo Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Provides information about the system for plugin initialization. ```APIDOC ## VmmPluginInitializationInfo ### Description Plugin Initialization System Information. This struct is used in the plugin module entry point (`InitializeVmmPlugin()`) to provide details about the system, such as system type, memory model, and OS version. ### Fields - **tp_system** (`VmmSystemType`) - The system type (e.g., 32-bit or 64-bit Windows). - **tp_memorymodel** (`VmmMemoryModelType`) - The memory model type (e.g., X86, X86PAE, X64). - **version_major** (`u32`) - The OS major version. - **version_minor** (`u32`) - The OS minor version. - **version_build** (`u32`) - The build version number. ### Examples ``` // Retrieve the system_info and plugin_init_ctx in InitializeVmmPlugin() let (system_info, mut plugin_init_ctx) = match new_plugin_initialization::(native_h, native_reginfo) { Ok(r) => r, Err(_) => return, }; ``` ``` -------------------------------- ### Access Registry Value by Full Path Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Example of retrieving a registry value using its complete path, starting from the root hive (e.g., HKLM). ```rust let regpath = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir"; let regvalue = vmm.reg_key(regpath)?; println!("{regvalue}"); if let Ok(VmmRegValueType::REG_SZ(s)) = regvalue.value() { println!("REG_SZ: {s}"); } ``` -------------------------------- ### Vmm::new Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.Vmm.html Initializes the MemProcFS VMM by specifying the path to the native VMM library and command-line arguments. This is the primary method for setting up the VMM on a target system. ```APIDOC ## pub fn new<'a>(vmm_lib_path: &str, args: &Vec<&str>) -> ResultEx> **MemProcFS Initialization Function.** The `Vmm` struct is the base of the MemProcFS API. All API accesses takes place from the `Vmm` struct and its sub-structs. The `Vmm` struct acts as a wrapper around the native MemProcFS VMM API. ##### §Arguments * `vmm_lib_path` - Full path to the native vmm library - i.e. `vmm.dll`, `vmm.so` or `vmm.dylib` depending on platform. * `args` - MemProcFS command line arguments as a Vec<&str>. MemProcFS command line argument documentation is found on the MemProcFS wiki. ##### §Examples ```rust // Initialize MemProcFS VMM on a Windows system parsing a // memory dump and virtual machines inside it. let args = ["-printf", "-v", "-waitinitialize", "-device", "C:\\Dumps\\mem.dmp"].to_vec(); if let Ok(vmm) = Vmm::new("C:\\MemProcFS\\vmm.dll", &args) { ... // The underlying native vmm is automatically closed // when the vmm object goes out of scope. }; ``` ```rust // Initialize MemProcFS VMM on a Linux system parsing live memory // retrieved from a PCILeech FPGA hardware device. let args = ["-device", "fpga"].to_vec(); if let Ok(vmm) = Vmm::new("/home/user/memprocfs/vmm.so", &args) { ... // The underlying native vmm is automatically closed // when the vmm object goes out of scope. }; ``` ``` -------------------------------- ### Get VmmSearch Result Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmSearch.html Retrieves the result of a VMM search. If the search has not yet started, it will be initiated. This function is blocking and will wait for the search to complete before returning the results. ```rust let search_status_and_result = vmmsearch.result(); ``` -------------------------------- ### Get Module Base Address Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves the base virtual address for a specified loaded module within a process. This is analogous to finding the starting address of a DLL or executable in memory. ```APIDOC ## get_module_base ### Description Get the base virtual address for a loaded module. ### Arguments * `module_name` (string) - The name of the module to find the base address for. ### Returns - `ResultEx`: A result containing the base address of the module if found, or an error. ### Example ```rust if let Ok(module_base_kernel32) = vmmprocess.get_module_base("kernel32.dll") { println!("kernel32.dll -> {:x}", module_base_kernel32); } ``` ``` -------------------------------- ### VmmSearch Start Implementation Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initiates a memory search. Configures the native search context with search terms, PID, and other parameters, then spawns a new thread to execute the VMMDLL_MemSearch function. ```rust fn impl_start(&mut self) { if self.is_started == false { self.is_started = true; // ugly code below - but it works ... self.native_search.cSearch = self.search_terms.len() as u32; self.native_search.pSearch = self.search_terms.as_ptr() as usize; self.native_search.pvUserPtrOpt = std::ptr::addr_of!(self.result) as usize; let pid = self.pid; let native_h = self.vmm.native.h; let pfn = self.vmm.native.VMMDLL_MemSearch; let ptr = &mut self.native_search as *mut CVMMDLL_MEM_SEARCH_CONTEXT; let ptr_wrap = ptr as usize; let thread_handle = std::thread::spawn(move || { let ptr = ptr_wrap as *mut CVMMDLL_MEM_SEARCH_CONTEXT; (pfn)(native_h, pid, ptr, std::ptr::null_mut(), std::ptr::null_mut()) }); self.thread = Some(thread_handle); } } ``` -------------------------------- ### Perform and Retrieve Yara Search Result Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Fetches a Yara search struct for the entire process virtual address space, starts the search asynchronously, and then retrieves the blocking result. This example demonstrates a common workflow for initiating and completing a Yara scan. ```rust let yara_rule = " rule mz_header { strings: $mz = \"MZ\" condition: $mz at 0 } "; let yara_rules = vec![yara_rule]; let mut vmmyara = vmmprocess.search_yara(yara_rules, 0, 0, 256, FLAG_NOCACHE); vmmyara.start(); let yara_result = vmmyara.result(); ``` -------------------------------- ### VmmPluginInitializationContext Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Context for plugin initialization, to be populated by the user. ```APIDOC ## VmmPluginInitializationContext ### Description Plugin Initialization Context. This struct is used in the plugin module entry point (`InitializeVmmPlugin()`) and is to be populated by the user with information such as name, callback functions, and plugin visibility. ### Usage Flow 1. Call `memprocfs::new_plugin_initialization()` to create the context. 2. Fill out `path_name` and other required members. 3. Fill out module type in `is*` members. 4. Fill out optional `pfn*` callback functions. 5. Register the plugin with `VMM` by calling the `register()` method. ### Examples ``` // Retrieve the system_info and plugin_init_ctx in InitializeVmmPlugin() let (system_info, mut plugin_init_ctx) = match new_plugin_initialization::(native_h, native_reginfo) { Ok(r) => r, Err(_) => return, }; // set plugin name: plugin_init_ctx.path_name = String::from("/rust/example"); // Set user-defined generic plugin context: let ctx = PluginContext { ... }; plugin_init_ctx.ctx = Some(ctx); // Set visiblity: plugin_init_ctx.is_root_module = true; plugin_init_ctx.is_process_module = true; ``` ``` -------------------------------- ### VmmSearch Result Implementation Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves the result of a memory search. Starts the search if not already started and ensures completion before returning the results. ```rust fn impl_result(&mut self) -> VmmSearchResult { if self.is_started == false { self.impl_start(); } if self.is_completed == false { self.is_completed = true; if let Some(thread) = self.thread.take() { if let Ok(thread_result) = thread.join() { self.is_completed_success = thread_result; } } } return self.impl_poll(); ``` -------------------------------- ### Vmm::new Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initializes the MemProcFS VMM. This is the primary entry point for interacting with the MemProcFS API, acting as a wrapper around the native MemProcFS VMM API. ```APIDOC ## Vmm::new ### Description Initializes the MemProcFS VMM. This is the primary entry point for interacting with the MemProcFS API, acting as a wrapper around the native MemProcFS VMM API. ### Arguments * `vmm_lib_path` - Full path to the native vmm library - i.e. `vmm.dll`, `vmm.so` or `vmm.dylib` depending on platform. * `args` - MemProcFS command line arguments as a Vec<&str>. ### Examples ```rust // Initialize MemProcFS VMM on a Windows system parsing a // memory dump and virtual machines inside it. let args = vec!["-printf", "-v", "-waitinitialize", "-device", "C:\\Dumps\\mem.dmp"]; if let Ok(vmm) = Vmm::new("C:\\MemProcFS\\vmm.dll", &args) { // ... use vmm object ... // The underlying native vmm is automatically closed // when the vmm object goes out of scope. }; ``` ```rust // Initialize MemProcFS VMM on a Linux system parsing live memory // retrieved from a PCILeech FPGA hardware device. let args = vec!["-device", "fpga"]; if let Ok(vmm) = Vmm::new("/home/user/memprocfs/vmm.so", &args) { // ... use vmm object ... // The underlying native vmm is automatically closed // when the vmm object goes out of scope. }; ``` ``` -------------------------------- ### Initialize LeechCore Library Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initializes the LeechCore library with provided device and remote configurations. Returns a LeechCore struct containing the library handle and function pointers. ```rust let LcRead = *library_lc.get(b"LcRead")?; let LcWrite = *library_lc.get(b"LcWrite")?; let LcGetOption = *library_lc.get(b"LcGetOption")?; let LcSetOption = *library_lc.get(b"LcSetOption")?; let LcCommand = *library_lc.get(b"LcCommand")?; let LcCommandPtr = *library_lc.get(b"LcCommand")?; // build config: let device_config_bytes = &*(device_config.as_bytes() as *const [u8] as *const [c_char]); let mut device_sz: [c_char; 260] = [0; 260]; device_sz[..device_config_bytes.len().min(260-1)].copy_from_slice(device_config_bytes); let remote_config_bytes = &*(remote_config.as_bytes() as *const [u8] as *const [c_char]); let mut remote_sz: [c_char; 260] = [0; 260]; remote_sz[..remote_config_bytes.len().min(260-1)].copy_from_slice(remote_config_bytes); let mut config = CLC_CONFIG { dwVersion : LeechCore::LC_CONFIG_VERSION, dwPrintfVerbosity : lc_config_printf_verbosity, szDevice : device_sz, szRemote : remote_sz, pfn_printf_opt : 0, paMax : pa_max, fVolatile : 0, fWritable : 0, fRemote : 0, fRemoteDisableCompress : 0, szDeviceName : [0; 260], }; // initialize library let h: usize; h = (LcCreate)(&mut config); if h == 0 { return Err(anyhow!("LcCreate: fail")); } // return LeechCore struct: let native = LcNative { h, library_lc, config, LcCreate, LcClose, LcMemFree, LcRead, LcWrite, LcGetOption, LcSetOption, LcCommand, LcCommandPtr, }; let lc = LeechCore { path_lc : str_path_lc.to_string(), native, }; return Ok(lc); } ``` -------------------------------- ### VMM Core Config Get - Internal Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Function pointer for getting configuration options from the VMM core. This is an internal structure used by MemProcFS. ```rust VMMDLL_ConfigGet : extern "C" fn(hVMM : usize, fOption : u64, pqwValue : *mut u64) -> bool, ``` -------------------------------- ### Get Process by PID Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves a VmmProcess object for a given PID. It first gets the process list and then checks if the process exists. Returns an error if the PID is not found. ```rust fn impl_process_from_pid(&self, pid : u32) -> ResultEx { let process_list = self.process_list()?; let process = VmmProcess { vmm : &self, pid : pid, }; if process_list.contains(&process) { return Ok(process); } return Err(anyhow!("VMMDLL_PidGetFromName: fail. PID '{pid}' does not exist.")); } ``` -------------------------------- ### new_plugin_initialization Source: https://docs.rs/memprocfs/5.16.0/memprocfs/fn.new_plugin_initialization.html Initializes plugin information and initialization context. This should usually be the first call in a `InitializeVmmPlugin()` export. ```APIDOC ## new_plugin_initialization ### Description Initialize plugin information and initialization context. This should usually be the first call in a `InitializeVmmPlugin()` export. See the plugin example for additional documentation. ### Signature ```rust pub fn new_plugin_initialization( native_h: usize, native_reginfo: usize, ) -> ResultEx<(VmmPluginInitializationInfo, VmmPluginInitializationContext)> ``` ### Parameters * `native_h` (usize) - Handle to the native VMM. * `native_reginfo` (usize) - Pointer to VMM registration information. ### Returns A `ResultEx` containing a tuple of `VmmPluginInitializationInfo` and `VmmPluginInitializationContext` on success. ``` -------------------------------- ### Get LeechCore Handle Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves the LeechCore handle by getting a configuration option and then creates a new LeechCore instance using the library path and device configuration string. ```rust fn impl_get_leechcore(&self) -> ResultEx { let lc_handle = self.get_config(CONFIG_OPT_CORE_LEECHCORE_HANDLE)?; let lc_lib_path = self.path_lc.as_str(); let device_config_string = format!("existing://0x{:x}", lc_handle); return LeechCore::new(lc_lib_path, device_config_string.as_str(), 0); } ``` -------------------------------- ### VmmProcessMapModuleDebugEntry Struct Definition Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapModuleDebugEntry.html Defines the structure for process module debug entries, containing process ID, age, raw GUID, GUID string, and PDB filename. ```rust pub struct VmmProcessMapModuleDebugEntry { pub pid: u32, pub age: u32, pub raw_guid: [u8; 16], pub guid: String, pub pdb_filename: String, } ``` -------------------------------- ### Initialize MemProcFS and VMM Handle Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initializes MemProcFS, obtaining a VMM handle. It supports using an existing handle or creating a new one with specified arguments. Includes initialization of plugins and error handling. ```rust let VMMDLL_VmGetVmmHandle = *lib.get(b"VMMDLL_VmGetVmmHandle")?; let VMMDLL_VfsList_AddFile = *lib.get(b"VMMDLL_VfsList_AddFile")?; let VMMDLL_VfsList_AddDirectory = *lib.get(b"VMMDLL_VfsList_AddDirectory")?; // initialize MemProcFS let h; if h_vmm_existing_opt != 0 { h = h_vmm_existing_opt; } else { let mut args = args.clone(); let lc_existing_device : String; if let Some(lc_existing) = lc_existing_opt { lc_existing_device = format!("existing://0x{:x}", lc_existing.native.h); args.push("-device"); args.push(lc_existing_device.as_str()); } let args = args.iter().map(|arg| CString::new(*arg).unwrap()).collect::>(); let argv: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect(); let argc: c_int = args.len() as c_int; h = (VMMDLL_Initialize)(argc, argv.as_ptr()); if h == 0 { return Err(anyhow!("VMMDLL_Initialize: fail")); } let r = (VMMDLL_InitializePlugins)(h); if !r { return Err(anyhow!("VMMDLL_InitializePlugins: fail")); } } // return Vmm struct: let native = VmmNative { h, is_close_h : h_vmm_existing_opt == 0, library_lc : Some(lib_lc), library_vmm : Some(lib), VMMDLL_Initialize, VMMDLL_InitializePlugins, VMMDLL_Close, VMMDLL_ConfigGet, VMMDLL_ConfigSet, VMMDLL_MemFree, VMMDLL_Log, VMMDLL_MemSearch, VMMDLL_YaraSearch, VMMDLL_MemReadEx, VMMDLL_MemWrite, VMMDLL_MemVirt2Phys, VMMDLL_Scatter_Initialize, VMMDLL_Scatter_Prepare, VMMDLL_Scatter_PrepareEx, VMMDLL_Scatter_PrepareWrite, VMMDLL_Scatter_Execute, VMMDLL_Scatter_Read, VMMDLL_Scatter_Clear, VMMDLL_Scatter_CloseHandle, VMMDLL_PidGetFromName, VMMDLL_PidList, VMMDLL_WinReg_HiveList, VMMDLL_WinReg_HiveReadEx, VMMDLL_WinReg_HiveWrite, VMMDLL_WinReg_EnumKeyExU, VMMDLL_WinReg_EnumValueU, VMMDLL_WinReg_QueryValueExU, VMMDLL_ProcessGetModuleBaseU, VMMDLL_ProcessGetProcAddressU, VMMDLL_ProcessGetInformation, VMMDLL_ProcessGetInformationString, VMMDLL_Map_GetKDeviceU, VMMDLL_Map_GetKDriverU, VMMDLL_Map_GetKObjectU, VMMDLL_Map_GetNetU, VMMDLL_Map_GetPfnEx, VMMDLL_Map_GetPhysMem, VMMDLL_Map_GetPool, VMMDLL_Map_GetUsersU, VMMDLL_Map_GetServicesU, VMMDLL_Map_GetVMU, VMMDLL_PdbLoad, VMMDLL_PdbSymbolName, VMMDLL_PdbSymbolAddress, VMMDLL_PdbTypeSize, VMMDLL_PdbTypeChildOffset, VMMDLL_Map_GetEATU, VMMDLL_Map_GetHandleU, VMMDLL_Map_GetHeap, VMMDLL_Map_GetHeapAlloc, VMMDLL_Map_GetIATU, VMMDLL_Map_GetModuleU, VMMDLL_Map_GetPteU, VMMDLL_Map_GetThread, VMMDLL_Map_GetThreadCallstackU, VMMDLL_Map_GetUnloadedModuleU, VMMDLL_Map_GetVadU, VMMDLL_Map_GetVadEx, VMMDLL_ProcessGetDirectoriesU, VMMDLL_ProcessGetSectionsU, VMMDLL_VfsListU, VMMDLL_VfsReadU, VMMDLL_VfsWriteU, VMMDLL_VmGetVmmHandle, VMMDLL_VfsList_AddFile, VMMDLL_VfsList_AddDirectory, }; let vmm = Vmm { path_lc : str_path_lc.to_string(), path_vmm : str_path_vmm.to_string(), native, parent_vmm : None, }; return Ok(vmm); } ``` -------------------------------- ### Registering a Plugin Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmPluginInitializationContext.html Demonstrates how to register a plugin with the MemProcFS plugin sub-system using the `register()` method on the `VmmPluginInitializationContext`. ```APIDOC ## impl VmmPluginInitializationContext ### pub fn register(self) -> ResultEx<()> Register the plugin with the MemProcFS plugin sub-system. The initialiation context may not be used after the `register()` call. It is possible to register additional plugins in the same plugin initialization function if a new `VmmPluginInitializationContext` is retrieved from the `new_plugin_initialization()` function. #### Examples ```rust // Register the plugin with MemProcFS. This will consume the context // which should not be possible to use after this. let _r = plugin_init_ctx.register(); ``` ``` -------------------------------- ### Start Asynchronous YARA Search Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmYara.html Starts a YARA search in a background thread, allowing other operations to proceed concurrently. The search progress and results can be monitored using `poll()` or retrieved blocking with `result()`. ```rust vmmyara.start(); ``` -------------------------------- ### Example: Log Critical Message Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Logs a critical message to MemProcFS. ```rust vmm.log(&VmmLogLevel::_1Critical, "Test Message Critical!"); ``` -------------------------------- ### Automatic Memory Population with prepare_ex Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmScatterMemory.html Demonstrates using `prepare_ex` to automatically populate prepared data regions when the VmmScatterMemory object is dropped. This approach is not recommended to be mixed with the `prepare()` syntax. Results are checked by examining the number of bytes read. ```rust // Example: vmmprocess.mem_scatter() #2: // This example demo how it's possible to use the prepare_ex function // which will populate the prepared data regions automatically when the // VmmScatterMemory is dropped. // It's not recommended to mix the #1 and #2 syntaxes. { // memory ranges to read are tuples: // .0 = the virtual address to read. // .1 = vector of u8 which memory should be read into. // .2 = u32 receiving the bytes successfully read data. let mut memory_range_1 = (kernel32.va_base + 0x0000, vec![0u8; 0x100], 0u32); let mut memory_range_2 = (kernel32.va_base + 0x1000, vec![0u8; 0x100], 0u32); let mut memory_range_3 = (kernel32.va_base + 0x2000, vec![0u8; 0x100], 0u32); // Feed the ranges into a mutable VmmScatterMemory inside a // separate scope. The actual memory read will take place when // the VmmScatterMemory goes out of scope and are dropped. println!("========================================"); println!("vmmprocess.mem_scatter() #2:"); if let Ok(mut mem_scatter) = vmmprocess.mem_scatter(FLAG_NOCACHE | FLAG_ZEROPAD_ON_FAIL) { let _r = mem_scatter.prepare_ex(&mut memory_range_1); let _r = mem_scatter.prepare_ex(&mut memory_range_2); let _r = mem_scatter.prepare_ex(&mut memory_range_3); } // Results should now be available in the memory ranges if the read // was successful. Note that there is no guarantee that memory is // read - make sure to check the .2 item - number of bytes read. for memory_range in [memory_range_1, memory_range_2, memory_range_3] { println!("memory range: va={:x} cb={:x} cb_read={:x}", memory_range.0, memory_range.1.len(), memory_range.2); println!("{:?}", memory_range.1.hex_dump()); println!("-----------------------"); } } ``` -------------------------------- ### VmmYara impl_start Method Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initiates the YARA scan by setting up the native configuration and spawning a new thread to execute the scan. ```rust fn impl_start(&mut self) { if self.is_started == false { self.is_started = true; // ugly code below - but it works ... self.native.pvUserPtrOpt2 = std::ptr::addr_of!(self.result) as usize; self.native.pvUserPtrOpt = std::ptr::addr_of!(self.native) as usize; let pid = self.pid; let native_h = self.vmm.native.h; let pfn = self.vmm.native.VMMDLL_YaraSearch; let ptr = &mut self.native as *mut CVMMDLL_YARA_CONFIG; let ptr_wrap = ptr as usize; let thread_handle = std::thread::spawn(move || { let ptr = ptr_wrap as *mut CVMMDLL_YARA_CONFIG; (pfn)(native_h, pid, ptr, std::ptr::null_mut(), std::ptr::null_mut()) }); self.thread = Some(thread_handle); } } ``` -------------------------------- ### VMM Handle Function Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Function to get the VMM handle for a specific VM. ```APIDOC ## VMMDLL_VmGetVmmHandle ### Description Retrieves the VMM handle associated with a given VM handle. ### Parameters - `hVMM` (usize) - Handle to the VMMDLL instance. - `hVM` (usize) - Handle to the VM. ### Returns - `usize` - The VMM handle for the specified VM. ``` -------------------------------- ### LeechCore::new Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Initializes a new LeechCore instance with basic configuration. This function is suitable for standard memory acquisition scenarios. ```APIDOC ## LeechCore::new ### Description Initializes a new LeechCore instance using the provided library path, device configuration, and verbosity level. ### Arguments * `lc_lib_path` - Full path to the native leechcore library (e.g., `leechcore.dll`, `leechcore.dylib`, or `leechcore.so`). * `device_config` - Leechcore device connection string (e.g., `fpga://algo=0`). * `lc_config_printf_verbosity` - Leechcore printf verbosity level, a combination of `LeechCore::LC_CONFIG_PRINTF_*` values. ### Returns A `ResultEx` containing the initialized LeechCore instance or an error. ### Examples ```rust // Initialize a new LeechCore instance using the FPGA memory acquisition method. let lc = LeechCore::new('C:\\Temp\\MemProcFS\\leechcore.dll', 'fpga://algo=0', LeechCore::LC_CONFIG_PRINTF_ENABLED)?; ``` ``` -------------------------------- ### Get Configuration Value Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves a numeric configuration value based on a configuration ID. ```APIDOC ## get_config ### Description Gets a numeric configuration value. The `config_id` should be a `CONFIG_OPT_*` constant. Some options can be OR'ed with a process PID. ### Arguments * `config_id` - (u64) The configuration option identifier. ### Returns A `ResultEx` containing the `u64` configuration value on success, or an error. ### Example ```rust // Get the maximum native address configuration. let max_addr = vmm.get_config(CONFIG_OPT_CORE_MAX_NATIVE_ADDRESS).unwrap_or(0); println!("max addr: {:#x}", max_addr); ``` ``` -------------------------------- ### prepare_as Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmScatterMemory.html Prepares a memory range for reading using method #1, allowing for a generic type to be read into. ```APIDOC ## pub fn prepare_as(&self, va: u64) ### Description Prepare a memory range for reading according to method #1. Once the `mem_scatter.execute()` call has been made it’s possible to read the memory by calling `mem_scatter.read()`. See the `VmmScatterMemory` struct for an example. ### Arguments * `va` - Address to prepare to read from. ``` -------------------------------- ### pcie_bar_callback Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.LeechCore.html Starts a PCIe BAR callback mechanism, allowing custom handling of BAR accesses. ```APIDOC ## pcie_bar_callback ### Description PCIe only function: Start a PCIe BAR callback. ### Arguments * `ctx` - User defined context to be passed to the callback function. * `fn_bar_callback` - The callback function to call when a BAR is accessed. See `LcBarContext` for more information. Only one PCIe BAR callback may be active at a time. ``` -------------------------------- ### Initialize and Register MemProcFS Plugin Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Set callback functions for VFS operations and register the plugin with the MemProcFS plugin manager. The initialization context is consumed upon registration. ```rust /// // Set callback functions: /// plugin_init_ctx.fn_list = Some(plugin_list_cb); /// plugin_init_ctx.fn_read = Some(plugin_read_cb); /// plugin_init_ctx.fn_write = Some(plugin_write_cb); /// // Register the plugin with the MemProcFS plugin manager: /// let _r = plugin_init_ctx.register(); /// ``` -------------------------------- ### Get Process Map Source: https://docs.rs/memprocfs/5.16.0/src/memprocfs/lib_memprocfs.rs.html Retrieves a HashMap of all running processes, keyed by their Process ID (PID). ```rust pub fn process_map(&self) -> ResultEx> { return Ok(self.impl_process_list()?.into_iter().map(|s| (s.pid, s)).collect()); } ``` -------------------------------- ### Get Parent Registry Key Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmRegKey.html Retrieves the parent registry key of the current VmmRegKey instance. ```rust let regkey_parent = regkey.parent()?; println!("{regkey_parent"); ``` -------------------------------- ### Iterate Over Process Modules Source: https://docs.rs/memprocfs/5.16.0/memprocfs/struct.VmmProcessMapModuleEntry.html Example of how to retrieve and iterate over all loaded modules for a process. This snippet demonstrates fetching module information and printing details for each module. ```rust if let Ok(module_all) = vmmprocess.map_module(true, true) { println!("Number of process modules: {}.", module_all.len()); for module in &*module_all { println!("{module}"); } } ```