vmi::os::windows

Trait WindowsOsSessionExt

Source
pub trait WindowsOsSessionExt<Driver>
where Driver: VmiDriver, <Driver as VmiDriver>::Architecture: Architecture + ArchAdapter<Driver>,
{
Show 45 methods // Required methods fn offsets(&self) -> &Offsets; fn symbols(&self) -> &Symbols; fn file_object_to_filename( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, file_object: Va, ) -> Result<String, VmiError>; fn file_object_to_full_path( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, file_object: Va, ) -> Result<String, VmiError>; fn control_area_to_filename( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, control_area: Va, ) -> Result<String, VmiError>; fn is_kernel_handle( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, handle: u64, ) -> Result<bool, VmiError>; fn handle_table( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<WindowsHandleTable, VmiError>; fn handle_table_entry( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<WindowsHandleTableEntry>, VmiError>; fn handle_table_entry_lookup( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, handle_table: &WindowsHandleTable, handle: u64, ) -> Result<Va, VmiError>; fn handle_to_object_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<Va>, VmiError>; fn handle_to_object( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<WindowsObject>, VmiError>; fn object_from_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObject>, VmiError>; fn kernel_information_string_ex( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Option<String>, VmiError>; fn vad( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad: Va, ) -> Result<WindowsVad, VmiError>; fn vad_root( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<Va, VmiError>; fn vad_hint( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<Va, VmiError>; fn vad_to_region( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad: Va, ) -> Result<OsRegion, VmiError>; fn vad_root_to_regions( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad_root: Va, ) -> Result<Vec<OsRegion>, VmiError>; fn find_process_vad( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, address: Va, ) -> Result<Option<Va>, VmiError>; fn lock_pfn( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, pfn: Gfn, ) -> Result<Option<u16>, VmiError>; fn unlock_pfn( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, pfn: Gfn, ) -> Result<Option<u16>, VmiError>; fn current_kpcr( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Va; fn exception_record( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, address: Va, ) -> Result<WindowsExceptionRecord, VmiError>; fn last_status( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Option<u32>, VmiError>; fn object_header_cookie( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Option<u8>, VmiError>; fn object_type( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObjectType>, VmiError>; fn object_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObjectName>, VmiError>; fn object_attributes_to_object_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, object_attributes: Va, ) -> Result<Option<String>, VmiError>; fn process_peb( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<WindowsPeb, VmiError>; fn process_current_directory( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>; fn process_dll_path( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>; fn process_image_path_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>; fn process_command_line( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>; fn process_from_thread( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, thread: ThreadObject, ) -> Result<ProcessObject, VmiError>; fn process_from_thread_apc_state( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, thread: ThreadObject, ) -> Result<ProcessObject, VmiError>; fn process_object_to_process( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<OsProcess, VmiError>; fn read_ansi_string( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn read_ansi_string32( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn read_ansi_string64( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn read_unicode_string( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn read_unicode_string32( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn read_unicode_string64( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>; fn lowest_user_address( &self, _registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Va, VmiError>; fn highest_user_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Va, VmiError>; fn is_valid_user_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, address: Va, ) -> Result<bool, VmiError>;
}
Available on crate feature os-windows only.
Expand description

WindowsOs extensions for the VmiSession.

Required Methods§

Source

fn offsets(&self) -> &Offsets

Returns a reference to the Windows-specific memory offsets.

Source

fn symbols(&self) -> &Symbols

Returns a reference to the Windows-specific symbols.

Source

fn file_object_to_filename( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, file_object: Va, ) -> Result<String, VmiError>

Extracts the FileName from a FILE_OBJECT structure.

§Equivalent C pseudo-code
UNICODE_STRING FileName = FileObject->FileName;
return FileName;
§Notes

This operation might fail as the filename is allocated from paged pool.

Source

fn file_object_to_full_path( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, file_object: Va, ) -> Result<String, VmiError>

Constructs the full path of a file from its FILE_OBJECT.

This function first reads the DeviceObject field of the FILE_OBJECT structure. Then it reads the ObjectNameInfo of the DeviceObject and its directory. Finally, it concatenates the device directory name, device name, and file name.

§Equivalent C pseudo-code
PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;

POBJECT_HEADER_NAME_INFO DeviceNameInfo = ObjectNameInfo(DeviceObject);
POBJECT_HEADER_NAME_INFO DeviceDirectoryNameInfo = DeviceNameInfo->Directory
    ? ObjectNameInfo(DeviceNameInfo->Directory)
    : NULL;

if (DeviceDirectoryNameInfo->Name != NULL) {
    FullPath += '\\' + DeviceDirectoryNameInfo->Name;
}

if (DeviceNameInfo->Name != NULL) {
    FullPath += '\\' + DeviceNameInfo->Name;
}

FullPath += FileObject->FileName;

return FullPath;
§Panics

Panics if the provided object is not a file object.

Source

fn control_area_to_filename( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, control_area: Va, ) -> Result<String, VmiError>

Extracts the filename from a CONTROL_AREA structure.

This function first reads the FilePointer field of the CONTROL_AREA structure, then reads the FileName field of the FILE_OBJECT structure pointed by the FilePointer.

§Equivalent C pseudo-code
PFILE_OBJECT FileObject = ControlArea->FilePointer;
UNICODE_STRING FileName = FileObject->FileName;
return FileName;
Source

fn is_kernel_handle( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, handle: u64, ) -> Result<bool, VmiError>

Checks if the given handle is a kernel handle.

Source

fn handle_table( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<WindowsHandleTable, VmiError>

Retrieves the handle table for a given process.

Source

fn handle_table_entry( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<WindowsHandleTableEntry>, VmiError>

Looks up a specific handle table entry for a given process and handle.

Source

fn handle_table_entry_lookup( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, handle_table: &WindowsHandleTable, handle: u64, ) -> Result<Va, VmiError>

Performs a lookup in the handle table to find the address of a handle table entry.

Implements the multi-level handle table lookup algorithm used by Windows. Returns the virtual address of the handle table entry.

Source

fn handle_to_object_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<Va>, VmiError>

Converts a handle to the virtual address of the corresponding object.

Uses the handle table entry lookup to find the object address for a given handle.

Source

fn handle_to_object( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, handle: u64, ) -> Result<Option<WindowsObject>, VmiError>

Retrieves the WindowsObject corresponding to a given handle in a process.

Source

fn object_from_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObject>, VmiError>

Parses a Windows object from its memory address.

Determines the object type and calls the appropriate parsing method. Currently supports File and Section object types.

Source

fn kernel_information_string_ex( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Option<String>, VmiError>

Retrieves the kernel information string.

§Implementation Details

The kernel information string is located by reading the NtBuildLabEx symbol from the kernel image.

Source

fn vad( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad: Va, ) -> Result<WindowsVad, VmiError>

Retrieves information about a Virtual Address Descriptor (VAD) for a given address.

This method extracts details such as the starting and ending virtual page numbers, VAD type, memory protection, and other flags associated with the specified VAD.

Source

fn vad_root( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<Va, VmiError>

Locates the VadRoot for a given process. Returns the address of the root node.

§Equivalent C pseudo-code
// For Windows 7:
return Process->VadRoot->BalancedRoot;

// For Windows 8 and later:
return Process->VadRoot->Root;
Source

fn vad_hint( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<Va, VmiError>

Retrieves the VadHint for a given process. Returns the address of the hint node in the VAD tree.

The VAD hint is an optimization used by Windows to speed up VAD lookups. This method returns the address of the hint node in the VAD tree.

§Equivalent C pseudo-code
// For Windows 7:
return Process->VadRoot->NodeHint;

// For Windows 8 and later:
return Process->VadRoot->Hint;
Source

fn vad_to_region( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad: Va, ) -> Result<OsRegion, VmiError>

Converts a VAD (Virtual Address Descriptor) to an OsRegion structure.

This method extracts information from a VAD and creates an OsRegion object, which includes details about the memory region’s address range, protection, and mapping type.

Source

fn vad_root_to_regions( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, vad_root: Va, ) -> Result<Vec<OsRegion>, VmiError>

Retrieves all memory regions associated with a process’s VAD tree.

This method traverses the entire VAD tree of a process and converts each VAD into an OsRegion, providing a comprehensive view of the process’s virtual address space.

Source

fn find_process_vad( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, address: Va, ) -> Result<Option<Va>, VmiError>

Locates the VAD that encompasses a specific virtual address in a process.

This method efficiently searches the VAD tree to find the VAD node that corresponds to the given virtual address within the process’s address space. Its functionality is similar to the Windows kernel’s internal MiLocateAddress() function.

Returns virtual address of the matching VAD if found, or None if the address is not within any VAD.

Source

fn lock_pfn( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, pfn: Gfn, ) -> Result<Option<u16>, VmiError>

Increments the reference count of a Page Frame Number (PFN).

This method is used to “lock” a physical page by increasing its reference count, preventing it from being paged out or reallocated.

Returns the new reference count if successful, or None if the operation failed (e.g., if the page is not in a valid state).

§Implementation Details

The method works by:

  1. Locating the _MMPFN structure for the given PFN within the MmPfnDatabase.
  2. Incrementing the ReferenceCount member of the _MMPFN structure.
§Warning

This function can potentially cause race conditions if the virtual machine is not paused during its execution. It is strongly recommended to pause the virtual machine before calling this function and resume it afterwards.

Failure to pause the VM may result in inconsistent state or potential crashes if the page is concurrently modified by the guest OS.

§Examples:
let _pause_guard = vmi.pause_guard()?;
os.lock_pfn(vmi, registers, pfn)?;
// The VM will automatically resume when `_guard` goes out of scope
Source

fn unlock_pfn( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, pfn: Gfn, ) -> Result<Option<u16>, VmiError>

Decrements the reference count of a Page Frame Number (PFN).

This method is used to “unlock” a physical page by decreasing its reference count, potentially allowing it to be paged out or reallocated if the count reaches zero.

Returns the new reference count if successful, or None if the operation failed (e.g., if the page is not in a valid state).

§Implementation Details

The method works by:

  1. Locating the _MMPFN structure for the given PFN within the MmPfnDatabase.
  2. Decrementing the ReferenceCount member of the _MMPFN structure.
§Warning

This function can potentially cause race conditions if the virtual machine is not paused during its execution. It is strongly recommended to pause the virtual machine before calling this function and resume it afterwards.

Failure to pause the VM may result in inconsistent state or potential crashes if the page is concurrently modified by the guest OS.

§Examples
let _pause_guard = vmi.pause_guard()?;
os.unlock_pfn(vmi, registers, pfn)?;
// The VM will automatically resume when `_guard` goes out of scope
Source

fn current_kpcr( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Va

Retrieves the virtual address of the current Kernel Processor Control Region (KPCR).

The KPCR is a per-processor data structure in Windows that contains critical information about the current processor state. This method returns the virtual address of the KPCR for the current processor.

Source

fn exception_record( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, address: Va, ) -> Result<WindowsExceptionRecord, VmiError>

Extracts information from an exception record at the specified address.

This method reads and parses an EXCEPTION_RECORD structure from memory, providing detailed information about an exception that has occurred in the system. The returned WindowsExceptionRecord contains data such as the exception code, flags, and related memory addresses.

Source

fn last_status( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Option<u32>, VmiError>

Retrieves the last status value for the current thread.

In Windows, the last status value is typically used to store error codes or success indicators from system calls. This method reads this value from the Thread Environment Block (TEB) of the current thread, providing insight into the outcome of recent operations performed by the thread.

Returns None if the TEB is not available.

§Notes

LastStatusValue is a NTSTATUS value, whereas LastError is a Win32 error code. The two values are related but not identical. You can obtain the Win32 error code by calling VmiOs::last_error.

§Implementation Details
return NtCurrentTeb()->LastStatusValue;

Retrieves the object header cookie used for obfuscating object types. Returns None if the cookie is not present in the kernel image.

§Notes

Windows 10 introduced a security feature that obfuscates the type of kernel objects by XORing the TypeIndex field in the object header with a random cookie value. This method fetches that cookie, which is essential for correctly interpreting object headers in memory.

§Implementation Details

The object header cookie is located by reading the ObHeaderCookie symbol from the kernel image.

Source

fn object_type( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObjectType>, VmiError>

Determines the type of a Windows kernel object.

This method analyzes the object header of a given kernel object and returns its type (e.g., Process, Thread, File). It handles the obfuscation introduced by the object header cookie, ensuring accurate type identification even on systems with this security feature enabled.

Source

fn object_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, object: Va, ) -> Result<Option<WindowsObjectName>, VmiError>

Retrieves the name of a named kernel object.

Many Windows kernel objects (like mutexes, events, etc.) can have names. This method extracts the name of such an object, if present. It also provides information about the object’s containing directory in the object namespace.

Source

fn object_attributes_to_object_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, object_attributes: Va, ) -> Result<Option<String>, VmiError>

Converts an OBJECT_ATTRIBUTES structure to an object name string.

OBJECT_ATTRIBUTES is a structure used in many Windows system calls to specify an object. This method interprets that structure and extracts a meaningful name or path for the object. It handles both absolute and relative object names, considering the root directory if specified.

Returns None if the _OBJECT_ATTRIBUTES::ObjectName field is NULL.

Source

fn process_peb( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<WindowsPeb, VmiError>

Retrieves the Process Environment Block (PEB) for a given process.

The PEB contains crucial information about a process, including its loaded modules, environment variables, and command line arguments.

Source

fn process_current_directory( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>

Gets the current working directory of a process.

This method retrieves the full path of the current working directory for the specified process.

§Equivalent C pseudo-code
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NtCurrentPeb()->ProcessParameters;
PUNICODE_STRING CurrentDirectory = ProcessParameters->CurrentDirectory;
return CurrentDirectory;
Source

fn process_dll_path( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>

Gets the DLL search path for a process.

This method retrieves the list of directories that the system searches when loading DLLs for the specified process.

§Equivalent C pseudo-code
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NtCurrentPeb()->ProcessParameters;
PUNICODE_STRING DllPath = ProcessParameters->DllPath;
return DllPath;
Source

fn process_image_path_name( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>

Gets the full path of the executable image for a process.

This method retrieves the full file system path of the main executable that was used to create the specified process.

§Equivalent C pseudo-code
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NtCurrentPeb()->ProcessParameters;
PUNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
return ImagePathName;
Source

fn process_command_line( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<String, VmiError>

Gets the command line used to launch a process.

This method retrieves the full command line string, including the executable path and any arguments, used to start the specified process.

§Equivalent C pseudo-code
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NtCurrentPeb()->ProcessParameters;
PUNICODE_STRING CommandLine = ProcessParameters->CommandLine;
return CommandLine;
Source

fn process_from_thread( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, thread: ThreadObject, ) -> Result<ProcessObject, VmiError>

Extracts the EPROCESS structure from a KTHREAD structure.

§Equivalent C pseudo-code
return Thread->Process;
Source

fn process_from_thread_apc_state( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, thread: ThreadObject, ) -> Result<ProcessObject, VmiError>

Extracts the EPROCESS structure from a KAPC_STATE structure.

§Equivalent C pseudo-code
return Thread->ApcState->Process;
Source

fn process_object_to_process( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, process: ProcessObject, ) -> Result<OsProcess, VmiError>

Constructs an OsProcess from an _EPROCESS.

Source

fn read_ansi_string( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from an _ANSI_STRING structure.

This method reads a native _ANSI_STRING structure which contains an ASCII/ANSI string. The structure is read according to the current OS’s architecture (32-bit or 64-bit).

Source

fn read_ansi_string32( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from a 32-bit version of _ANSI_STRING structure.

This method is specifically for reading _ANSI_STRING structures in 32-bit processes or WoW64 processes where pointers are 32 bits.

Source

fn read_ansi_string64( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from a 64-bit version of _ANSI_STRING structure.

This method is specifically for reading _ANSI_STRING structures in 64-bit processes where pointers are 64 bits.

Source

fn read_unicode_string( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from a _UNICODE_STRING structure.

This method reads a native _UNICODE_STRING structure which contains a UTF-16 string. The structure is read according to the current OS’s architecture (32-bit or 64-bit).

Source

fn read_unicode_string32( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from a 32-bit version of _UNICODE_STRING structure.

This method is specifically for reading _UNICODE_STRING structures in 32-bit processes or WoW64 processes where pointers are 32 bits.

Source

fn read_unicode_string64( &self, ctx: impl Into<AccessContext>, ) -> Result<String, VmiError>

Reads string from a 64-bit version of _UNICODE_STRING structure.

This method is specifically for reading _UNICODE_STRING structures in 64-bit processes where pointers are 64 bits.

Source

fn lowest_user_address( &self, _registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Va, VmiError>

Returns the lowest user-mode address.

This method returns a constant value (0x10000) representing the lowest address that can be used by user-mode applications in Windows.

§Notes
  • Windows creates a NO_ACCESS VAD (Virtual Address Descriptor) for the first 64KB of virtual memory. This means the VA range 0-0x10000 is off-limits for usage.

  • This behavior is consistent across all Windows versions from XP through recent Windows 11, and applies to x86, x64, and ARM64 architectures.

  • Many Windows APIs leverage this fact to determine whether an input argument is a pointer or not. Here are two notable examples:

    1. The FindResource() function accepts an lpName parameter of type LPCTSTR, which can be either:

      • A pointer to a valid string

      • A value created by MAKEINTRESOURCE(ID)

        This allows FindResource() to accept WORD values (unsigned shorts) with a maximum value of 0xFFFF, distinguishing them from valid memory addresses.

    2. The AddAtom() function similarly accepts an lpString parameter of type LPCTSTR. This parameter can be:

      • A pointer to a null-terminated string (max 255 bytes)
      • An integer atom converted using the MAKEINTATOM(ID) macro

    In both cases, the API can distinguish between valid pointers (which will be above 0x10000) and integer values (which will be below 0x10000), allowing for flexible parameter usage without ambiguity.

Source

fn highest_user_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, ) -> Result<Va, VmiError>

Retrieves the highest user-mode address.

This method reads the highest user-mode address from the Windows kernel. The value is cached after the first read for performance.

Source

fn is_valid_user_address( &self, registers: &<<Driver as VmiDriver>::Architecture as Architecture>::Registers, address: Va, ) -> Result<bool, VmiError>

Checks if a given address is a valid user-mode address.

This method determines whether the provided address falls within the range of valid user-mode addresses in Windows.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<Driver> WindowsOsSessionExt<Driver> for VmiOsSession<'_, Driver, WindowsOs<Driver>>
where Driver: VmiDriver, <Driver as VmiDriver>::Architecture: Architecture + ArchAdapter<Driver>,