memflow-win32 0.2.0

win32 integration of the memflow physical memory introspection framework
Documentation
use std::convert::TryInto;
use std::prelude::v1::*;

use log::debug;

use memflow::error::{Error, ErrorKind, ErrorOrigin, PartialResultExt, Result};
use memflow::mem::MemoryView;
use memflow::types::{size, umem, Address};

use pelite::{self, PeView};

pub fn try_get_pe_size<T: MemoryView>(mem: &mut T, probe_addr: Address) -> Result<umem> {
    let mut probe_buf = vec![0; size::kb(4)];
    mem.read_raw_into(probe_addr, &mut probe_buf)?;

    let pe_probe = PeView::from_bytes(&probe_buf)
        .map_err(|err| Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile).log_trace(err))?;

    let opt_header = pe_probe.optional_header();
    let size_of_image = match opt_header {
        pelite::Wrap::T32(opt32) => opt32.SizeOfImage,
        pelite::Wrap::T64(opt64) => opt64.SizeOfImage,
    };
    if size_of_image > 0 {
        debug!(
            "found pe header for image with a size of {} bytes.",
            size_of_image
        );
        Ok(size_of_image as umem)
    } else {
        Err(Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile)
            .log_trace("pe size_of_image is zero"))
    }
}

pub fn try_get_pe_image<T: MemoryView>(mem: &mut T, probe_addr: Address) -> Result<Vec<u8>> {
    let size_of_image = try_get_pe_size(mem, probe_addr)?;
    mem.read_raw(probe_addr, size_of_image.try_into().unwrap())
        .data_part()
}

pub fn try_get_pe_name<T: MemoryView>(mem: &mut T, probe_addr: Address) -> Result<String> {
    let image = try_get_pe_image(mem, probe_addr)?;
    let pe = PeView::from_bytes(&image)
        .map_err(|err| Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile).log_trace(err))?;
    let name = pe
        .exports()
        .map_err(|_| {
            Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile)
                .log_trace("unable to get exports")
        })?
        .dll_name()
        .map_err(|_| {
            Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile)
                .log_trace("unable to get dll name")
        })?
        .to_str()
        .map_err(|_| {
            Error(ErrorOrigin::OsLayer, ErrorKind::Encoding)
                .log_trace("unable to convert dll name string")
        })?;
    debug!("try_get_pe_name: found pe header for {}", name);
    Ok(name.to_string())
}