use std::prelude::v1::*;
use super::pehelper;
use crate::kernel::StartBlock;
use memflow::dataview::PodMethods;
use memflow::error::{Error, ErrorKind, ErrorOrigin, PartialResultExt, Result};
use memflow::mem::MemoryView;
use memflow::types::{size, umem, Address};
use log::{debug, info};
use pelite::image::IMAGE_DOS_HEADER;
const SIZE_256MB: usize = size::mb(256);
const SIZE_8MB: usize = size::mb(8);
const SIZE_4KB: usize = size::kb(4);
pub fn find<T: MemoryView>(virt_mem: &mut T, _start_block: &StartBlock) -> Result<(Address, umem)> {
debug!("x86::find: trying to find ntoskrnl.exe");
for base_addr in (0..SIZE_256MB).step_by(SIZE_8MB) {
let base_addr = size::gb(2) + base_addr;
let mut buf = vec![0; SIZE_8MB];
virt_mem
.read_raw_into(base_addr.into(), &mut buf)
.data_part()?;
for addr in (0..SIZE_8MB).step_by(SIZE_4KB) {
let view = PodMethods::as_data_view(&buf[addr..]);
if view.read::<IMAGE_DOS_HEADER>(0).e_magic != 0x5a4d {
continue;
}
if view.read::<IMAGE_DOS_HEADER>(0).e_lfanew > 0x800 {
continue;
}
let image_base = Address::from(base_addr + addr);
if let Ok(name) = pehelper::try_get_pe_name(virt_mem, image_base) {
if name == "ntoskrnl.exe" {
info!("ntoskrnl found");
if let Ok(size_of_image) = pehelper::try_get_pe_size(virt_mem, image_base) {
return Ok((image_base, size_of_image));
}
}
}
}
}
Err(Error(ErrorOrigin::OsLayer, ErrorKind::ProcessNotFound)
.log_trace("find_x86(): unable to locate ntoskrnl.exe in high mem"))
}