Короче, если вы пишите на Rust под Win, то скорее всего знаете, что существует две основных библы с биндами: офциальный windows-rs/windows-sys и забытый богом winapi-rs. Я выбор отдал в пользу первого и вам советую. Есть только пару недостатков, например отсутсвие биндов под NtApi и Peb/Teb.
В общем убил 20 мин, переписал PEB и TEB структуры под windows-sys. Надеюсь не обосрался нигде.
Может кому-то пригодится:
В общем убил 20 мин, переписал PEB и TEB структуры под windows-sys. Надеюсь не обосрался нигде.
Может кому-то пригодится:
Код:
use std::ffi::c_void;
use std::arch::asm;
use windows_sys::core::GUID;
use windows_sys::Win32::{
Foundation::{BOOLEAN, UNICODE_STRING, NTSTATUS, HANDLE},
System::{
Kernel::{NT_TIB, LIST_ENTRY, SLIST_HEADER, PROCESSOR_NUMBER},
Threading::{RTL_CRITICAL_SECTION, PEB_LDR_DATA, RTL_USER_PROCESS_PARAMETERS},
WindowsProgramming::CLIENT_ID
}
};
macro_rules! field_offset {
($_type:ty, $field:ident$(.$cfields:ident)*) => {
unsafe {
union Transmuter<T: 'static> { p: *const T, r: &'static T, i: usize }
Transmuter {
r: &(&Transmuter {
p: core::ptr::null::<$_type>()
}.r).$field$(.$cfields)*
}.i
}
};
}
#[inline]
pub unsafe fn __readfsdword(offset: u32) -> u32 {
let out: u32;
asm!(
"mov {:e}, fs:[{:e}]",
lateout(reg) out,
in(reg) offset,
options(nostack, pure, readonly),
);
out
}
#[inline]
#[cfg(target_pointer_width = "64")]
pub unsafe fn __readgsqword(offset: u32) -> u64 {
let out: u64;
asm!(
"mov {}, gs:[{:e}]",
lateout(reg) out,
in(reg) offset,
options(nostack, pure, readonly),
);
out
}
#[inline] #[allow(non_snake_case)]
pub unsafe fn NtCurrentTeb() -> *mut TEB {
let offset = field_offset!(NT_TIB, Self_) as u32;
#[cfg(target_arch = "x86_64")] {
__readgsqword(offset) as *mut TEB
}
#[cfg(target_arch = "x86")] {
__readfsdword(offset) as *mut TEB
}
}
#[inline] #[allow(non_snake_case)]
pub unsafe fn NtCurrentPeb() -> *mut PEB {
(*NtCurrentTeb()).ProcessEnvironmentBlock
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct TEB {
pub NtTib: NT_TIB,
pub EnvironmentPointer: *mut c_void,
pub ClientId: CLIENT_ID,
pub ActiveRpcHandle: *mut c_void,
pub ThreadLocalStoragePointer: *mut c_void,
pub ProcessEnvironmentBlock: *mut PEB,
pub LastErrorValue: u32,
pub CountOfOwnedCriticalSections: u32,
pub CsrClientThread: *mut c_void,
pub Win32ThreadInfo: *mut c_void,
pub User32Reserved: [u32; 26],
pub UserReserved: [u32; 5],
pub WOW32Reserved: *mut c_void,
pub CurrentLocale: u32,
pub FpSoftwareStatusRegister: u32,
pub ReservedForDebuggerInstrumentation: [*mut c_void; 16],
pub SystemReserved1: [*mut c_void; 30],
pub PlaceholderCompatibilityMode: i8,
pub PlaceholderReserved: [i8; 11],
pub ProxiedProcessId: u32,
pub ActivationStack: ACTIVATION_CONTEXT_STACK,
pub WorkingOnBehalfTicket: [u8; 8],
pub ExceptionCode: NTSTATUS,
pub ActivationContextStackPointer: *mut ACTIVATION_CONTEXT_STACK,
pub InstrumentationCallbackSp: usize,
pub InstrumentationCallbackPreviousPc: usize,
pub InstrumentationCallbackPreviousSp: usize,
pub TxFsContext: u32,
pub InstrumentationCallbackDisabled: BOOLEAN,
pub GdiTebBatch: GDI_TEB_BATCH,
pub RealClientId: CLIENT_ID,
pub GdiCachedProcessHandle: HANDLE,
pub GdiClientPID: u32,
pub GdiClientTID: u32,
pub GdiThreadLocalInfo: *mut c_void,
pub Win32ClientInfo: [usize; 62],
pub glDispatchTable: [*mut c_void; 233],
pub glReserved1: [usize; 29],
pub glReserved2: *mut c_void,
pub glSectionInfo: *mut c_void,
pub glSection: *mut c_void,
pub glTable: *mut c_void,
pub glCurrentRC: *mut c_void,
pub glContext: *mut c_void,
pub LastStatusValue: NTSTATUS,
pub StaticUnicodeString: UNICODE_STRING,
pub StaticUnicodeBuffer: [u16; 261],
pub DeallocationStack: *mut c_void,
pub TlsSlots: [*mut c_void; 64],
pub TlsLinks: LIST_ENTRY,
pub Vdm: *mut c_void,
pub ReservedForNtRpc: *mut c_void,
pub DbgSsReserved: [*mut c_void; 2],
pub HardErrorMode: u32,
pub Instrumentation: [*mut c_void; 11],
pub ActivityId: GUID,
pub SubProcessTag: *mut c_void,
pub PerflibData: *mut c_void,
pub EtwTraceData: *mut c_void,
pub WinSockData: *mut c_void,
pub GdiBatchCount: u32,
pub u: TEB_u,
pub GuaranteedStackBytes: u32,
pub ReservedForPerf: *mut c_void,
pub ReservedForOle: *mut c_void,
pub WaitingOnLoaderLock: u32,
pub SavedPriorityState: *mut c_void,
pub ReservedForCodeCoverage: usize,
pub ThreadPoolData: *mut c_void,
pub TlsExpansionSlots: *mut *mut c_void,
pub DeallocationBStore: *mut c_void,
pub BStoreLimit: *mut c_void,
pub MuiGeneration: u32,
pub IsImpersonating: u32,
pub NlsCache: *mut c_void,
pub pShimData: *mut c_void,
pub HeapVirtualAffinity: u16,
pub LowFragHeapDataSlot: u16,
pub CurrentTransactionHandle: HANDLE,
pub ActiveFrame: *mut TEB_ACTIVE_FRAME,
pub FlsData: *mut c_void,
pub PreferredLanguages: *mut c_void,
pub UserPrefLanguages: *mut c_void,
pub MergedPrefLanguages: *mut c_void,
pub MuiImpersonation: u32,
pub CrossTebFlags: u16,
pub SameTebFlags: u16,
pub TxnScopeEnterCallback: *mut c_void,
pub TxnScopeExitCallback: *mut c_void,
pub TxnScopeContext: *mut c_void,
pub LockCount: u32,
pub WowTebOffset: i32,
pub ResourceRetValue: *mut c_void,
pub ReservedForWdf: *mut c_void,
pub ReservedForCrt: u64,
pub EffectiveContainerId: GUID,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct PEB {
pub InheritedAddressSpace: BOOLEAN,
pub ReadImageFileExecOptions: BOOLEAN,
pub BeingDebugged: BOOLEAN,
pub BitField: BOOLEAN,
pub Mutant: HANDLE,
pub ImageBaseAddress: *mut c_void,
pub Ldr: *mut PEB_LDR_DATA,
pub ProcessParameters: *mut RTL_USER_PROCESS_PARAMETERS,
pub SubSystemData: *mut c_void,
pub ProcessHeap: *mut c_void,
pub FastPebLock: *mut RTL_CRITICAL_SECTION,
pub IFEOKey: *mut c_void,
pub AtlThunkSListPtr: *mut SLIST_HEADER,
pub CrossProcessFlags: u32,
pub u: PEB_u,
pub SystemReserved: [u32; 1],
pub AtlThunkSListPtr32: u32,
pub ApiSetMap: *mut API_SET_NAMESPACE,
pub TlsExpansionCounter: u32,
pub TlsBitmap: *mut c_void,
pub TlsBitmapBits: [u32; 2],
pub ReadOnlySharedMemoryBase: *mut c_void,
pub SharedData: *mut c_void,
pub ReadOnlyStaticServerData: *mut *mut c_void,
pub AnsiCodePageData: *mut c_void,
pub OemCodePageData: *mut c_void,
pub UnicodeCaseTableData: *mut c_void,
pub NumberOfProcessors: u32,
pub NtGlobalFlag: u32,
pub CriticalSectionTimeout: ULARGE_INTEGER,
pub HeapSegmentReserve: usize,
pub HeapSegmentCommit: usize,
pub HeapDeCommitTotalFreeThreshold: usize,
pub HeapDeCommitFreeBlockThreshold: usize,
pub NumberOfHeaps: u32,
pub MaximumNumberOfHeaps: u32,
pub ProcessHeaps: *mut *mut c_void,
pub GdiSharedHandleTable: *mut c_void,
pub ProcessStarterHelper: *mut c_void,
pub GdiDCAttributeList: u32,
pub LoaderLock: *mut RTL_CRITICAL_SECTION,
pub OSMajorVersion: u32,
pub OSMinorVersion: u32,
pub OSBuildNumber: u16,
pub OSCSDVersion: u16,
pub OSPlatformId: u32,
pub ImageSubsystem: u32,
pub ImageSubsystemMajorVersion: u32,
pub ImageSubsystemMinorVersion: u32,
pub ActiveProcessAffinityMask: usize,
pub GdiHandleBuffer: [u32; 60],
pub PostProcessInitRoutine: *mut c_void,
pub TlsExpansionBitmap: *mut c_void,
pub TlsExpansionBitmapBits: [u32; 32],
pub SessionId: u32,
pub AppCompatFlags: ULARGE_INTEGER,
pub AppCompatFlagsUser: ULARGE_INTEGER,
pub pShimData: *mut c_void,
pub AppCompatInfo: *mut c_void,
pub CSDVersion: UNICODE_STRING,
pub ActivationContextData: *mut c_void,
pub ProcessAssemblyStorageMap: *mut c_void,
pub SystemDefaultActivationContextData: *mut c_void,
pub SystemAssemblyStorageMap: *mut c_void,
pub MinimumStackCommit: usize,
pub FlsCallback: *mut *mut c_void,
pub FlsListHead: LIST_ENTRY,
pub FlsBitmap: *mut c_void,
pub FlsBitmapBits: [u32; 4],
pub FlsHighIndex: u32,
pub WerRegistrationData: *mut c_void,
pub WerShipAssertPtr: *mut c_void,
pub pUnused: *mut c_void,
pub pImageHeaderHash: *mut c_void,
pub TracingFlags: u32,
pub CsrServerReadOnlySharedMemoryBase: u64,
pub TppWorkerpListLock: *mut RTL_CRITICAL_SECTION,
pub TppWorkerpList: LIST_ENTRY,
pub WaitOnAddressHashTable: [*mut c_void; 128],
pub TelemetryCoverageHeader: *mut c_void,
pub CloudFileFlags: u32,
pub CloudFileDiagFlags: u32,
pub PlaceholderCompatibilityMode: i8,
pub PlaceholderCompatibilityModeReserved: [i8; 7],
pub LeapSecondData: *mut LEAP_SECOND_DATA,
pub LeapSecondFlags: u32,
pub NtGlobalFlag2: u32,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct ACTIVATION_CONTEXT_STACK {
pub ActiveFrame: *mut RTL_ACTIVATION_CONTEXT_STACK_FRAME,
pub FrameListCache: LIST_ENTRY,
pub Flags: u32,
pub NextCookieSequenceNumber: u32,
pub StackId: u32,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct RTL_ACTIVATION_CONTEXT_STACK_FRAME {
pub Previous: *mut RTL_ACTIVATION_CONTEXT_STACK_FRAME,
pub ActivationContext: *mut ACTIVATION_CONTEXT,
pub Flags: u32,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct ACTIVATION_CONTEXT {
pub dummy: *mut c_void,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct GDI_TEB_BATCH {
pub Offset: u32,
pub HDC: usize,
pub Buffer: [u32; 310],
}
#[repr(C)] #[derive(Copy, Clone)]
pub union TEB_u {
pub CurrentIdealProcessor: PROCESSOR_NUMBER,
pub IdealProcessorValue: u32,
pub s: TEB_u_s,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct TEB_u_s {
pub ReservedPad0: u8,
pub ReservedPad1: u8,
pub ReservedPad2: u8,
pub IdealProcessor: u8,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct TEB_ACTIVE_FRAME {
pub Flags: u32,
pub Previous: *mut TEB_ACTIVE_FRAME,
pub Context: *mut TEB_ACTIVE_FRAME_CONTEXT,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct TEB_ACTIVE_FRAME_CONTEXT {
pub Flags: u32,
pub FrameName: *mut i8,
}
#[repr(C)] #[derive(Copy, Clone)]
pub union PEB_u {
pub KernelCallbackTable: *mut c_void,
pub UserSharedInfoPtr: *mut c_void
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct API_SET_NAMESPACE {
pub Version: u32,
pub Size: u32,
pub Flags: u32,
pub Count: u32,
pub EntryOffset: u32,
pub HashOffset: u32,
pub HashFactor: u32,
}
#[repr(C)] #[derive(Copy, Clone)]
pub struct LEAP_SECOND_DATA([u8; 0]);
#[repr(C)] #[derive(Copy, Clone)]
pub struct ULARGE_INTEGER([u64; 1]);