memflow_win32/kernel/
start_block.rs

1mod aarch64;
2mod x64;
3mod x86;
4mod x86pae;
5
6use std::prelude::v1::*;
7
8use log::warn;
9
10use memflow::architecture::ArchitectureIdent;
11use memflow::error::{Error, ErrorKind, ErrorOrigin, Result};
12use memflow::mem::PhysicalMemory;
13use memflow::types::{size, Address, PhysicalAddress};
14
15// PROCESSOR_START_BLOCK
16#[derive(Debug, Copy, Clone)]
17#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
18pub struct StartBlock {
19    pub arch: ArchitectureIdent,
20    pub kernel_hint: Address,
21    pub dtb: Address,
22}
23
24pub fn find_fallback<T: PhysicalMemory>(
25    mem: &mut T,
26    arch: ArchitectureIdent,
27) -> Result<StartBlock> {
28    match arch {
29        ArchitectureIdent::X86(64, _) => {
30            // read low 16mb stub
31            let mut low16m = vec![0; size::mb(16)];
32            mem.phys_read_into(PhysicalAddress::NULL, low16m.as_mut_slice())?;
33
34            x64::find(&low16m)
35        }
36        ArchitectureIdent::AArch64(_) => {
37            // read low 16mb stub
38            let mut low16m = vec![0; size::mb(16)];
39
40            //TODO: configure this, but so far arm null starts at this address
41            mem.phys_read_into(aarch64::PHYS_BASE.into(), low16m.as_mut_slice())?;
42
43            aarch64::find(&low16m)
44        }
45        _ => Err(Error(ErrorOrigin::OsLayer, ErrorKind::NotImplemented)
46            .log_error("start_block: fallback not implemented for given arch")),
47    }
48}
49
50// bcdedit /set firstmegabytepolicyuseall
51pub fn find<T: PhysicalMemory>(mem: &mut T, arch: Option<ArchitectureIdent>) -> Result<StartBlock> {
52    if let Some(arch) = arch {
53        match arch {
54            ArchitectureIdent::X86(64, _) => {
55                // read low 1mb stub
56                let mut low1m = vec![0; size::mb(1)];
57                mem.phys_read_into(PhysicalAddress::NULL, low1m.as_mut_slice())?;
58
59                // find x64 dtb in low stub < 1M
60                match x64::find_lowstub(&low1m) {
61                    Ok(d) => {
62                        if d.dtb.to_umem() != 0 {
63                            return Ok(d);
64                        }
65                    }
66                    Err(e) => warn!("x64::find_lowstub() error: {}", e),
67                }
68
69                find_fallback(mem, arch)
70            }
71            ArchitectureIdent::X86(32, true) => {
72                let mut low16m = vec![0; size::mb(16)];
73                mem.phys_read_into(PhysicalAddress::NULL, low16m.as_mut_slice())?;
74                x86pae::find(&low16m)
75            }
76            ArchitectureIdent::X86(32, false) => {
77                let mut low16m = vec![0; size::mb(16)];
78                mem.phys_read_into(PhysicalAddress::NULL, low16m.as_mut_slice())?;
79                x86::find(&low16m)
80            }
81            ArchitectureIdent::AArch64(_) => find_fallback(mem, arch),
82            _ => Err(Error(ErrorOrigin::OsLayer, ErrorKind::NotSupported)
83                .log_error("Unsupported architecture")),
84        }
85    } else {
86        find(mem, Some(ArchitectureIdent::X86(64, false)))
87            .or_else(|_| find(mem, Some(ArchitectureIdent::X86(32, true))))
88            .or_else(|_| find(mem, Some(ArchitectureIdent::X86(32, false))))
89            .or_else(|_| find(mem, Some(ArchitectureIdent::AArch64(size::kb(4)))))
90            .map_err(|_| {
91                Error(ErrorOrigin::OsLayer, ErrorKind::NotFound).log_error("unable to find dtb")
92            })
93    }
94}