wraith/km_client/
mod.rs

1//! Usermode client for kernel driver communication
2//!
3//! This module provides a usermode API for communicating with kernel drivers
4//! built using the `km` module. It supports:
5//!
6//! - IOCTL-based communication
7//! - Shared memory access
8//! - Process memory operations via driver
9//!
10//! # Example
11//!
12//! ```no_run
13//! use wraith::km_client::{DriverClient, ProcessOps};
14//!
15//! let client = DriverClient::connect("\\\\.\\MyDriver")?;
16//! let mut process = client.open_process(1234)?;
17//! let value: u32 = process.read(0x7FFE0000)?;
18//! ```
19
20mod driver;
21mod process;
22mod memory;
23pub mod ioctl;
24
25pub use driver::{DriverClient, DriverHandle};
26pub use process::ProcessOps;
27pub use memory::{RemoteMemory, MemoryProtection};
28pub use ioctl::{IoctlCode, IoctlRequest, IoctlResponse};
29
30use std::io;
31
32/// result type for client operations
33pub type ClientResult<T> = Result<T, ClientError>;
34
35/// client error types
36#[derive(Debug)]
37pub enum ClientError {
38    /// failed to open driver
39    DriverOpenFailed(io::Error),
40    /// driver not found
41    DriverNotFound,
42    /// IOCTL operation failed
43    IoctlFailed {
44        code: u32,
45        error: io::Error,
46    },
47    /// invalid response from driver
48    InvalidResponse {
49        expected: usize,
50        received: usize,
51    },
52    /// process operation failed
53    ProcessError {
54        pid: u32,
55        reason: String,
56    },
57    /// memory operation failed
58    MemoryError {
59        address: u64,
60        reason: String,
61    },
62    /// buffer too small
63    BufferTooSmall {
64        required: usize,
65        provided: usize,
66    },
67    /// operation not supported
68    NotSupported,
69}
70
71impl std::fmt::Display for ClientError {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            Self::DriverOpenFailed(e) => write!(f, "failed to open driver: {e}"),
75            Self::DriverNotFound => write!(f, "driver not found"),
76            Self::IoctlFailed { code, error } => write!(f, "IOCTL {code:#x} failed: {error}"),
77            Self::InvalidResponse { expected, received } => {
78                write!(f, "invalid response: expected {expected} bytes, got {received}")
79            }
80            Self::ProcessError { pid, reason } => {
81                write!(f, "process {pid} error: {reason}")
82            }
83            Self::MemoryError { address, reason } => {
84                write!(f, "memory error at {address:#x}: {reason}")
85            }
86            Self::BufferTooSmall { required, provided } => {
87                write!(f, "buffer too small: need {required}, got {provided}")
88            }
89            Self::NotSupported => write!(f, "operation not supported"),
90        }
91    }
92}
93
94impl std::error::Error for ClientError {}
95
96impl From<io::Error> for ClientError {
97    fn from(e: io::Error) -> Self {
98        Self::DriverOpenFailed(e)
99    }
100}