Implemented: - Core: UTF-16 ReadString boundary/alignment fix, target bitness and process id on MemoryBase - function interception: PatchManager, DetourManager, InstructionAnalyzer, MainThreadDispatcher - Execution: BackgroundTaskExecutor, InProcessInvoker - High-level: Magic facade, RemotePointer, async wrappers - Discovery/external code loading/Window groundwork (PEB/TEB, pattern scanning, raw allocations, DLL external code loading, window/input) Tests: 180 passing, 4 integration/interactive tests skipped.
179 lines
6.6 KiB
C#
179 lines
6.6 KiB
C#
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace WhiteMagic.Native;
|
|
|
|
/// <summary>
|
|
/// P/Invoke declarations for kernel32/ntdll/user32 APIs used by the high-level
|
|
/// PEB, TEB, windowing, and input helpers. These live in a separate partial file so
|
|
/// they can evolve independently of <see cref="NativeMethods"/>.
|
|
/// </summary>
|
|
internal static partial class NativeMethods
|
|
{
|
|
// ── Natives used directly by public helpers ──────────────────────────────
|
|
|
|
/// <summary>Queries information about the specified process.</summary>
|
|
[LibraryImport("ntdll.dll")]
|
|
internal static partial int NtQueryInformationProcess(
|
|
SafeMemoryHandle processHandle,
|
|
int processInformationClass,
|
|
ref ProcessBasicInformation processInformation,
|
|
uint processInformationLength,
|
|
out uint returnLength);
|
|
|
|
/// <summary>Queries information about the specified thread.</summary>
|
|
[LibraryImport("ntdll.dll")]
|
|
internal static partial int NtQueryInformationThread(
|
|
SafeMemoryHandle threadHandle,
|
|
int threadInformationClass,
|
|
ref ThreadBasicInformation threadInformation,
|
|
uint threadInformationLength,
|
|
out uint returnLength);
|
|
|
|
/// <summary>Enumerates all top-level windows on the screen.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
internal static partial int EnumWindows(
|
|
nint lpEnumFunc,
|
|
IntPtr lParam);
|
|
|
|
/// <summary>Retrieves the identifier of the thread that created the window and the process id of the window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
internal static partial uint GetWindowThreadProcessId(
|
|
IntPtr hWnd,
|
|
out uint lpdwProcessId);
|
|
|
|
/// <summary>Retrieves the name of the class to which the specified window belongs.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
|
|
internal static partial int GetClassNameW(
|
|
IntPtr hWnd,
|
|
[Out] char[] lpClassName,
|
|
int nMaxCount);
|
|
|
|
/// <summary>Copies the text of the specified window's title bar into a buffer.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
|
|
internal static partial int GetWindowTextW(
|
|
IntPtr hWnd,
|
|
[Out] char[] lpString,
|
|
int nMaxCount);
|
|
|
|
/// <summary>Changes the text of the specified window's title bar.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool SetWindowTextW(
|
|
IntPtr hWnd,
|
|
string lpString);
|
|
|
|
/// <summary>Changes the size, position, and Z order of a child, pop-up, or top-level window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool SetWindowPos(
|
|
IntPtr hWnd,
|
|
IntPtr hWndInsertAfter,
|
|
int x,
|
|
int y,
|
|
int cx,
|
|
int cy,
|
|
uint uFlags);
|
|
|
|
/// <summary>Retrieves a handle to the foreground window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
internal static partial IntPtr GetForegroundWindow();
|
|
|
|
/// <summary>Brings the thread that created the specified window into the foreground and activates the window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool SetForegroundWindow(IntPtr hWnd);
|
|
|
|
/// <summary>Flashes the specified window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool FlashWindowEx(ref FlashWindowInfo pwfi);
|
|
|
|
/// <summary>Attaches or detaches the input processing mechanism of one thread to that of another thread.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool AttachThreadInput(
|
|
uint idAttach,
|
|
uint idAttachTo,
|
|
[MarshalAs(UnmanagedType.Bool)] bool fAttach);
|
|
|
|
/// <summary>Places a message in the message queue associated with the thread that created the specified window.</summary>
|
|
[LibraryImport("user32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
internal static partial bool PostMessageW(
|
|
IntPtr hWnd,
|
|
uint msg,
|
|
nuint wParam,
|
|
nint lParam);
|
|
|
|
// ── Window / input constants ───────────────────────────────────────────────
|
|
|
|
internal const uint WmChar = 0x0102;
|
|
internal const uint WmLButtonDown = 0x0201;
|
|
internal const uint WmLButtonUp = 0x0202;
|
|
internal const uint WmRButtonDown = 0x0204;
|
|
internal const uint WmRButtonUp = 0x0205;
|
|
|
|
internal static readonly IntPtr HwndTop = IntPtr.Zero;
|
|
|
|
internal const uint SwpShowWindow = 0x0040;
|
|
internal const uint SwpNoActivate = 0x0010;
|
|
|
|
internal const uint FlashwAll = 0x00000003;
|
|
internal const uint FlashwCaption = 0x00000001;
|
|
internal const uint FlashwTray = 0x00000002;
|
|
internal const uint FlashwTimer = 0x00000004;
|
|
internal const uint FlashwTimerNoFg = 0x0000000C;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Layout matches <c>PROCESS_BASIC_INFORMATION</c> (ProcessBasicInformation = 0).
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct ProcessBasicInformation
|
|
{
|
|
public int ExitStatus;
|
|
public IntPtr PebBaseAddress;
|
|
public UIntPtr AffinityMask;
|
|
public int BasePriority;
|
|
public UIntPtr UniqueProcessId;
|
|
public UIntPtr InheritedFromUniqueProcessId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Layout matches <c>THREAD_BASIC_INFORMATION</c> (ThreadBasicInformation = 0).
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct ThreadBasicInformation
|
|
{
|
|
public int ExitStatus;
|
|
public IntPtr TebBaseAddress;
|
|
public ClientId ClientId;
|
|
public UIntPtr AffinityMask;
|
|
public int Priority;
|
|
public int BasePriority;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Layout matches <c>CLIENT_ID</c>.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct ClientId
|
|
{
|
|
public IntPtr UniqueProcess;
|
|
public IntPtr UniqueThread;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Layout matches <c>FLASHWINFO</c> used by <see cref="NativeMethods.FlashWindowEx"/>.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct FlashWindowInfo
|
|
{
|
|
public uint cbSize;
|
|
public IntPtr hwnd;
|
|
public uint dwFlags;
|
|
public uint uCount;
|
|
public uint dwTimeout;
|
|
}
|