mod direct;
mod enumerator;
mod indirect;
mod table;
mod wrappers;
pub use direct::DirectSyscall;
pub use enumerator::{enumerate_syscalls, EnumeratedSyscall, SyscallEnumerator};
pub use indirect::IndirectSyscall;
pub use table::{hashes, SyscallEntry, SyscallTable};
pub use wrappers::*;
use crate::error::Result;
#[cfg(feature = "std")]
use std::sync::OnceLock;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::format;
#[cfg(feature = "std")]
static SYSCALL_TABLE: OnceLock<Result<SyscallTable>> = OnceLock::new();
#[cfg(feature = "std")]
pub fn get_syscall_table() -> Result<&'static SyscallTable> {
let result = SYSCALL_TABLE.get_or_init(SyscallTable::enumerate);
match result {
Ok(table) => Ok(table),
Err(e) => Err(crate::error::WraithError::SyscallEnumerationFailed {
reason: format!("{}", e),
}),
}
}
#[cfg(not(feature = "std"))]
pub fn enumerate_syscall_table() -> Result<SyscallTable> {
SyscallTable::enumerate()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SyscallMode {
Direct,
Indirect,
Native,
}
impl Default for SyscallMode {
fn default() -> Self {
Self::Direct
}
}
static PREFERRED_MODE: core::sync::atomic::AtomicU8 = core::sync::atomic::AtomicU8::new(0);
pub fn set_syscall_mode(mode: SyscallMode) {
let value = match mode {
SyscallMode::Direct => 0,
SyscallMode::Indirect => 1,
SyscallMode::Native => 2,
};
PREFERRED_MODE.store(value, core::sync::atomic::Ordering::Relaxed);
}
pub fn get_syscall_mode() -> SyscallMode {
match PREFERRED_MODE.load(core::sync::atomic::Ordering::Relaxed) {
0 => SyscallMode::Direct,
1 => SyscallMode::Indirect,
_ => SyscallMode::Native,
}
}
#[inline]
pub const fn nt_success(status: i32) -> bool {
status >= 0
}
pub mod status {
pub const STATUS_SUCCESS: i32 = 0;
pub const STATUS_INVALID_HANDLE: i32 = 0xC0000008_u32 as i32;
pub const STATUS_ACCESS_DENIED: i32 = 0xC0000022_u32 as i32;
pub const STATUS_BUFFER_TOO_SMALL: i32 = 0xC0000023_u32 as i32;
pub const STATUS_INFO_LENGTH_MISMATCH: i32 = 0xC0000004_u32 as i32;
}