internal Enumerations.MemoryProtectionType Invoke(SafeProcessHandle processHandle, IntPtr baseAddress, int protectionSize, Enumerations.MemoryProtectionType newProtectionType) { // Store the base address of the memory region to protect in a buffer var baseAddressBuffer = MemoryTools.StoreStructureInBuffer(baseAddress); // Store the protection size in a buffer var protectionSizeBuffer = MemoryTools.StoreStructureInBuffer(protectionSize); // Initialise a buffer to store the returned old protection of the memory region var oldProtectionBuffer = MemoryTools.AllocateMemoryForBuffer(sizeof(ulong)); // Perform the syscall var syscallResult = _ntProtectVirtualMemoryDelegate(processHandle, baseAddressBuffer, protectionSizeBuffer, newProtectionType, oldProtectionBuffer); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to protect memory in the target process", syscallResult); } // Marshal the returned old protection of the memory region from the buffer var oldProtection = (Enumerations.MemoryProtectionType)Marshal.PtrToStructure <ulong>(oldProtectionBuffer); MemoryTools.FreeMemoryForBuffer(baseAddressBuffer); MemoryTools.FreeMemoryForBuffer(protectionSizeBuffer); MemoryTools.FreeMemoryForBuffer(oldProtectionBuffer); return(oldProtection); }
internal TDelegate CreateDelegateForSyscall <TDelegate>() where TDelegate : class { // Get the address of the function var functionAddress = _ntDllAddress + (int)_ntDllFunctions.Find(function => function.Name == typeof(TDelegate).Name.Replace("Definition", "")).Offset; // Copy the first 8 bytes of the function var functionBytes = new byte[8]; Marshal.Copy(functionAddress, functionBytes, 0, 8); // Retrieve the syscall index from the bytes var syscallIndexBytes = Environment.Is64BitProcess ? functionBytes.Skip(4).Take(4) : functionBytes.Skip(1).Take(4); var syscallIndex = BitConverter.ToUInt32(syscallIndexBytes.ToArray(), 0); // Create the shellcode used to perform the syscall var shellcode = Environment.Is64BitProcess ? SyscallX64.GetShellcode(syscallIndex) : SyscallX86.GetShellcode(syscallIndex); // Store the shellcode in a buffer var shellcodeBuffer = MemoryTools.AllocateMemoryForBuffer(shellcode.Length); _shellcodeAddresses.Add(shellcodeBuffer); Marshal.Copy(shellcode, 0, shellcodeBuffer, shellcode.Length); // Create a delegate to perform the syscall return(Marshal.GetDelegateForFunctionPointer <TDelegate>(shellcodeBuffer)); }
internal SafeThreadHandle Invoke(SafeProcessHandle processHandle, IntPtr startAddress, IntPtr parameter) { // Initialise a buffer to store the returned thread handle var threadHandleBuffer = MemoryTools.AllocateMemoryForBuffer(IntPtr.Size); // Perform the syscall const Enumerations.ThreadAccessMask desiredAccess = Enumerations.ThreadAccessMask.SpecificRightsAll | Enumerations.ThreadAccessMask.StandardRightsAll; var syscallResult = _ntCreateThreadExDelegate(threadHandleBuffer, desiredAccess, IntPtr.Zero, processHandle, startAddress, parameter, Enumerations.ThreadCreationType.HideFromDebugger, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to create a thread in the target process", syscallResult); } // Marshal the returned thread handle from the buffer var threadHandle = new SafeThreadHandle(Marshal.PtrToStructure <IntPtr>(threadHandleBuffer), true); MemoryTools.FreeMemoryForBuffer(threadHandleBuffer); return(threadHandle); }
internal IntPtr Invoke(SafeProcessHandle processHandle, int allocationSize, Enumerations.MemoryProtectionType protectionType) { // Initialise a buffer to store the returned address of the allocated memory region var memoryRegionAddressBuffer = MemoryTools.AllocateMemoryForBuffer(IntPtr.Size); // Store the size of the allocation in a buffer var allocationSizeBuffer = MemoryTools.StoreStructureInBuffer(allocationSize); // Perform the syscall const Enumerations.MemoryAllocationType allocationType = Enumerations.MemoryAllocationType.Commit | Enumerations.MemoryAllocationType.Reserve; var syscallResult = _ntAllocateVirtualMemoryDelegate(processHandle, memoryRegionAddressBuffer, 0, allocationSizeBuffer, allocationType, protectionType); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory in the target process", syscallResult); } // Marshal the returned address of the memory region from the buffer var memoryRegionAddress = Marshal.PtrToStructure <IntPtr>(memoryRegionAddressBuffer); MemoryTools.FreeMemoryForBuffer(memoryRegionAddressBuffer); MemoryTools.FreeMemoryForBuffer(allocationSizeBuffer); return(memoryRegionAddress); }
internal IntPtr Invoke(SafeProcessHandle processHandle, IntPtr baseAddress, int bytesToRead) { // Initialise a buffer to store the returned bytes read var bytesReadBuffer = MemoryTools.AllocateMemoryForBuffer(bytesToRead); // Perform the syscall var syscallResult = _ntReadVirtualMemoryDelegate(processHandle, baseAddress, bytesReadBuffer, (ulong)bytesToRead, IntPtr.Zero); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to read memory from the target process", syscallResult); } return(bytesReadBuffer); }
internal IntPtr Invoke(SafeProcessHandle processHandle, IntPtr baseAddress) { // Initialise a buffer to store the returned memory basic information structure in var memoryBasicInformationBuffer = MemoryTools.AllocateMemoryForBuffer(Marshal.SizeOf <Structures.MemoryBasicInformation>()); // Perform the syscall var syscallResult = _ntQueryVirtualMemoryDelegate(processHandle, baseAddress, Enumerations.MemoryInformationClass.BasicInformation, memoryBasicInformationBuffer, (ulong)Marshal.SizeOf <Structures.MemoryBasicInformation>(), IntPtr.Zero); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to query memory in the target process", syscallResult); } return(memoryBasicInformationBuffer); }
internal IntPtr Invoke(SafeProcessHandle processHandle, Enumerations.ProcessInformationClass processInformationClass) { // Initialise a buffer to store the returned process information structure var bufferSize = processInformationClass == Enumerations.ProcessInformationClass.BasicInformation ? Marshal.SizeOf <Structures.ProcessBasicInformation>() : sizeof(ulong); var processInformationBuffer = MemoryTools.AllocateMemoryForBuffer(bufferSize); // Perform the syscall var syscallResult = _ntQueryInformationProcessDelegate(processHandle, processInformationClass, processInformationBuffer, (ulong)bufferSize, IntPtr.Zero); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to query the information of the target process", syscallResult); } return(processInformationBuffer); }
internal SafeProcessHandle Invoke(int processId) { // Initialise a buffer to store the returned process handle var processHandleBuffer = MemoryTools.AllocateMemoryForBuffer(IntPtr.Size); // Store an empty object attributes structure in a buffer var objectAttributesBuffer = MemoryTools.StoreStructureInBuffer(new Structures.ObjectAttributes()); // Store a client id structure in a buffer var clientId = new Structures.ClientId { UniqueProcess = new IntPtr(processId), UniqueThread = IntPtr.Zero }; var clientIdBuffer = MemoryTools.StoreStructureInBuffer(clientId); // Perform the syscall var syscallResult = _ntOpenProcessDelegate(processHandleBuffer, Enumerations.ProcessAccessMask.AllAccess, objectAttributesBuffer, clientIdBuffer); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to open a handle to the target process", syscallResult); } // Marshal the returned process handle from the buffer var processHandle = new SafeProcessHandle(Marshal.PtrToStructure <IntPtr>(processHandleBuffer), true); MemoryTools.FreeMemoryForBuffer(processHandleBuffer); MemoryTools.FreeMemoryForBuffer(objectAttributesBuffer); MemoryTools.FreeMemoryForBuffer(clientIdBuffer); return(processHandle); }