VMProtect/runtime/VMProtect.Runtime/Win32.cs
VNGhostMans 5ec92ee05e first commit
Version 3.x.x
2023-05-14 20:21:09 +07:00

825 lines
28 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public enum MessageBoxButtons : uint
{
OK,
OKCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel,
CancelTryAgainContinue
}
public enum MessageBoxIcon : uint
{
Asterisk = 0x40,
Error = 0x10,
Exclamation = 0x30,
Hand = 0x10,
Information = 0x40,
None = 0,
Question = 0x20,
Stop = 0x10,
Warning = 0x30,
UserIcon = 0x80
}
internal static class Win32
{
[Flags()]
public enum AllocationType : uint
{
Commit = 0x1000,
Reserve = 0x2000,
}
[Flags()]
public enum FreeType : uint
{
Release = 0x8000,
}
[Flags()]
public enum MemoryProtection : uint
{
NoAccess = 0x01,
ReadOnly = 0x02,
ReadWrite = 0x04,
WriteCopy = 0x08,
Execute = 0x10,
ExecuteRead = 0x20,
ExecuteReadWrite = 0x40,
Guard = 0x100
}
[Flags()]
public enum MapAccess : uint
{
Copy = 0x0001,
Write = 0x0002,
Read = 0x0004,
AllAccess = 0x001f
}
[Flags()]
public enum SectionType : uint
{
Execute = 0x20000000,
Read = 0x40000000,
Write = 0x80000000
}
[StructLayout(LayoutKind.Sequential)]
public struct UNICODE_STRING
{
public readonly ushort Length;
public readonly ushort MaximumLength;
private readonly IntPtr Buffer;
public UNICODE_STRING(string str)
{
if (str == null)
{
Length = 0;
MaximumLength = 0;
Buffer = IntPtr.Zero;
}
else
{
Length = (ushort)(str.Length * UnicodeEncoding.CharSize);
MaximumLength = (ushort)(Length + UnicodeEncoding.CharSize);
Buffer = Marshal.StringToHGlobalUni(str);
}
}
public void Dispose()
{
if (Buffer != IntPtr.Zero)
Marshal.FreeHGlobal(Buffer);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_ATTRIBUTES
{
public readonly uint Length;
public readonly IntPtr RootDirectory;
public readonly IntPtr ObjectName;
public readonly uint Attributes;
public readonly IntPtr SecurityDescriptor;
public readonly IntPtr SecurityQualityOfService;
public OBJECT_ATTRIBUTES(UNICODE_STRING name, uint attrs)
{
Length = (uint)Marshal.SizeOf(typeof(OBJECT_ATTRIBUTES));
RootDirectory = IntPtr.Zero;
ObjectName = IntPtr.Zero;
Attributes = attrs;
SecurityDescriptor = IntPtr.Zero;
SecurityQualityOfService = IntPtr.Zero;
ObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(name));
Marshal.StructureToPtr(name, ObjectName, false);
}
public void Dispose()
{
Marshal.FreeHGlobal(ObjectName);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct IO_STATUS_BLOCK
{
public uint Status;
public IntPtr Information;
}
[StructLayout(LayoutKind.Sequential)]
public struct LARGE_INTEGER
{
public uint LowPart;
public uint HighPart;
}
public enum HardErrorResponse
{
ReturnToCaller,
NotHandled,
Abort, Cancel,
Ignore,
No,
Ok,
Retry,
Yes
}
public enum Values : uint
{
GENERIC_READ = 0x80000000,
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
FILE_READ_ATTRIBUTES = 0x00000080,
SYNCHRONIZE = 0x00100000,
SECTION_QUERY = 0x0001,
SECTION_MAP_WRITE = 0x0002,
SECTION_MAP_READ = 0x0004,
SECTION_MAP_EXECUTE = 0x0008,
SEC_COMMIT = 0x8000000,
FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
FILE_NON_DIRECTORY_FILE = 0x00000040,
}
public static readonly IntPtr InvalidHandleValue = new IntPtr(-1);
public static readonly IntPtr NullHandle = IntPtr.Zero;
public static readonly IntPtr CurrentProcess = new IntPtr(-1);
public static readonly IntPtr CurrentThread = new IntPtr(-2);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass,
IntPtr ProcessInformation, int ProcessInformationLength, out uint ReturnLength);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtSetInformationThread(IntPtr ThreadHandle, THREADINFOCLASS ThreadInformationClass, IntPtr ThreadInformation,
uint ThreadInformationLength);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tEnumSystemFirmwareTables(uint firmwareTableProviderSignature, IntPtr firmwareTableBuffer, uint bufferSize);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tGetSystemFirmwareTable(uint firmwareTableProviderSignature, uint firmwareTableID, IntPtr firmwareTableBuffer, uint bufferSize);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtClose(IntPtr Handle);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtProtectVirtualMemory(IntPtr ProcesssHandle, ref IntPtr BaseAddress, ref UIntPtr RegionSize, MemoryProtection Protect, out MemoryProtection OldProtect);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref UIntPtr RegionSize, AllocationType AllocationType, MemoryProtection Protect);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref UIntPtr RegionSize, FreeType FreeType);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtUnmapViewOfSection(IntPtr ProcessHandle, IntPtr BaseAddress);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate IntPtr tMapViewOfFile(IntPtr hFileMappingObject, MapAccess dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, IntPtr dwNumBytesToMap);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtRaiseHardError(uint ErrorStatus, uint NumberOfParameters, uint UnicodeStringParameterMask, IntPtr[] Parameters, uint ValidResponseOptions, out HardErrorResponse Response);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtOpenFile(out IntPtr FileHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, out IO_STATUS_BLOCK IoStatusBlock, uint ShareAccess, uint OpenOptions);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtCreateSection(out IntPtr SectionHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, ref LARGE_INTEGER MaximumSize, MemoryProtection SectionPageProtection, uint AllocationAttributes, IntPtr FileHandle);
private static IntPtr _ntdll;
private static tNtQueryInformationProcess _nt_query_information_process;
private static tNtSetInformationThread _nt_set_information_thread;
private static tNtClose _nt_close;
private static tNtProtectVirtualMemory _nt_protect_virtual_memory;
private static tNtAllocateVirtualMemory _nt_allocate_virtual_memory;
private static tNtFreeVirtualMemory _nt_free_virtual_memory;
private static tNtUnmapViewOfSection _nt_unmap_view_of_section;
private static tNtRaiseHardError _nt_raise_hard_error;
private static tNtOpenFile _nt_open_file;
private static tNtCreateSection _nt_create_section;
private static IntPtr _kernel32;
private static tEnumSystemFirmwareTables _enum_system_firmware_tables;
private static tGetSystemFirmwareTable _get_system_firmware_table;
private static tMapViewOfFile _map_view_of_file;
static Win32()
{
_ntdll = GetModuleHandleEnc((uint)Faces.NTDLL_NAME);
_nt_query_information_process = (tNtQueryInformationProcess)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_QUERY_INFORMATION_PROCESS_NAME), typeof(tNtQueryInformationProcess));
_nt_set_information_thread = (tNtSetInformationThread)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_SET_INFORMATION_THREAD_NAME), typeof(tNtSetInformationThread));
_nt_close = (tNtClose)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_CLOSE), typeof(tNtClose));
_nt_protect_virtual_memory = (tNtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_VIRTUAL_PROTECT_NAME), typeof(tNtProtectVirtualMemory));
_nt_allocate_virtual_memory = (tNtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_ALLOCATE_VIRTUAL_MEMORY_NAME), typeof(tNtAllocateVirtualMemory));
_nt_free_virtual_memory = (tNtFreeVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_FREE_VIRTUAL_MEMORY_NAME), typeof(tNtFreeVirtualMemory));
_nt_unmap_view_of_section = (tNtUnmapViewOfSection)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_UNMAP_VIEW_OF_SECTION), typeof(tNtUnmapViewOfSection));
_nt_raise_hard_error = (tNtRaiseHardError)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_RAISE_HARD_ERROR_NAME), typeof(tNtRaiseHardError));
_nt_open_file = (tNtOpenFile)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_OPEN_FILE_NAME), typeof(tNtOpenFile));
_nt_create_section = (tNtCreateSection)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_CREATE_SECTION_NAME), typeof(tNtCreateSection));
_kernel32 = GetModuleHandleEnc((uint)Faces.KERNEL32_NAME);
IntPtr proc = GetProcAddressEnc(_kernel32, (uint)Faces.ENUM_SYSTEM_FIRMWARE_NAME);
if (proc != IntPtr.Zero)
_enum_system_firmware_tables = (tEnumSystemFirmwareTables)Marshal.GetDelegateForFunctionPointer(proc, typeof(tEnumSystemFirmwareTables));
proc = GetProcAddressEnc(_kernel32, (uint)Faces.GET_SYSTEM_FIRMWARE_NAME);
if (proc != IntPtr.Zero)
_get_system_firmware_table = (tGetSystemFirmwareTable)Marshal.GetDelegateForFunctionPointer(proc, typeof(tGetSystemFirmwareTable));
_map_view_of_file = (tMapViewOfFile)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_kernel32, (uint)Faces.NT_MAP_VIEW_OF_SECTION), typeof(tMapViewOfFile));
}
internal static IntPtr GetModuleHandleEnc(uint position)
{
long instance = Marshal.GetHINSTANCE(typeof(Loader).Module).ToInt64();
var buffer = new byte[100];
for (var pos = 0; pos < buffer.Length; pos++)
{
var c = (byte)(Marshal.ReadByte(new IntPtr(instance + position + pos)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, pos) + pos));
if (c == 0)
{
if (pos > 0)
return Win32.GetModuleHandle(Encoding.ASCII.GetString(buffer, 0, pos));
break;
}
buffer[pos] = c;
}
return IntPtr.Zero;
}
[DllImport("kernel32", SetLastError = true)]
public static extern uint GetFileSize(IntPtr handle, IntPtr lpFileSizeHigh);
[DllImport("kernel32", SetLastError = true)]
public static extern bool GetVolumeInformation(
string pathName,
StringBuilder volumeNameBuffer,
uint volumeNameSize,
ref uint volumeSerialNumber,
ref uint maximumComponentLength,
ref uint fileSystemFlags,
StringBuilder fileSystemNameBuffer,
uint fileSystemNameSize);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(String lpModuleName);
[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 InheritedFromUniqueProcessId;
}
public enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0x00,
ProcessDebugPort = 0x07,
ProcessDebugObjectHandle = 0x1e
}
public enum THREADINFOCLASS
{
ThreadHideFromDebugger = 0x11
}
internal static IntPtr GetProcAddress(IntPtr module, object proc_name)
{
if (module == IntPtr.Zero || proc_name == null)
return IntPtr.Zero;
unsafe
{
byte* ptr = (byte*)module.ToPointer();
PE.IMAGE_DOS_HEADER* dos_header = (PE.IMAGE_DOS_HEADER*)ptr;
if (dos_header->e_magic != PE.IMAGE_DOS_SIGNATURE)
return IntPtr.Zero;
PE.IMAGE_NT_HEADERS* pe_header = (PE.IMAGE_NT_HEADERS*)(ptr + dos_header->e_lfanew);
if (pe_header->Signature != PE.IMAGE_NT_SIGNATURE)
return IntPtr.Zero;
if (pe_header->FileHeader.SizeOfOptionalHeader == 0)
return IntPtr.Zero;
PE.IMAGE_DATA_DIRECTORY* export_table;
byte* optional_header = (byte*)pe_header + Marshal.SizeOf(typeof(PE.IMAGE_NT_HEADERS));
switch (*(UInt16*)(optional_header))
{
case PE.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
export_table = &((PE.IMAGE_OPTIONAL_HEADER32*)(optional_header))->ExportTable;
break;
case PE.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
export_table = &((PE.IMAGE_OPTIONAL_HEADER64*)(optional_header))->ExportTable;
break;
default:
return IntPtr.Zero;
}
if (export_table->VirtualAddress == 0)
return IntPtr.Zero;
uint address = 0;
PE.IMAGE_EXPORT_DIRECTORY* export_directory = (PE.IMAGE_EXPORT_DIRECTORY*)(ptr + export_table->VirtualAddress);
if (proc_name is string)
{
string name = (string)proc_name;
if (export_directory->NumberOfNames > 0)
{
int left_index = 0;
int right_index = (int)export_directory->NumberOfNames - 1;
uint* names = (UInt32*)(ptr + export_directory->AddressOfNames);
while (left_index <= right_index)
{
int cur_index = (left_index + right_index) >> 1;
int cmp = String.CompareOrdinal(name, Marshal.PtrToStringAnsi(new IntPtr(module.ToInt64() + names[cur_index])));
if (cmp < 0)
right_index = cur_index - 1;
else if (cmp > 0)
left_index = cur_index + 1;
else
{
uint ordinal_index = ((UInt16*)(ptr + export_directory->AddressOfNameOrdinals))[cur_index];
if (ordinal_index < export_directory->NumberOfFunctions)
address = ((UInt32*)(ptr + export_directory->AddressOfFunctions))[ordinal_index];
break;
}
}
}
}
else
{
uint ordinal_index = System.Convert.ToUInt32(proc_name) - export_directory->Base;
if (ordinal_index < export_directory->NumberOfFunctions)
address = ((UInt32*)(ptr + export_directory->AddressOfFunctions))[ordinal_index];
}
if (address == 0)
return IntPtr.Zero;
if (address < export_table->VirtualAddress || address >= export_table->VirtualAddress + export_table->Size)
return new IntPtr(module.ToInt64() + address);
string forwarded_name = Marshal.PtrToStringAnsi(new IntPtr(module.ToInt64() + address));
int dot_pos = forwarded_name.IndexOf('.');
if (dot_pos > 0)
{
IntPtr forwarded_module = Win32.GetModuleHandle(forwarded_name.Substring(0, dot_pos));
if (forwarded_name[dot_pos + 1] == '#')
{
uint ordinal;
if (UInt32.TryParse(forwarded_name.Substring(dot_pos + 2), out ordinal))
return GetProcAddress(forwarded_module, ordinal);
}
else
return GetProcAddress(forwarded_module, forwarded_name.Substring(dot_pos + 1));
}
}
return IntPtr.Zero;
}
internal static IntPtr GetProcAddressEnc(IntPtr module, uint position)
{
long instance = Marshal.GetHINSTANCE(typeof(Loader).Module).ToInt64();
var buffer = new byte[100];
for (var pos = 0; pos < buffer.Length; pos++)
{
var c = (byte)(Marshal.ReadByte(new IntPtr(instance + position + pos)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, pos) + pos));
if (c == 0)
{
if (pos > 0)
return GetProcAddress(module, Encoding.ASCII.GetString(buffer, 0, pos));
break;
}
buffer[pos] = c;
}
return IntPtr.Zero;
}
public static uint NtQueryInformationProcess(IntPtr processHandle, Win32.PROCESSINFOCLASS processInformationClass,
out object processInformation, int processInformationLength, out uint returnLength)
{
IntPtr mem = Marshal.AllocHGlobal(processInformationLength);
uint res = _nt_query_information_process(processHandle, processInformationClass, mem, processInformationLength, out returnLength);
if (res == 0)
{
Type type;
switch (processInformationClass)
{
case Win32.PROCESSINFOCLASS.ProcessBasicInformation:
type = typeof(Win32.PROCESS_BASIC_INFORMATION);
break;
case Win32.PROCESSINFOCLASS.ProcessDebugPort:
case Win32.PROCESSINFOCLASS.ProcessDebugObjectHandle:
type = typeof(IntPtr);
break;
default:
type = null;
break;
}
processInformation = Marshal.PtrToStructure(mem, type);
}
else
processInformation = null;
Marshal.FreeHGlobal(mem);
return res;
}
public static uint NtSetInformationThread(IntPtr ThreadHandle, Win32.THREADINFOCLASS ThreadInformationClass, IntPtr ThreadInformation, uint ThreadInformationLength)
{
return _nt_set_information_thread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
}
public static uint EnumSystemFirmwareTables(uint firmwareTableProviderSignature, IntPtr firmwareTableBuffer, uint bufferSize)
{
return _enum_system_firmware_tables(firmwareTableProviderSignature, firmwareTableBuffer, bufferSize);
}
public static uint GetSystemFirmwareTable(uint firmwareTableProviderSignature, uint firmwareTableID, IntPtr firmwareTableBuffer, uint bufferSize)
{
return _get_system_firmware_table(firmwareTableProviderSignature, firmwareTableID, firmwareTableBuffer, bufferSize);
}
public static bool CloseHandle(IntPtr handle)
{
return (_nt_close(handle) == 0);
}
public static IntPtr OpenFile(String FileName, uint DesiredAccess, uint ShareMode)
{
char[] preffix;
if (FileName[0] == '\\' && FileName[1] == '\\')
{
preffix = new char[7];
preffix[0] = '\\';
preffix[1] = '?';
preffix[2] = '?';
preffix[3] = '\\';
preffix[4] = 'U';
preffix[5] = 'N';
preffix[6] = 'C';
}
else
{
preffix = new char[4];
preffix[0] = '\\';
preffix[1] = '?';
preffix[2] = '?';
preffix[3] = '\\';
}
var str = new UNICODE_STRING(new string(preffix) + FileName);
var objectAttributes = new OBJECT_ATTRIBUTES(str, 0);
try
{
IntPtr res;
IO_STATUS_BLOCK io_status_block;
if (_nt_open_file(out res, DesiredAccess | (uint)Values.SYNCHRONIZE | (uint)Values.FILE_READ_ATTRIBUTES, ref objectAttributes, out io_status_block, ShareMode, (uint)Values.FILE_SYNCHRONOUS_IO_NONALERT | (uint)Values.FILE_NON_DIRECTORY_FILE) == 0)
return res;
}
finally
{
str.Dispose();
objectAttributes.Dispose();
}
return InvalidHandleValue;
}
public static bool VirtualProtect(IntPtr BaseAddress, UIntPtr RegionSize, MemoryProtection Protect, out MemoryProtection OldProtect)
{
return (_nt_protect_virtual_memory(CurrentProcess, ref BaseAddress, ref RegionSize, Protect, out OldProtect) == 0);
}
public static IntPtr VirtualAlloc(IntPtr BaseAddress, UIntPtr RegionSize, AllocationType AllocationType, MemoryProtection Protect)
{
if (_nt_allocate_virtual_memory(CurrentProcess, ref BaseAddress, IntPtr.Zero, ref RegionSize, AllocationType, Protect) == 0)
return BaseAddress;
return IntPtr.Zero;
}
public static bool VirtualFree(IntPtr BaseAddress, UIntPtr RegionSize, FreeType FreeType)
{
return (_nt_free_virtual_memory(CurrentProcess, ref BaseAddress, ref RegionSize, FreeType) == 0);
}
public static IntPtr CreateFileMapping(IntPtr FileHandle, IntPtr Attributes, MemoryProtection Protect, uint MaximumSizeLow, uint MaximumSizeHigh, String Name)
{
uint desiredAccess = (uint)Values.SECTION_MAP_READ;
if (Protect == MemoryProtection.ReadWrite)
desiredAccess |= (uint)Values.SECTION_MAP_WRITE;
else if (Protect == MemoryProtection.ExecuteReadWrite)
desiredAccess |= (uint)Values.SECTION_MAP_WRITE | (uint)Values.SECTION_MAP_EXECUTE;
else if (Protect == MemoryProtection.ExecuteRead)
desiredAccess |= (uint)Values.SECTION_MAP_EXECUTE;
IntPtr res;
var str = new UNICODE_STRING(null);
var objectAttributes = new OBJECT_ATTRIBUTES(str, 0);
try
{
var size = new LARGE_INTEGER();
size.LowPart = MaximumSizeLow;
size.HighPart = MaximumSizeHigh;
if (_nt_create_section(out res, desiredAccess, ref objectAttributes, ref size, Protect, (uint)Values.SEC_COMMIT, FileHandle) == 0)
return res;
}
finally
{
str.Dispose();
objectAttributes.Dispose();
}
return NullHandle;
}
public static IntPtr MapViewOfFile(IntPtr hFileMappingObject, MapAccess dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, IntPtr dwNumBytesToMap)
{
return _map_view_of_file(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumBytesToMap);
}
public static bool UnmapViewOfFile(IntPtr BaseAddress)
{
return (_nt_unmap_view_of_section(CurrentProcess, BaseAddress) == 0);
}
public static bool IsDebuggerPresent()
{
object obj;
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessBasicInformation, out obj, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out _) == 0)
{
if (Marshal.ReadByte(new IntPtr(((PROCESS_BASIC_INFORMATION)obj).PebBaseAddress.ToInt64() + 2)) != 0) // PEB.BeingDebugged
return true;
}
return false;
}
public static bool CheckRemoteDebuggerPresent()
{
object obj;
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessDebugPort, out obj, IntPtr.Size, out _) == 0)
{
if ((IntPtr)obj != IntPtr.Zero)
return true;
}
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessDebugObjectHandle, out _, IntPtr.Size, out _) == 0)
return true;
return false;
}
public static void ShowMessage(string Text, string Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon)
{
IntPtr[] p = new IntPtr[4];
var strText = new UNICODE_STRING(Text);
var strCaption = new UNICODE_STRING(Caption);
p[0] = Marshal.AllocHGlobal(Marshal.SizeOf(strText));
p[1] = Marshal.AllocHGlobal(Marshal.SizeOf(strCaption));
try
{
Marshal.StructureToPtr(strText, p[0], false);
Marshal.StructureToPtr(strCaption, p[1], false);
p[2] = new IntPtr((uint)Buttons | (uint)Icon);
p[3] = new IntPtr(-1);
_nt_raise_hard_error(0x40000018 | 0x10000000, 4, 3, p, 0, out _);
}
finally
{
strText.Dispose();
strCaption.Dispose();
Marshal.FreeHGlobal(p[0]);
Marshal.FreeHGlobal(p[1]);
}
}
}
internal class PE
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_DOS_HEADER
{
public UInt16 e_magic;
public UInt16 e_cblp;
public UInt16 e_cp;
public UInt16 e_crlc;
public UInt16 e_cparhdr;
public UInt16 e_minalloc;
public UInt16 e_maxalloc;
public UInt16 e_ss;
public UInt16 e_sp;
public UInt16 e_csum;
public UInt16 e_ip;
public UInt16 e_cs;
public UInt16 e_lfarlc;
public UInt16 e_ovno;
public UInt16 e_res_0;
public UInt16 e_res_1;
public UInt16 e_res_2;
public UInt16 e_res_3;
public UInt16 e_oemid;
public UInt16 e_oeminfo;
public UInt16 e_res2_0;
public UInt16 e_res2_1;
public UInt16 e_res2_2;
public UInt16 e_res2_3;
public UInt16 e_res2_4;
public UInt16 e_res2_5;
public UInt16 e_res2_6;
public UInt16 e_res2_7;
public UInt16 e_res2_8;
public UInt16 e_res2_9;
public UInt32 e_lfanew;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_FILE_HEADER
{
public UInt16 Machine;
public UInt16 NumberOfSections;
public UInt32 TimeDateStamp;
public UInt32 PointerToSymbolTable;
public UInt32 NumberOfSymbols;
public UInt16 SizeOfOptionalHeader;
public UInt16 Characteristics;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_NT_HEADERS
{
public UInt32 Signature;
public IMAGE_FILE_HEADER FileHeader;
//IMAGE_OPTIONAL_HEADER OptionalHeader;
}
public const UInt16 IMAGE_DOS_SIGNATURE = 0x5A4D;
public const UInt32 IMAGE_NT_SIGNATURE = 0x00004550;
public const UInt16 IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
public const UInt16 IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_DATA_DIRECTORY
{
public UInt32 VirtualAddress;
public UInt32 Size;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER32
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt32 BaseOfData;
public UInt32 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt32 SizeOfStackReserve;
public UInt32 SizeOfStackCommit;
public UInt32 SizeOfHeapReserve;
public UInt32 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY ExportTable;
public IMAGE_DATA_DIRECTORY ImportTable;
public IMAGE_DATA_DIRECTORY ResourceTable;
public IMAGE_DATA_DIRECTORY ExceptionTable;
public IMAGE_DATA_DIRECTORY CertificateTable;
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
public IMAGE_DATA_DIRECTORY Debug;
public IMAGE_DATA_DIRECTORY Architecture;
public IMAGE_DATA_DIRECTORY GlobalPtr;
public IMAGE_DATA_DIRECTORY TLSTable;
public IMAGE_DATA_DIRECTORY LoadConfigTable;
public IMAGE_DATA_DIRECTORY BoundImport;
public IMAGE_DATA_DIRECTORY IAT;
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
public IMAGE_DATA_DIRECTORY Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER64
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt64 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt64 SizeOfStackReserve;
public UInt64 SizeOfStackCommit;
public UInt64 SizeOfHeapReserve;
public UInt64 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY ExportTable;
public IMAGE_DATA_DIRECTORY ImportTable;
public IMAGE_DATA_DIRECTORY ResourceTable;
public IMAGE_DATA_DIRECTORY ExceptionTable;
public IMAGE_DATA_DIRECTORY CertificateTable;
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
public IMAGE_DATA_DIRECTORY Debug;
public IMAGE_DATA_DIRECTORY Architecture;
public IMAGE_DATA_DIRECTORY GlobalPtr;
public IMAGE_DATA_DIRECTORY TLSTable;
public IMAGE_DATA_DIRECTORY LoadConfigTable;
public IMAGE_DATA_DIRECTORY BoundImport;
public IMAGE_DATA_DIRECTORY IAT;
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
public IMAGE_DATA_DIRECTORY Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_EXPORT_DIRECTORY
{
public UInt32 Characteristics;
public UInt32 TimeDateStamp;
public UInt16 MajorVersion;
public UInt16 MinorVersion;
public UInt32 Name;
public UInt32 Base;
public UInt32 NumberOfFunctions;
public UInt32 NumberOfNames;
public UInt32 AddressOfFunctions;
public UInt32 AddressOfNames;
public UInt32 AddressOfNameOrdinals;
}
}
}