using System.Runtime.InteropServices; namespace WhiteMagic.Native; /// /// P/Invoke declarations for the Win32 process, memory, thread, and module /// APIs that WhiteMagic uses. Every declaration uses /// (source-generated interop). SetLastError is enabled on all calls that the /// Win32 API documents as setting a thread-local last-error value. /// internal static partial class NativeMethods { // ── Process ────────────────────────────────────────────────────────────── /// Opens an existing process and returns a handle to it. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial SafeMemoryHandle OpenProcess( ProcessAccess desiredAccess, [MarshalAs(UnmanagedType.Bool)] bool inheritHandle, int processId); /// Opens an existing thread and returns a handle to it. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial SafeMemoryHandle OpenThread( ThreadAccess desiredAccess, [MarshalAs(UnmanagedType.Bool)] bool inheritHandle, int threadId); /// Closes an open object handle. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool CloseHandle(IntPtr handle); /// Determines whether the specified process is running under WOW64. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool IsWow64Process( SafeMemoryHandle process, [MarshalAs(UnmanagedType.Bool)] out bool wow64Process); /// Retrieves the termination status of the specified thread. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool GetExitCodeThread( SafeMemoryHandle thread, out uint exitCode); // ── Memory ─────────────────────────────────────────────────────────────── /// Reads memory from a process. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool ReadProcessMemory( SafeMemoryHandle process, IntPtr baseAddress, Span buffer, int size, out nint bytesRead); /// Writes memory to a process. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool WriteProcessMemory( SafeMemoryHandle process, IntPtr baseAddress, ReadOnlySpan buffer, int size, out nint bytesWritten); /// Reserves or commits a region of memory in a process. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial IntPtr VirtualAllocEx( SafeMemoryHandle process, IntPtr address, nint size, MemoryAllocationType allocationType, MemoryProtectionType protect); /// Changes the protection on a committed region of memory. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool VirtualProtectEx( SafeMemoryHandle process, IntPtr address, nint size, MemoryProtectionType newProtect, out MemoryProtectionType oldProtect); /// Releases or decommits a region of memory in a process. [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool VirtualFreeEx( SafeMemoryHandle process, IntPtr address, nint size, MemoryFreeType freeType); // ── Threading ──────────────────────────────────────────────────────────── /// Creates a thread that runs in the virtual address space of a process. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial SafeMemoryHandle CreateRemoteThread( SafeMemoryHandle process, IntPtr threadAttributes, nint stackSize, IntPtr startAddress, IntPtr parameter, ThreadCreationFlags creationFlags, out uint threadId); /// Suspends the specified thread. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial uint SuspendThread(SafeMemoryHandle thread); /// Resumes the specified thread. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial uint ResumeThread(SafeMemoryHandle thread); /// Returns the thread identifier of the specified thread. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial uint GetThreadId(SafeMemoryHandle thread); /// Returns the identifier of the calling thread. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial uint GetCurrentThreadId(); /// Sets a 64-bit thread context (AMD64). [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool SetThreadContext( SafeMemoryHandle thread, ref Context64 context); /// Gets a 64-bit thread context (AMD64). [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool GetThreadContext( SafeMemoryHandle thread, ref Context64 context); /// Sets a 32-bit thread context (x86 or WOW64). [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool SetThreadContext( SafeMemoryHandle thread, ref Context32 context); /// Gets a 32-bit thread context (x86 or WOW64). [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool GetThreadContext( SafeMemoryHandle thread, ref Context32 context); // ── Modules ────────────────────────────────────────────────────────────── /// Loads a module into the calling process. [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryW")] internal static partial IntPtr LoadLibrary( [MarshalAs(UnmanagedType.LPWStr)] string lpFileName); /// Returns the address of a function or variable from a loaded module. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial IntPtr GetProcAddress( IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); /// Waits until an object is signaled or the timeout elapses. Returns a /// WAIT_* status (DWORD); WAIT_FAILED is 0xFFFFFFFF. [LibraryImport("kernel32.dll", SetLastError = true)] internal static partial uint WaitForSingleObject( SafeMemoryHandle handle, uint milliseconds); }