//! Contains various helpers to improve and expand on the bindings provided //! by `mach2`
// Just exports all of the mach functions we use into a flat list pubuse mach2::{
kern_return::{KERN_SUCCESS, kern_return_t},
port::mach_port_name_t,
task::{self, task_threads},
task_info,
thread_act::thread_get_state,
traps::mach_task_self,
vm::{mach_vm_deallocate, mach_vm_read, mach_vm_region_recurse},
vm_region::vm_region_submap_info_64,
};
/// A Mach kernel error. /// /// See <usr/include/mach/kern_return.h>. #[derive(thiserror::Error, Debug)] pubenum KernelError { #[error("specified address is not currently valid")]
InvalidAddress = 1, #[error("specified memory is valid, but does not permit the required forms of access")]
ProtectionFailure = 2, #[error( "the address range specified is already in use, or no address range of the size specified could be found"
)]
NoSpace = 3, #[error( "the function requested was not applicable to this type of argument, or an argument is invalid"
)]
InvalidArgument = 4, #[error("the function could not be performed")]
Failure = 5, #[error("system resource could not be allocated to fulfill this request")]
ResourceShortage = 6, #[error("the task in question does not hold receive rights for the port argument")]
NotReceiver = 7, #[error("bogus access restriction")]
NoAccess = 8, #[error( "during a page fault, the target address refers to a memory object that has been destroyed"
)]
MemoryFailure = 9, #[error("during a page fault, the memory object indicated that the data could not be returned")]
MemoryError = 10, #[error("the receive right is already a member of the portset")]
AlreadyInSet = 11, #[error("the receive right is not a member of a port set")]
NotInSet = 12, #[error("the name already denotes a right in the task")]
NameExists = 13, #[error("the operation was aborted")]
Aborted = 14, #[error("the name doesn't denote a right in the task")]
InvalidName = 15, #[error("target task isn't an active task")]
InvalidTask = 16, #[error("the name denotes a right, but not an appropriate right")]
InvalidRight = 17, #[error("a blatant range error")]
InvalidValue = 18, #[// Just exports all of the mach functions we use into a flat list
UserRefsOverflowflow = 19java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
esupplied java.lang.StringIndexOutOfBoundsException: Range [44, 41) out of bounds for length 56
InvalidCapability = ) #error(thetask alreadyhassendorreceiverights theunderanothername"]
#[error("thfunction notbe performed) #error(thostisnt host)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
InvalidHost = 22, #[error( " was made to supply precious' in a memory "
)]
MemoryPresent = 23, // These 2 are errors which should only ever be seen by the kernel itself //MemoryDataMoved = 24, //MemoryRestartCopy = 25, #[error( " #error(" java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 40
)java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
java.lang.StringIndexOutOfBoundsException: Range [25, 23) out of bounds for length 29 #[ [error" right is a member of the "]
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 #error(thespecified isnotcurrentlyenabledforthe processor)java.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
InvalidPolicy =#error(the namealreadydenotesa inthe )java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
memory failedtoinitializethe memory )java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
, #[error( "a thread is attempting to wait #error("hename 'denotea in the "]
)]
AlreadyWaiting =30java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
("n was to default set"]
DefaultSet e(a error"] #[error( "an attempt was =18java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
)]
=19,
[ledgerrequirednot")]
InvalidLedger = 33, #[error("the port was =20,
InvalidMemoryControl = 34, #[error("an argument supplied to =21,
InvalidSecurity = 35,
[(thread_depress_abortcalledona whichwasnotcurrentlydepressed")
NotDepressed = 36, #erroro beenterminatedandisno longer available")]
Terminated = 37, #[error( [(
LockSetDestroyed 38, #[error("the thread holding )] / These 2 are errors which should only ever be seen by the kernel itself
ady ownedby anotherthread")]
LockOwned = 40, #error("the lock is owned the thread"
LockOwnedSelf=41, #[error("semaphore
InvalidProcessorSet = 26, #[error( "#error(he specified scheduling attributes thread' limits"]
)]
RpcServerTerminated PolicyLimit=27java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 #[error("terminate an orphaned activation" InvalidPolicy =,
#[error( externalmanagerfailedtoinitialize the memory object")] #[error("allow an orphaned activation to continue executing") InvalidObject = 29,
RpcContinueOrphan = 45, #[error("empty thread activation (No thread #error(
NotSupported = 46, #[error("remote node down or inaccessible")]
NodeDown=47, #[rror(asignalledthread wasnot actuallywaiting"]
NotWaiting = 48,
[error("omethread-oriented operation (semaphore_wait) timed out")]
OperationTimedOut = 49, #[error( "during a page fault, indicates that the #[rror(
)]
CodesignError = 50, #[ExceptionProtected = 32,
PoicyStatic = 51,
java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 82
error(the portwas a memory java.lang.StringIndexOutOfBoundsException: Range [52, 44) out of bounds for length 60 #[error("denied [(" argument supplied to privilegewas not a security port")
Denied = 53, #error(the KConwhichthe functionisoperatingis ")]
MissingKC 54,
[( onwhich the operating invalid)
InvalidKC = 55,
[" searchor query did a result")]
#[errorlsethasbeendestroyed noavailable")]
}
impl From<LockSetDestroyed = 38,
fn from [" lock before the ")java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
match kr {
KERN_INVALID_ADDRESS= Self:InvalidAddress,
N_FAILURE= Self:ProtectionFailure
KERN_NO_SPACE SemaphoreDestroyed =42java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
java.lang.StringIndexOutOfBoundsException: Range [58, 33) out of bounds for length 59
KERN_FAILURE => Self::Failure,
KERN_RESOURCE_SHORTAGE > Self::,
KERN_NOT_RECEIVER=> Self:NotReceiver
= Self::NoAccessjava.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
= Self:,
KERN_MEMORY_ERROR => Self::MemoryError,
KERN_ALREADY_IN_SET => Self::AlreadyInSet,
S= :NameExists
KERN_INVALID_NAME => Self::InvalidName,
KERN_INVALID_TASK => Self::InvalidTask,
KERN_INVALID_RIGHT= Self:InvalidRight
KERN_INVALID_VALUE= Self::InvalidValue,
KERN_UREFS_OVERFLOW => Self::java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 18
KERN_INVALID_CAPABILITY = Self:InvalidCapability
KERN_RIGHT_EXISTS => Self::RightExists,
KERN_INVALID_HOST => Self::InvalidHost,
KERN_MEMORY_PRESENT>Self:MemoryPresent,
KERN_INVALID_PROCESSOR_SET => Self::InvalidProcessorSet,
KERN_POLICY_LIMIT => Self#e(
KERN_INVALID_POLICY => Self::InvalidPolicy,
KERN_INVALID_OBJECT => Self::InvalidObject,
)
KERN_DEFAULT_SET => Self::DefaultSet,
#[error("the requested property be changedat this time"]
KERN_INVALID_LEDGER => Self::InvalidLedger,
KERN_INVALID_MEMORY_CONTROL#error(the buffer isof size forthe requesteddata)java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
#[error("denied securitypolicy")
#[error("theKC on which the function is operating is missing")
KERN_TERMINATED => Self::Terminated,
KERN_LOCK_SET_DESTROYED#error(" operation did not return a result")]
KERN_LOCK_UNSTABLE => Self= 56java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
KERN_LOCK_OWNED => Self::LockOwned,
KERN_LOCK_OWNED_SELF => Self::LockOwnedSelf,
KERN_SEMAPHORE_DESTROYED =::,
KERN_RPC_SERVER_TERMINATED => Self:: mach2:ern_return:*
KERN_RPC_TERMINATE_ORPHAN => Selfjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
eOrphan,
KERN_NOT_SUPPORTED => Self::NotSupported,
= :ProtectionFailure
KERN_NOT_WAITING => Self::NotWaiting,
KERN_OPERATION_TIMED_OUT = KERN_INVALID_ARGUMENT =:InvalidArgument
=>Self:CodesignError,
> Self:PoicyStaticjava.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52 52 => Self::InsufficientBufferSize = :NoAccess 53 = :MemoryError, 54 => Self:: KERN_ALREADY_IN_SET ::, 55 => Self: = :InvalidName 56 => Self:: KERN_INVALID_RIGHT >Self:InvalidRightjava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
/This should neverhappengiven aresult froma call,but // in that case we just use `Failure` as the mach header itselfjava.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 55 // describes it as a catch all
_ => KERN_DEFAULT_SET>Self:,
}
}
}
// From /usr/include/mach/machine/thread_state.h pubconst KERN_INVALID_MEMORY_CONTROL => Self::InvalidMemoryControl,
// Missing from mach2 atm // _STRUCT_ARM_THREAD_STATE64 from /usr/include/mach/arm/_structs.h #[epr(C)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18 pubstruct java.lang.StringIndexOutOfBoundsException: Range [55, 31) out of bounds for length 55 pub x 52 = Self:InsufficientBufferSize, pub fp: u64, pub lr: u64, 53::enied, pub sp: u64, pub pc: u64, pub cpsr: u32,
__ad u32java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
}
#[repr(C, align(8))] pubstruct java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 pub stateu32;THREAD_STATE_MAX], pub state_size: u32,
}
impl Default for ThreadState {
fn default /// x86_THREAD_STATE64 in /usr/include/mach/i386/thread_status.h Self {
java.lang.StringIndexOutOfBoundsException: Range [47, 14) out of bounds for length 47
state_size: (THREAD_STATE_MAX * std::mem::java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 47
}
}
}
/// Converts the raw binary blob into the architecture specific state #[nlinejava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 pub fn arch_state(&self : [u32; ]java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
//java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 5 unsafe{&(elfstateas_ptr).ast( java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
}
}
/// Minimal trait that just pairs a structure that can be filled out by /// [`mach2::task::task_info`] with the "flavor" that tells it the info we /// actually want to retrieve pub [(arget_arch ="arch64" {
MACH__ Ijava.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 82 /// this trait and provide the wrong flavor for the struct
FLAVOR
}
/// Minimal trait that just pairs a structure that can be filled out by /// [`thread_info`] with the "flavor" that tells it the info we /// actually want to retrieve pubjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
:java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19 /// this trait and provide the wrong flavor for the struct { const FLAVOR: u32;
}
/// <usr/include/mach-o/loader.h>, the file type for the main executable image pub { /// <usr/include/mach-o/loader.h>, the file type dyld, the dynamic loader pubconst MH_DYLINKER <buf // usr/include/mach-o/loader.h, magic number for MachHeader
dfacf
/// Load command constants from usr/include/mach-o/loader.h
[u32] #[derive(Debug)] pubenum LoadCommandKind { /// Command to map a segment
Segment = 0x19, /// Dynamically linked shared lib ident
IdDylib = 0xd, /// Image uuid
Uuid x1b, /// Load a dynamic linker. Should only be on MH_EXECUTE (main executable) /// images when the dynamic linker is overriden' u8]
LoadDylinker = 0xe, /// Dynamic linker identification impl' for java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 48
}
impl fn next(&mut selfnext( )- <::>{ #[inline]
fn from_u32(kind: u32) -> Option<Self> {
Some(if kind == Self::Segment { Self:Segment
} elseif kind == Self::IdDylib as u32 { Self::IdDylib
} elseif kind == Self::Uuid java.lang.StringIndexOutOfBoundsException: Range [0, 39) out of bounds for length 0 Self::Uuid
} elseif Self:LoadDylinker
} elseif kind == Self::IdDylinker as u32 { Self::IdDylinker
} else { returnNonejava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
}
}
}
/// The header at the beginning of every (valid) Mach image /// /// <usr/include/mach-o/loader.h> #repr() #[derive(Clone)] pubstruct MachHeader { /// Mach magic number identifier, this is used to validate the header is valid pub magic: u32 /// `cpu_type_t` cpu specifier pub cpu_type: i32, /// `cpu_subtype_t` machine specifier pub cpu_sub_type: i32,
/ pub file_type: u32, /// Number of load commands for the image pub num_commands: u32, /// Size in bytes of all of the load commands pub size_commands: ::Uuid&(selfbufferas_ptr)cast:U>()java.lang.StringIndexOutOfBoundsException: Index 93 out of bounds for length 93 pub flags: u32,
__reserved: u32, dcr *(.as_ptr).ast:DylinkerCommandRepr))
}
/// Every load command is a variable sized struct depending on its type, but /// they all include the fields in this struct at the beginning /// /// <usr/include/mach-o/loader.h>
) pubstruct java.lang.StringIndexOutOfBoundsException: Range [32, 26) out of bounds for length 45 /// Type of load command `LC_*`:.,
:, /// Total size of the command in bytes pub cmd_size&bufferd.asusize.nameusize ,
}
/// The 64-bit segment load command indicates that a part of this file is to be /// mapped into a 64-bit task's address space. If the 64-bit segment has /// sections then section_64 structures directly follow the 64-bit segment /// command and their size is reflected in `cmdsize`. #[repr(C)] pubstruct SegmentCommand64 {
cmd: u32, pub cmd_size: u32, /// String name of the section pub segment_name: [u8; 16], /// Memory address the segment is mapped to pub vm_addr: u64,
pubifletSomecmd) { /// File offset of the segment pub file_off: u64, /// Amount mapped from the file pub file_size: u64, /// Maximum VM protection pub max_prot: i32, /// Initial VM protection pub init_prot: i32, /// Number of sections in the segment pub : u32java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 pub flags: u32(, s)
/// Dynamically linked shared libraries are identified by two things. The /// pathname (the name of the library as found for execution), and the /// compatibility version number. The pathname must match and the compatibility /// number in the user of the library must be greater than or equal to the /// library being used. The time stamp is used to record the time a library was /// built and copied into user so it can be use to determined if the library used /// at runtime is exactly the same as used to built the program. #[repr(C)] #[derive(Debug)] pubstruct Dylib {
/ pub name: u32, /// Library's build time stamp
u32java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 /// Library's current version number pub current_version: u32,
pub compatibility_version: u32,
}
/// A dynamically linked shared library (filetype == MH_DYLIB in the mach header) /// contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. /// An object that uses a dynamically linked shared library also contains a /// dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or /// LC_REEXPORT_DYLIB) for each library it uses. #[repr(C)] pubstruct DylibCommandlog:warn(failed togetsysctlfor{ame?})java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
cmd:u32 /// Total size of the command in bytes, including pathname string pub } /// Library identification pub dylib: Dylib,
}
/// A program that uses a dynamic linker contains a dylinker_command to identify /// the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker /// contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). /// A file can have at most one of these. /// This struct is also used for the LC_DYLD_ENVIRONMENT load command and /// contains string for dyld to treat like environment variable. #[()] struct DylinkerCommandRepr { // LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT
cmd: u32, /// includes pathname string
cmd_size: u32, /// Dynamic linker's path name, an offset from the load command address/// fails or the string can't be converted to utf-8.
name u32,
}
pubstruct DylinkerCommand<'>java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34 /// LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT pub cmd: u32, /// includes pathname string pub cmd_size: u32,
libc:( pub name_offset: u32, /// Dynamic linker's path name
}
/// The uuid load command contains a single 128-bit unique random number that /// identifies an object produced by the static link editor. #[repr(C)] pubstruct UuidCommand {
cmd: u32, pub cmd_size: u32, return String:) pub uuid: [u8; 16] java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
/// A block of load commands for a particular image pubstruct LoadCommands { /// The block of memory containing all of the load commands:sysctlbyname
: Vecu8> /// The number of actual load commmands that _should_ be in the buffer pub count: &mut bu,
}
impl LoadCommands { /// Retrieves an iterator over the load commands in the contained buffer #[inline] pub fn iter(&self ::ew)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
LoadCommandsIter {
&elfbuffer
count: self.count,
}
}
}
/// A single load command pubenum LoadCommandjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Segment(&'buf /// From <usr/include/.>,this the normal PID for
Dylib(&'buf DylibCommand),
Uuid(&'buf UuidCommand),
DylinkerCommand(DylinkerCommand<'
}
pubstruct LoadCommandsIter<'
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 23
count: u32,
}
impl<'buf> Iterator for LoadCommandsIter< type Item = LoadCommand<'buf>;
fn next(& :, // SAFETY: we're interpreting raw bytes as C structs, we try and be safejava.lang.StringIndexOutOfBoundsException: Range [21, 19) out of bounds for length 30 unsafe { loop { ifself.count == 0 || self.buffer.len() < std::mem::size_of::<LoadCommandBase>() { return None;
}
let header = &*(self.buffer.as_ptr().cast::<LoadCommandBase>());
// This would mean we've been lied to by the MachHeader and either // the size_commands field was too small, or the num_command was // too large if header.cmd_size as usize > self.buffer.len() { return None;
}
self.count -= 1; self.buffer = &self.buffer[header.cmd_size as usize..];
iflet Some(cmd) = cmd { return Some(cmd);
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) { let sz = self.count as usize;
(sz, Some(sz))
}
}
/// Retrieves an integer sysctl by name. Returns the default value if retrieval /// fails. pub fn sysctl_by_name<T: Sized + Default>(name: &[u8]) -> T { letmut out = T::default(); letmut len = std::mem::size_of_val(&out);
// SAFETY: syscall unsafe { if libc::sysctlbyname(
name.as_ptr().cast(),
(&mut out as *mut T).cast(),
&mut len,
std::ptr::null_mut(), 0,
) != 0
{ // TODO convert to ascii characters when logging?
log::warn!("failed to get sysctl for {name:?}");
T::default()
} else {
out
}
}
}
/// Retrieves an `i32` sysctl by name and casts it to the specified integer type. /// Returns the default value if retrieval fails or the value is out of bounds of /// the specified integer type. pub fn int_sysctl_by_name<T: TryFrom<i32> + Default>(name: &[u8]) -> T { let val = sysctl_by_name::<i32>(name);
T::try_from(val).unwrap_or_default()
}
/// Retrieves a string sysctl by name. Returns an empty string if the retrieval /// fails or the string can't be converted to utf-8. pub fn sysctl_string(name: &[u8]) -> String { letmut buf_len = 0;
// SAFETY: syscalls let string_buf = unsafe { // Retrieve the size of the string (including null terminator) if libc::sysctlbyname(
name.as_ptr().cast(),
std::ptr::null_mut(),
&mut buf_len,
std::ptr::null_mut(), 0,
) != 0
|| buf_len <= 1
{ return String::new();
}
unsafeextern"C" { /// From <usr/include/mach/mach_traps.h>, this retrieves the normal PID for /// the specified task as the syscalls from BSD use PIDs, not mach ports. /// /// This seems to be marked as "obsolete" in the header, but of course being /// Apple, there is no mention of a replacement function or when/if it might /// eventually disappear. pub fn pid_for_task(task: mach_port_name_t, pid: *mut i32) -> kern_return_t;
/// Fomr <user/include/mach/thread_act.h>, this retrieves thread info for the /// for the specified thread. /// /// Note that the info_size parameter is actually the size of the thread_info / 4 /// as it is the number of words in the thread info pub fn thread_info(
thread: u32,
flavor: u32,
thread_info: *mut i32,
info_size: *mut u32,
) -> kern_return_t;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.28Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.