1
mirror of https://github.com/thepeacockproject/Peacock synced 2025-03-01 14:43:02 +01:00
Peacock/patcher/Pinvoke.cs
Reece Dunham 6245e91624 Initial commit
Co-authored-by: Tino Roivanen <tino.roivanen98@gmail.com>
Co-authored-by: Govert de Gans <grappigegovert@hotmail.com>
Co-authored-by: Gray Olson <gray@grayolson.com>
Co-authored-by: Alexandre Sanchez <alex73630@gmail.com>
Co-authored-by: Anthony Fuller <24512050+anthonyfuller@users.noreply.github.com>
Co-authored-by: atampy25 <24306974+atampy25@users.noreply.github.com>
Co-authored-by: David <davidstulemeijer@gmail.com>
Co-authored-by: c0derMo <c0dermo@users.noreply.github.com>
Co-authored-by: Jeevat Singh <jeevatt.singh@gmail.com>
Signed-off-by: Reece Dunham <me@rdil.rocks>
2022-10-19 21:33:45 -04:00

115 lines
4.5 KiB
C#

using System;
#if TARGET_WINDOWS
using System.ComponentModel;
using System.Diagnostics;
#endif
using System.Runtime.InteropServices;
namespace HitmanPatcher
{
// from https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants
[Flags]
public enum MemProtection : uint
{
PAGE_EXECUTE = 0x00000010,
PAGE_EXECUTE_READ = 0x00000020,
PAGE_EXECUTE_READWRITE = 0x00000040,
PAGE_EXECUTE_WRITECOPY = 0x00000080,
PAGE_NOACCESS = 0x00000001,
PAGE_READONLY = 0x00000002,
PAGE_READWRITE = 0x00000004,
PAGE_WRITECOPY = 0x00000008,
PAGE_GUARD = 0x00000100,
PAGE_NOCACHE = 0x00000200,
PAGE_WRITECOMBINE = 0x00000400
}
// from https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
// I've only listed the ones that I use
[Flags]
public enum ProcessAccess : uint
{
#if TARGET_WINDOWS
PROCESS_QUERY_INFORMATION = 0x0400, // Required to retrieve certain information about a process.
#endif
PROCESS_VM_READ = 0x0010, // Required to read memory in a process using ReadProcessMemory.
PROCESS_VM_WRITE = 0x0020, // Required to write to memory in a process using WriteProcessMemory.
PROCESS_VM_OPERATION = 0x0008 // Required to perform an operation on the address space of a process using VirtualProtectEx
}
#if TARGET_WINDOWS
// from https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
public enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29,
ProcessSubsystemInformation = 75
}
// from https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebBaseAddress;
public IntPtr Reserved2_0;
public IntPtr Reserved2_1;
public IntPtr UniqueProcessId;
public IntPtr Reserved3;
}
#endif
public static class Pinvoke
{
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory([In] IntPtr hProcess, [In] IntPtr address, [In, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, [In] UIntPtr size, [Out] out UIntPtr byteswritten);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory([In] IntPtr hProcess, [In] IntPtr address, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] buffer, [In] UIntPtr size, [Out] out UIntPtr numberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtectEx([In] IntPtr hProcess, [In] IntPtr lpAddress, [In] UIntPtr dwSize, [In] MemProtection flNewProtect, [Out] out MemProtection lpflOldProtect);
#if TARGET_WINDOWS
[DllImport("ntdll.dll")]
public static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS processInformationClass, out PROCESS_BASIC_INFORMATION processInformation, uint processInformationLength, out uint returnLength);
public static int GetProcessParentPid(Process process)
{
IntPtr hProcess = OpenProcess(
ProcessAccess.PROCESS_VM_READ
| ProcessAccess.PROCESS_QUERY_INFORMATION,
false, process.Id);
if (hProcess == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get a process handle.");
}
PROCESS_BASIC_INFORMATION PEB = new PROCESS_BASIC_INFORMATION();
int result = NtQueryInformationProcess(hProcess,
PROCESSINFOCLASS.ProcessBasicInformation, out PEB,
(uint) Marshal.SizeOf(PEB), out _);
CloseHandle(hProcess);
if (result != 0)
{
throw new Win32Exception(result, "(NTSTATUS)"); // not a w32 status code, but an NTSTATUS
}
return PEB.Reserved3.ToInt32(); // undocumented, but should hold the parent PID
}
#endif
}
}