825 lines
28 KiB
C#
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;
|
||
|
}
|
||
|
}
|
||
|
}
|