use memprocfs::{Vmm, VmmProcess, CONFIG_OPT_PROCESS_DTB};
use std::{thread, time};
use std::error::Error;
pub fn init<'a>(vmm_path: &'a str, args: &'a Vec<&'a str>) -> Result<Vmm<'a>, Box<dyn std::error::Error + 'a>> {
let vmm = Vmm::new(vmm_path, args)?;
Ok(vmm)
}
pub fn get_winver(vmm: &Vmm) -> Result<String, Box<dyn Error>> {
Ok(vmm.kernel().build().to_string())
}
pub fn find_process(vmm: &Vmm, process_name: &str) -> Option<u32> {
match vmm.process_from_name(process_name) {
Ok(process) => Some(process.pid),
Err(e) => {
println!("Failed to find {}: {}", process_name, e);
None
}
}
}
pub fn find_base_address(vmm: &Vmm, process_pid: u32, module_name: &str) -> Option<u64> {
if let Ok(process) = vmm.process_from_pid(process_pid) {
match process.get_module_base(module_name) {
Ok(base) => Some(base),
Err(e) => {
println!("Failed to find {} base: {}", module_name, e);
None
}
}
} else {
None
}
}
pub fn fix_cr3(vmm: &Vmm, process: &VmmProcess, target_module: &str, pid: u32) -> Result<bool, Box<dyn Error>> {
let mut possible_dtbs = Vec::new();
loop {
if let Ok(progress_percent) = vmm.vfs_read("\\misc\\procinfo\\progress_percent.txt", 3, 0) {
if progress_percent.len() == 3 {
break;
}
}
thread::sleep(time::Duration::from_millis(500));
}
let dtbs = vmm.vfs_read("\\misc\\procinfo\\dtb.txt", 0x80000, 0)?;
let result = String::from_utf8_lossy(&dtbs);
for line in result.lines() {
let mut split = line.split_whitespace().filter(|s| !s.is_empty());
if let (Some(_), Some("0"), Some(dtb)) = (split.next(), split.next(), split.next()) {
if let Ok(dtb_value) = u64::from_str_radix(dtb, 16) {
possible_dtbs.push(dtb_value);
}
}
}
for dtb in &possible_dtbs {
if vmm.set_config(CONFIG_OPT_PROCESS_DTB | pid as u64, *dtb).is_ok() {
if process.get_module_base(target_module).is_ok() {
return Ok(true);
}
}
}
Ok(false)
}