memflow_win32/kernel/
start_block.rs1mod 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#[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 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 let mut low16m = vec![0; size::mb(16)];
39
40 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
50pub 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 let mut low1m = vec![0; size::mb(1)];
57 mem.phys_read_into(PhysicalAddress::NULL, low1m.as_mut_slice())?;
58
59 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}