Files
2025-08-02 01:43:11 +05:30

315 lines
13 KiB
C#

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static ProcessInjection.Native.Enum;
using static ProcessInjection.Native.Delegates;
using static ProcessInjection.Native.Structs;
namespace ProcessInjection.DInvoke
{
public static class Native
{
public static NTSTATUS NtCreateThreadEx(ref IntPtr threadHandle, ACCESS_MASK desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr startAddress, IntPtr parameter, bool createSuspended, int stackZeroBits, int sizeOfStack, int maximumStackSize, IntPtr attributeList)
{
object[] funcargs =
{
threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits,
sizeOfStack, maximumStackSize, attributeList
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtCreateThreadEx",
typeof(NtCreateThreadEx), ref funcargs);
threadHandle = (IntPtr)funcargs[0];
return retValue;
}
public static NTSTATUS NtCreateSection(ref IntPtr sectionHandle, uint desiredAccess, IntPtr objectAttributes, ref ulong maximumSize, uint sectionPageProtection, uint allocationAttributes, IntPtr fileHandle)
{
object[] funcargs =
{
sectionHandle, desiredAccess, objectAttributes, maximumSize, sectionPageProtection, allocationAttributes, fileHandle
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtCreateSection", typeof(NtCreateSection), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Unable to create section, " + retValue);
sectionHandle = (IntPtr)funcargs[0];
maximumSize = (ulong)funcargs[3];
return retValue;
}
public static NTSTATUS NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr)
{
object[] funcargs =
{
hProc, baseAddr
};
var result = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtUnmapViewOfSection", typeof(NtUnmapViewOfSection), ref funcargs);
return result;
}
public static NTSTATUS NtMapViewOfSection(IntPtr sectionHandle, IntPtr processHandle, ref IntPtr baseAddress, IntPtr zeroBits, IntPtr commitSize, IntPtr sectionOffset, ref ulong viewSize, uint inheritDisposition, uint allocationType, uint win32Protect)
{
object[] funcargs =
{
sectionHandle, processHandle, baseAddress, zeroBits, commitSize, sectionOffset, viewSize, inheritDisposition, allocationType,
win32Protect
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtMapViewOfSection", typeof(NtMapViewOfSection), ref funcargs);
if (retValue != NTSTATUS.Success && retValue != NTSTATUS.ImageNotAtBase)
throw new InvalidOperationException("Unable to map view of section, " + retValue);
baseAddress = (IntPtr)funcargs[2];
viewSize = (ulong)funcargs[6];
return retValue;
}
public static void RtlInitUnicodeString(ref UNICODE_STRING destinationString, [MarshalAs(UnmanagedType.LPWStr)] string sourceString)
{
object[] funcargs =
{
destinationString, sourceString
};
DynamicInvoke.DynamicApiInvoke("ntdll.dll", "RtlInitUnicodeString", typeof(RtlInitUnicodeString), ref funcargs);
destinationString = (UNICODE_STRING)funcargs[0];
}
public static NTSTATUS LdrLoadDll(IntPtr pathToFile, uint dwFlags, ref UNICODE_STRING moduleFileName, ref IntPtr moduleHandle)
{
object[] funcargs =
{
pathToFile, dwFlags, moduleFileName, moduleHandle
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "LdrLoadDll", typeof(LdrLoadDll), ref funcargs);
moduleHandle = (IntPtr)funcargs[3];
return retValue;
}
public static void RtlZeroMemory(IntPtr destination, int length)
{
object[] funcargs =
{
destination, length
};
DynamicInvoke.DynamicApiInvoke("ntdll.dll", "RtlZeroMemory", typeof(RtlZeroMemory), ref funcargs);
}
public static NTSTATUS NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo)
{
int processInformationLength;
uint retLen = 0;
switch (processInfoClass)
{
case PROCESSINFOCLASS.ProcessWow64Information:
pProcInfo = Marshal.AllocHGlobal(IntPtr.Size);
RtlZeroMemory(pProcInfo, IntPtr.Size);
processInformationLength = IntPtr.Size;
break;
case PROCESSINFOCLASS.ProcessBasicInformation:
var pbi = new PROCESS_BASIC_INFORMATION();
pProcInfo = Marshal.AllocHGlobal(Marshal.SizeOf(pbi));
RtlZeroMemory(pProcInfo, Marshal.SizeOf(pbi));
Marshal.StructureToPtr(pbi, pProcInfo, true);
processInformationLength = Marshal.SizeOf(pbi);
break;
default:
throw new InvalidOperationException($"Invalid ProcessInfoClass: {processInfoClass}");
}
object[] funcargs =
{
hProcess, processInfoClass, pProcInfo, processInformationLength, retLen
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtQueryInformationProcess", typeof(NtQueryInformationProcess), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new UnauthorizedAccessException("Access is denied.");
pProcInfo = (IntPtr)funcargs[2];
return retValue;
}
public static bool NtQueryInformationProcessWow64Information(IntPtr hProcess)
{
var retValue = NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessWow64Information, out var pProcInfo);
if (retValue != NTSTATUS.Success)
throw new UnauthorizedAccessException("Access is denied.");
return Marshal.ReadIntPtr(pProcInfo) != IntPtr.Zero;
}
public static PROCESS_BASIC_INFORMATION NtQueryInformationProcessBasicInformation(IntPtr hProcess)
{
var retValue = NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, out var pProcInfo);
if (retValue != NTSTATUS.Success)
throw new UnauthorizedAccessException("Access is denied.");
return (PROCESS_BASIC_INFORMATION)Marshal.PtrToStructure(pProcInfo, typeof(PROCESS_BASIC_INFORMATION));
}
public static IntPtr NtAllocateVirtualMemory(IntPtr processHandle, ref IntPtr baseAddress, IntPtr zeroBits, ref IntPtr regionSize, uint allocationType, uint protect)
{
object[] funcargs =
{
processHandle, baseAddress, zeroBits, regionSize, allocationType, protect
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtAllocateVirtualMemory", typeof(NtAllocateVirtualMemory), ref funcargs);
switch (retValue)
{
case NTSTATUS.AccessDenied:
throw new UnauthorizedAccessException("Access is denied.");
case NTSTATUS.AlreadyCommitted:
throw new InvalidOperationException("The specified address range is already committed.");
case NTSTATUS.CommitmentLimit:
throw new InvalidOperationException("Your system is low on virtual memory.");
case NTSTATUS.ConflictingAddresses:
throw new InvalidOperationException("The specified address range conflicts with the address space.");
case NTSTATUS.InsufficientResources:
throw new InvalidOperationException("Insufficient system resources exist to complete the API call.");
case NTSTATUS.InvalidHandle:
throw new InvalidOperationException("An invalid HANDLE was specified.");
case NTSTATUS.InvalidPageProtection:
throw new InvalidOperationException("The specified page protection was not valid.");
case NTSTATUS.NoMemory:
throw new InvalidOperationException("Not enough virtual memory or paging file quota is available to complete the specified operation.");
case NTSTATUS.ObjectTypeMismatch:
throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request.");
}
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("An attempt was made to duplicate an object handle into or out of an exiting process.");
baseAddress = (IntPtr)funcargs[1];
return baseAddress;
}
public static void NtFreeVirtualMemory(IntPtr processHandle, ref IntPtr baseAddress, ref IntPtr regionSize, uint freeType)
{
object[] funcargs =
{
processHandle, baseAddress, regionSize, freeType
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtFreeVirtualMemory", typeof(NtFreeVirtualMemory), ref funcargs);
switch (retValue)
{
case NTSTATUS.AccessDenied:
throw new UnauthorizedAccessException("Access is denied.");
case NTSTATUS.InvalidHandle:
throw new InvalidOperationException("An invalid HANDLE was specified.");
}
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request.");
}
public static uint NtProtectVirtualMemory(IntPtr processHandle, ref IntPtr baseAddress, ref IntPtr regionSize, uint newProtect)
{
uint oldProtect = 0;
object[] funcargs =
{
processHandle, baseAddress, regionSize, newProtect, oldProtect
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtProtectVirtualMemory", typeof(NtProtectVirtualMemory), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Failed to change memory protection, " + retValue);
oldProtect = (uint)funcargs[4];
return oldProtect;
}
public static uint NtWriteVirtualMemory(IntPtr processHandle, IntPtr baseAddress, IntPtr buffer, uint bufferLength)
{
uint bytesWritten = 0;
object[] funcargs =
{
processHandle, baseAddress, buffer, bufferLength, bytesWritten
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "NtWriteVirtualMemory", typeof(NtWriteVirtualMemory), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Failed to write memory, " + retValue);
bytesWritten = (uint)funcargs[4];
return bytesWritten;
}
public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr functionName, IntPtr ordinal, ref IntPtr functionAddress)
{
object[] funcargs =
{
hModule, functionName, ordinal, functionAddress
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "LdrGetProcedureAddress", typeof(LdrGetProcedureAddress), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Failed get procedure address, " + retValue);
functionAddress = (IntPtr)funcargs[3];
return functionAddress;
}
public static void RtlGetVersion(ref OSVERSIONINFOEX versionInformation)
{
object[] funcargs =
{
versionInformation
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke("ntdll.dll", "RtlGetVersion", typeof(RtlGetVersion), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Failed get procedure address, " + retValue);
versionInformation = (OSVERSIONINFOEX)funcargs[0];
}
public static IntPtr NtOpenFile(ref IntPtr fileHandle, FileAccessFlags desiredAccess, ref OBJECT_ATTRIBUTES objectAttributes, ref IO_STATUS_BLOCK ioStatusBlock, FileShareFlags shareAccess, FileOpenFlags openOptions)
{
object[] funcargs =
{
fileHandle, desiredAccess, objectAttributes, ioStatusBlock, shareAccess, openOptions
};
var retValue = (NTSTATUS)DynamicInvoke.DynamicApiInvoke(@"ntdll.dll", @"NtOpenFile", typeof(NtOpenFile), ref funcargs);
if (retValue != NTSTATUS.Success)
throw new InvalidOperationException("Failed to open file, " + retValue);
fileHandle = (IntPtr)funcargs[0];
return fileHandle;
}
}
}