mirror of
https://github.com/3xpl01tc0d3r/ProcessInjection
synced 2026-06-06 15:14:27 +00:00
315 lines
13 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|