memflow_win32/kernel/
sysproc.rs

1use std::prelude::v1::*;
2
3use super::ntos::pehelper;
4use super::StartBlock;
5
6use std::convert::TryInto;
7
8use log::{debug, info, warn};
9
10use memflow::architecture::ArchitectureObj;
11use memflow::error::{Error, ErrorKind, ErrorOrigin, Result};
12use memflow::mem::MemoryView;
13use memflow::types::{size, umem, Address};
14
15use pelite::{self, pe64::exports::Export, PeView};
16
17pub fn find<T: MemoryView>(
18    virt_mem: &mut T,
19    start_block: &StartBlock,
20    ntos: Address,
21) -> Result<Address> {
22    debug!("trying to find system eprocess");
23
24    match find_exported(virt_mem, start_block, ntos) {
25        Ok(e) => return Ok(e),
26        Err(e) => warn!("{}", e),
27    }
28
29    match find_in_section(virt_mem, start_block, ntos) {
30        Ok(e) => return Ok(e),
31        Err(e) => warn!("{}", e),
32    }
33
34    Err(Error(ErrorOrigin::OsLayer, ErrorKind::NotFound).log_info("unable to find system eprocess"))
35}
36
37// find from exported symbol
38pub fn find_exported<T: MemoryView>(
39    virt_mem: &mut T,
40    start_block: &StartBlock,
41    kernel_base: Address,
42) -> Result<Address> {
43    // PsInitialSystemProcess -> PsActiveProcessHead
44    let image = pehelper::try_get_pe_image(virt_mem, kernel_base)?;
45    let pe = PeView::from_bytes(&image)
46        .map_err(|err| Error(ErrorOrigin::OsLayer, ErrorKind::InvalidExeFile).log_info(err))?;
47
48    let sys_proc = match pe
49        .get_export_by_name("PsInitialSystemProcess")
50        .map_err(|err| Error(ErrorOrigin::OsLayer, ErrorKind::ExportNotFound).log_info(err))?
51    {
52        Export::Symbol(s) => kernel_base + *s as umem,
53        Export::Forward(_) => {
54            return Err(Error(ErrorOrigin::OsLayer, ErrorKind::ExportNotFound)
55                .log_info("PsInitialSystemProcess found but it was a forwarded export"))
56        }
57    };
58    info!("PsInitialSystemProcess found at 0x{:x}", sys_proc);
59
60    let arch_obj: ArchitectureObj = start_block.arch.into();
61
62    // read containing value
63    let mut buf = vec![0u8; arch_obj.size_addr()];
64    let sys_proc_addr: Address = match arch_obj.bits() {
65        64 => {
66            virt_mem.read_raw_into(sys_proc, &mut buf)?;
67            u64::from_le_bytes(buf[0..8].try_into().unwrap()).into()
68        }
69        32 => {
70            virt_mem.read_raw_into(sys_proc, &mut buf)?;
71            u32::from_le_bytes(buf[0..4].try_into().unwrap()).into()
72        }
73        _ => return Err(Error(ErrorOrigin::OsLayer, ErrorKind::InvalidArchitecture)),
74    };
75    Ok(sys_proc_addr)
76}
77
78// TODO: scan in pdb
79
80// scan in section
81pub fn find_in_section<T: MemoryView>(
82    virt_mem: &mut T,
83    _start_block: &StartBlock,
84    ntos: Address,
85) -> Result<Address> {
86    // find section ALMOSTRO
87    // scan for va of system process (dtb.va)
88    // ... check if its 32 or 64bit
89
90    let mut header_buf = vec![0; size::mb(32)];
91    virt_mem.read_raw_into(ntos, &mut header_buf)?;
92
93    /*
94    let mut pe_opts = ParseOptions::default();
95    pe_opts.resolve_rva = false;
96
97    let header = PE::parse_with_opts(&header_buf, &pe_opts).unwrap(); // TODO: error
98    let _sect = header
99        .sections
100        .iter()
101        .filter(|s| String::from_utf8(s.name.to_vec()).unwrap_or_default() == "ALMOSTRO")
102        .nth(0)
103        .ok_or_else(|| Error::new("unable to find section ALMOSTRO"))?;
104    */
105
106    Err(Error(ErrorOrigin::OsLayer, ErrorKind::NotImplemented)
107        .log_info("sysproc::find_in_section(): not implemented yet"))
108}