Beispiel #1
0
        public static bool TryGetParentId(this Process process, out int processId)
        {
            processId = 0;
            var handle = Kernel32.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, process.Id);

            if (handle == IntPtr.Zero)
            {
                return(false);
            }

            try
            {
                var info   = new PROCESS_BASIC_INFORMATION();
                int status = Ntdll.NtQueryInformationProcess(handle, 0, ref info, Marshal.SizeOf(info), out var returnLength);
                if (status != 0)
                {
                    return(false);
                }

                processId = info.InheritedFromUniqueProcessId.ToInt32();
                return(true);
            }
            finally
            {
                Kernel32.CloseHandle(handle);
            }
        }
Beispiel #2
0
        public void TestNtOpenProcess()
        {
            if (Environment.Is64BitProcess)
            {
                var syscall = new Syscall <Delegates.OpenProcess64>();

                var status = syscall.Method(out var processHandle, AccessMask.ProcessAllAccess, new ObjectAttributes64(), new ClientId64(_process.Id));

                if (status != NtStatus.Success)
                {
                    throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
                }

                Assert.False(processHandle.IsInvalid);
            }

            else
            {
                var syscall = new Syscall <Delegates.OpenProcess32>();

                var status = syscall.Method(out var processHandle, AccessMask.ProcessAllAccess, new ObjectAttributes32(), new ClientId32(_process.Id));

                if (status != NtStatus.Success)
                {
                    throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
                }

                Assert.False(processHandle.IsInvalid);
            }
        }
Beispiel #3
0
        public IntPtr GetThreadStartAddress(int ThreadId)
        {
            var hThread = Kernel32.OpenThread(ThreadAccess.QUERY_INFORMATION, false, ThreadId);

            if (hThread == IntPtr.Zero)
            {
                throw new MemoryException("Failed to open thread");
            }
            var buf = new byte[4];

            try
            {
                var result = Ntdll.NtQueryInformationThread(hThread,
                                                            ThreadInfoClass.ThreadQuerySetWin32StartAddress,
                                                            buf, buf.Length, IntPtr.Zero);
                if (result != 0)
                {
                    throw new MemoryException("NtQueryInformationThread failed; NTSTATUS = {0:X8}", result);
                }
                return(new IntPtr(BitConverter.ToInt32(buf, 0)));
            }
            finally
            {
                Kernel32.CloseHandle(hThread);
            }
        }
Beispiel #4
0
        private void ExecuteShellcode(Span <byte> shellcodeBytes)
        {
            // Write the shellcode into the process

            var shellcodeAddress = Memory.AllocateBuffer(shellcodeBytes.Length, ProtectionType.ExecuteRead);

            try
            {
                Memory.WriteSpan(shellcodeAddress, shellcodeBytes);

                // Create a thread to execute the shellcode

                var status = Ntdll.RtlCreateUserThread(Process.SafeHandle, IntPtr.Zero, false, 0, 0, 0, shellcodeAddress, IntPtr.Zero, out var threadHandle, IntPtr.Zero);

                if (status != NtStatus.Success)
                {
                    throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
                }

                using (threadHandle)
                {
                    if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)
                    {
                        throw new Win32Exception();
                    }
                }
            }

            finally
            {
                Memory.FreeBuffer(shellcodeAddress);
            }
        }
Beispiel #5
0
        public Result <string> GetLinkTarget()
        {
            var type = NtdllHelper.GetObjectType(Name);

            if (type != "SymbolicLink")
            {
                return(Result <string> .Failed("Not a symbolic link"));
            }

            var objectAttributes = new OBJECT_ATTRIBUTES(Name, 0);
            var status           = Ntdll.NtOpenSymbolicLinkObject(
                out var linkHandle,
                ACCESS_MASK.GENERIC_READ,
                ref objectAttributes);

            if (status < 0)
            {
                return(Result <string> .Failed("Open file failed with status " + status));
            }

            using (linkHandle)
            {
                var targetBuffer = new UNICODE_STRING(new string(' ', 512));
                status = Ntdll.NtQuerySymbolicLinkObject(
                    linkHandle,
                    ref targetBuffer,
                    out var len);
                return(status < 0
                                        ? Result <string> .Failed("Query link failed with status " + status)
                                        : Result <string> .Succeeded(targetBuffer.ToString()));
            }
        }
Beispiel #6
0
        public MemoryPointer GetPebAddress()
        {
            ProcessBasicInformation pbi = new ProcessBasicInformation();

            Ntdll.NtQueryInformationProcess(NativeHandle, ProcessInformationClass.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), out int _);

            return(new InternalMemoryPointer(pbi.PebBaseAddress));
        }
Beispiel #7
0
        public Download(string url, string fileName, int crc32, long length, Action <bool, string> callback)
        {
            if (!Directory.Exists(Path.GetDirectoryName(fileName)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(fileName));
            }
            int lastCrc32 = 0;

            if (File.Exists(fileName))
            {
                try
                {
                    BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open));
                    int          size;
                    byte[]       buffer = new byte[512];
                    while ((size = reader.Read(buffer, 0, 512)) > 0)
                    {
                        lastCrc32 = Ntdll.RtlComputeCrc32(lastCrc32, buffer, (uint)size);
                    }
                    reader.Close();
                    if (lastCrc32 == crc32)
                    {
                        Close();
                        callback(true, fileName);
                        return;
                    }
                }
                catch { }
            }
            InitializeComponent();
            textBox2.Text     = Path.GetFullPath(fileName);
            label6.Text       = "0B out of " + Unit.AutoScale(length, "B");
            request           = (HttpWebRequest)HttpWebRequest.Create(url);
            request.UserAgent = Headers.DefaultUserAgent;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (Exception ex)
            {
                Close();
                System.Windows.Forms.MessageBox.Show("Unable to connect to server:\n\n" + ex.Message, "Download", MessageBoxButtons.OK, MessageBoxIcon.Error);
                callback(false, fileName);
                return;
            }

            textBox1.Text = response.ResponseUri.AbsoluteUri;
            this.fileName = fileName;
            this.crc32    = crc32;
            this.length   = length;
            this.callback = callback;
            Show();
            timer.AutoReset = true;
            timer.Interval  = 1000;
            timer.Elapsed  += timer_Elapsed;
            timer.Start();
            Receive();
        }
Beispiel #8
0
        private static (PlatformOS, Version) GetWindowsInfo()
        {
            Ntdll.RTL_OSVERSIONINFOEX osvi = new Ntdll.RTL_OSVERSIONINFOEX();
            osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);

            return(Ntdll.RtlGetVersion(out osvi) == 0
                ? (PlatformOS.Windows, new Version((int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion))
                : (PlatformOS.Windows, new Version(0, 0)));
        }
Beispiel #9
0
            public static void NtQueryObject(IntPtr Handle, out OBJECT_NAME_INFORMATION ObjectNameInformation)
            {
                IntPtr buffer = Marshal.AllocHGlobal(1024);

                try{
                    Ntdll.NtQueryObject(Handle, 1, buffer, 1024);
                    ObjectNameInformation = Marshal.PtrToStructure <Ntdll.OBJECT_NAME_INFORMATION>(buffer);
                }finally{
                    Marshal.FreeHGlobal(buffer);
                }
            }
Beispiel #10
0
        private int GetParentProcessId(Process process)
        {
            var processBasicInformation = new smPROCESS_BASIC_INFORMATION();
            var result = Ntdll.NtQueryInformationProcess(process.Handle, Ntdll.ProcessBasicInformation, ref processBasicInformation, Marshal.SizeOf(processBasicInformation), out var returnLength);

            _trace.TraceVerbose("{0} returned {1}", nameof(Ntdll.NtQueryInformationProcess), result);

            var parentPid = processBasicInformation.InheritedFromUniqueProcessId.ToInt32();

            _trace.TraceVerbose("Parent PID: {0}", parentPid);
            return(parentPid);
        }
    internal static T QueryInformation <T>(this Process process, ProcessInformationType informationType) where T : unmanaged
    {
        Span <byte> informationBytes = stackalloc byte[Unsafe.SizeOf <T>()];

        var status = Ntdll.NtQueryInformationProcess(process.SafeHandle, informationType, out informationBytes[0], informationBytes.Length, IntPtr.Zero);

        if (status != NtStatus.Success)
        {
            throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
        }

        return(MemoryMarshal.Read <T>(informationBytes));
    }
Beispiel #12
0
        internal static T QueryInformation <T>(this Process process, ProcessInformationClass informationClass) where T : unmanaged
        {
            Span <byte> informationBlock = stackalloc byte[Unsafe.SizeOf <T>()];

            var ntStatus = Ntdll.NtQueryInformationProcess(process.SafeHandle, informationClass, out informationBlock[0], informationBlock.Length, out _);

            if (ntStatus != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(ntStatus));
            }

            return(MemoryMarshal.Read <T>(informationBlock));
        }
Beispiel #13
0
        private Tuple <IntPtr, IntPtr> ReadPeb(SafeProcessHandle processHandle)
        {
            if (_isWow64)
            {
                // Query the remote process for the address of the WOW64 PEB

                var processInformationBuffer = Marshal.AllocHGlobal(sizeof(long));

                var ntStatus = Ntdll.NtQueryInformationProcess(processHandle, ProcessInformationClass.Wow64Information, processInformationBuffer, sizeof(long), IntPtr.Zero);

                if (ntStatus != NtStatus.Success)
                {
                    throw new PInvokeException("Failed to call NtQueryInformationProcess", ntStatus);
                }

                var pebAddress = Marshal.ReadIntPtr(processInformationBuffer);

                Marshal.FreeHGlobal(processInformationBuffer);

                // Read the WOW64 PEB

                var peb = _memoryManager.ReadVirtualMemory <Peb32>(pebAddress);

                return(new Tuple <IntPtr, IntPtr>((IntPtr)peb.ApiSetMap, (IntPtr)peb.Ldr));
            }

            else
            {
                // Query the remote process for the address of the PEB

                var processInformationBuffer = Marshal.AllocHGlobal(Marshal.SizeOf <ProcessBasicInformation>());

                var ntStatus = Ntdll.NtQueryInformationProcess(processHandle, ProcessInformationClass.BasicInformation, processInformationBuffer, Marshal.SizeOf <ProcessBasicInformation>(), IntPtr.Zero);

                if (ntStatus != NtStatus.Success)
                {
                    throw new PInvokeException("Failed to call NtQueryInformationProcess", ntStatus);
                }

                var pebAddress = Marshal.PtrToStructure <ProcessBasicInformation>(processInformationBuffer).PebBaseAddress;

                Marshal.FreeHGlobal(processInformationBuffer);

                // Read the WOW64 PEB

                var peb = _memoryManager.ReadVirtualMemory <Peb64>(pebAddress);

                return(new Tuple <IntPtr, IntPtr>((IntPtr)peb.ApiSetMap, (IntPtr)peb.Ldr));
            }
        }
Beispiel #14
0
        internal void Call(IntPtr remoteDllAddress)
        {
            if (_injectionMethod == InjectionMethod.ManualMap || _injectionFlags.HasFlag(InjectionFlags.HideDllFromPeb))
            {
                // Call the entry point of the DLL with DllProcessDetach

                if (!_process.CallFunction <bool>(CallingConvention.StdCall, remoteDllAddress + _peImage.PeHeaders.PEHeader.AddressOfEntryPoint, (long)remoteDllAddress, Constants.DllProcessDetach, 0))
                {
                    throw new RemoteFunctionCallException("Failed to call the entry point of the DLL");
                }

                // Remove the entry for the DLL from the LdrpInvertedFunctionTable

                var rtRemoveInvertedFunctionTableAddress = _process.PdbFile.Value.Symbols["RtlRemoveInvertedFunctionTable"];

                _process.CallFunction(CallingConvention.FastCall, rtRemoveInvertedFunctionTableAddress, (long)remoteDllAddress);

                // Decrease the reference count of the DLL dependencies

                var freeLibraryAddress = _process.GetFunctionAddress("kernel32.dll", "FreeLibrary");

                if (_peImage.ImportedFunctions.Value.GroupBy(importedFunction => importedFunction.Dll).Select(dll => _process.Modules.Find(module => module.Name.Equals(dll.Key, StringComparison.OrdinalIgnoreCase)).BaseAddress).Any(dependencyAddress => !_process.CallFunction <bool>(CallingConvention.StdCall, freeLibraryAddress, (long)dependencyAddress)))
                {
                    throw new RemoteFunctionCallException("Failed to call FreeLibrary");
                }

                // Free the memory allocated for the DLL

                if (_injectionMethod == InjectionMethod.ManualMap)
                {
                    _process.MemoryManager.FreeVirtualMemory(remoteDllAddress);
                }

                else
                {
                    Ntdll.NtUnmapViewOfSection(_process.Process.SafeHandle, remoteDllAddress);
                }
            }

            else
            {
                var freeLibraryAddress = _process.GetFunctionAddress("kernel32.dll", "FreeLibrary");

                if (!_process.CallFunction <bool>(CallingConvention.StdCall, freeLibraryAddress, (long)remoteDllAddress))
                {
                    throw new RemoteFunctionCallException("Failed to call FreeLibrary");
                }
            }
        }
Beispiel #15
0
        public static Process TryGetParentProcess(Process process)
        {
            try
            {
                var processInformation = default(Ntdll.PROCESS_BASIC_INFORMATION);
                if (Ntdll.NtQueryInformationProcess(process.Handle, 0, ref processInformation, processInformation.Size, out var returnLength) == Ntdll.STATUS_SUCCESS)
                {
                    return(Process.GetProcessById(processInformation.InheritedFromUniqueProcessId.ToInt32()));
                }
            }
            catch
            {
            }

            return(null);
        }
Beispiel #16
0
        private PebData ReadPebData()
        {
            if (_process.GetArchitecture() == Architecture.X86)
            {
                Span <byte> pebAddressBuffer = stackalloc byte[IntPtr.Size];

                // Query the process for the address of its WOW64 PEB

                var ntStatus = Ntdll.NtQueryInformationProcess(_process.SafeHandle, ProcessInformationClass.Wow64Information, out pebAddressBuffer[0], pebAddressBuffer.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw new Win32Exception(Ntdll.RtlNtStatusToDosError(ntStatus));
                }

                var pebAddress = MemoryMarshal.Read <IntPtr>(pebAddressBuffer);

                // Read the WOW64 PEB

                var peb = _process.ReadStructure <Peb32>(pebAddress);

                return(new PebData(SafeHelpers.CreateSafeIntPtr(peb.ApiSetMap), SafeHelpers.CreateSafeIntPtr(peb.Ldr)));
            }

            else
            {
                Span <byte> basicInformationBuffer = stackalloc byte[Unsafe.SizeOf <ProcessBasicInformation64>()];

                // Query the process for its basic information

                var ntStatus = Ntdll.NtQueryInformationProcess(_process.SafeHandle, ProcessInformationClass.BasicInformation, out basicInformationBuffer[0], basicInformationBuffer.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw new Win32Exception(Ntdll.RtlNtStatusToDosError(ntStatus));
                }

                var basicInformation = MemoryMarshal.Read <ProcessBasicInformation64>(basicInformationBuffer);

                // Read the PEB

                var peb = _process.ReadStructure <Peb64>(SafeHelpers.CreateSafeIntPtr(basicInformation.PebBaseAddress));

                return(new PebData(SafeHelpers.CreateSafeIntPtr(peb.ApiSetMap), SafeHelpers.CreateSafeIntPtr(peb.Ldr)));
            }
        }
Beispiel #17
0
        private PebData ReadPebData()
        {
            if (IsWow64)
            {
                // Query the process for the address of its WOW64 PEB

                var wow64PebAddressBytes = new byte[sizeof(long)];

                var ntStatus = Ntdll.NtQueryInformationProcess(_processHandle, ProcessInformationClass.Wow64Information, ref wow64PebAddressBytes[0], wow64PebAddressBytes.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw new Win32Exception($"Failed to call NtQueryInformationProcess with error code {Ntdll.RtlNtStatusToDosError(ntStatus)}");
                }

                var wow64PebAddress = MemoryMarshal.Read <IntPtr>(wow64PebAddressBytes);

                // Read the WOW64 PEB data

                var wow64Peb = Memory.Read <Peb32>(wow64PebAddress);

                return(new PebData(new IntPtr(wow64Peb.ApiSetMap), new IntPtr(wow64Peb.Ldr)));
            }

            else
            {
                // Query the process for the address of its PEB

                var processBasicInformationBytes = new byte[Unsafe.SizeOf <ProcessBasicInformation>()];

                var ntStatus = Ntdll.NtQueryInformationProcess(_processHandle, ProcessInformationClass.BasicInformation, ref processBasicInformationBytes[0], processBasicInformationBytes.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw new Win32Exception($"Failed to call NtQueryInformationProcess with error code {Ntdll.RtlNtStatusToDosError(ntStatus)}");
                }

                // Read the PEB data

                var processBasicInformation = MemoryMarshal.Read <ProcessBasicInformation>(processBasicInformationBytes);

                var peb = Memory.Read <Peb64>(processBasicInformation.PebBaseAddress);

                return(new PebData(new IntPtr(peb.ApiSetMap), new IntPtr(peb.Ldr)));
            }
        }
Beispiel #18
0
        internal static void CreateThread(this Process process, IntPtr address)
        {
            var status = Ntdll.NtCreateThreadEx(out var threadHandle, AccessMask.SpecificRightsAll | AccessMask.StandardRightsAll, IntPtr.Zero, process.SafeHandle, address, IntPtr.Zero, ThreadCreationFlags.HideFromDebugger | ThreadCreationFlags.SkipThreadAttach, 0, 0, 0, IntPtr.Zero);

            if (status != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
            }

            using (threadHandle)
            {
                if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)
                {
                    throw new Win32Exception();
                }
            }
        }
Beispiel #19
0
        internal static void CreateThread(this Process process, IntPtr address)
        {
            var status = Ntdll.RtlCreateUserThread(process.SafeHandle, IntPtr.Zero, false, 0, 0, 0, address, IntPtr.Zero, out var threadHandle, IntPtr.Zero);

            if (status != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
            }

            using (threadHandle)
            {
                if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)
                {
                    throw new Win32Exception();
                }
            }
        }
Beispiel #20
0
        private static PebData ReadPebData(Process process)
        {
            if (process.GetArchitecture() == Architecture.X86)
            {
                // Query the remote process for the address of its WOW64 PEB

                var wow64PebAddressBytes = new byte[IntPtr.Size];

                var ntStatus = Ntdll.NtQueryInformationProcess(process.SafeHandle, ProcessInformationClass.Wow64Information, ref wow64PebAddressBytes[0], wow64PebAddressBytes.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw ExceptionBuilder.BuildWin32Exception("NtQueryInformationProcess", ntStatus);
                }

                var wow64PebAddress = MemoryMarshal.Read <IntPtr>(wow64PebAddressBytes);

                // Read the WOW64 PEB data

                var wow64Peb = process.ReadStructure <Peb32>(wow64PebAddress);

                return(new PebData(new IntPtr(wow64Peb.ApiSetMap), new IntPtr(wow64Peb.Ldr)));
            }

            else
            {
                // Query the remote process for its BasicInformation

                var processBasicInformationBytes = new byte[Unsafe.SizeOf <ProcessBasicInformation64>()];

                var ntStatus = Ntdll.NtQueryInformationProcess(process.SafeHandle, ProcessInformationClass.BasicInformation, ref processBasicInformationBytes[0], processBasicInformationBytes.Length, out _);

                if (ntStatus != NtStatus.Success)
                {
                    throw ExceptionBuilder.BuildWin32Exception("NtQueryInformationProcess", ntStatus);
                }

                var processBasicInformation = MemoryMarshal.Read <ProcessBasicInformation64>(processBasicInformationBytes);

                // Read the PEB data

                var peb = process.ReadStructure <Peb64>(new IntPtr(processBasicInformation.PebBaseAddress));

                return(new PebData(new IntPtr(peb.ApiSetMap), new IntPtr(peb.Ldr)));
            }
        }
Beispiel #21
0
        public void TestNtWriteVirtualMemory()
        {
            var syscall = new Syscall <Signatures.NtWriteVirtualMemory>();

            Span <byte> bytes = stackalloc byte[sizeof(int)];

            MemoryMarshal.Write(bytes, ref Unsafe.AsRef(_testValue));

            var status = syscall.Method(_process.SafeHandle, _testAddress, in bytes[0], bytes.Length, out _);

            if (status != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
            }

            Assert.Equal(_testValue, Marshal.ReadInt32(_testAddress));
        }
Beispiel #22
0
        private Peb ReadPeb()
        {
            if (IsWow64)
            {
                // Query the process for the address of its WOW64 PEB

                var wow64PebAddressBuffer = new byte[sizeof(long)];

                var ntStatus = Ntdll.NtQueryInformationProcess(Process.SafeHandle, ProcessInformationClass.Wow64Information, ref wow64PebAddressBuffer[0], wow64PebAddressBuffer.Length, out var returnLength);

                if (ntStatus != NtStatus.Success || returnLength != wow64PebAddressBuffer.Length)
                {
                    throw new Win32Exception($"Failed to call NtQueryInformationProcess with error code {ntStatus}");
                }

                var wow64PebAddress = Unsafe.ReadUnaligned <IntPtr>(ref wow64PebAddressBuffer[0]);

                // Read the WOW64 PEB

                var wow64Peb = Memory.Read <Peb <int> >(wow64PebAddress);

                return(new Peb((IntPtr)wow64Peb.ApiSetMap, (IntPtr)wow64Peb.Ldr));
            }

            else
            {
                // Query the process for the address of its PEB

                var processBasicInformationBuffer = new byte[Unsafe.SizeOf <ProcessBasicInformation>()];

                var ntStatus = Ntdll.NtQueryInformationProcess(Process.SafeHandle, ProcessInformationClass.BasicInformation, ref processBasicInformationBuffer[0], processBasicInformationBuffer.Length, out var returnLength);

                if (ntStatus != NtStatus.Success || returnLength != processBasicInformationBuffer.Length)
                {
                    throw new Win32Exception($"Failed to call NtQueryInformationProcess with error code {ntStatus}");
                }

                var pebAddress = Unsafe.ReadUnaligned <ProcessBasicInformation>(ref processBasicInformationBuffer[0]).PebBaseAddress;

                // Read the PEB

                var peb = Memory.Read <Peb <long> >(pebAddress);

                return(new Peb((IntPtr)peb.ApiSetMap, (IntPtr)peb.Ldr));
            }
        }
Beispiel #23
0
        private void CallRoutine(RoutineDescriptor routineDescriptor)
        {
            // Write the shellcode used to perform the function call into a buffer

            Span <byte> shellcodeBuffer;

            if (Process.GetArchitecture() == Architecture.X86)
            {
                shellcodeBuffer = RoutineAssembler.AssembleRoutine32(routineDescriptor);
            }

            else
            {
                shellcodeBuffer = RoutineAssembler.AssembleRoutine64(routineDescriptor);
            }

            var shellcodeBufferAddress = Process.AllocateBuffer(shellcodeBuffer.Length, true);

            try
            {
                Process.WriteBuffer(shellcodeBufferAddress, shellcodeBuffer);

                // Create a thread to execute the shellcode

                var ntStatus = Ntdll.NtCreateThreadEx(out var threadHandle, AccessMask.SpecificRightsAll | AccessMask.StandardRightsAll, IntPtr.Zero, Process.SafeHandle, shellcodeBufferAddress, IntPtr.Zero, ThreadCreationFlags.HideFromDebugger | ThreadCreationFlags.SkipThreadAttach, IntPtr.Zero, 0, 0, IntPtr.Zero);

                using (threadHandle)
                {
                    if (ntStatus != NtStatus.Success)
                    {
                        throw new Win32Exception(Ntdll.RtlNtStatusToDosError(ntStatus));
                    }

                    if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)
                    {
                        throw new Win32Exception();
                    }
                }
            }

            finally
            {
                Process.FreeBuffer(shellcodeBufferAddress);
            }
        }
        /// <summary>
        ///     Gets the parent process of a specified process.
        /// </summary>
        /// <param name="handle">The process handle.</param>
        /// <returns>An instance of the Process class.</returns>
        public static Process GetParentProcess(IntPtr handle)
        {
            var pbi = new ParentProcess();
            int returnLength;
            int status = Ntdll.NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);

            if (status != 0)
            {
                throw new Win32Exception(status);
            }

            try {
                return(Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()));
            } catch (ArgumentException) {
                // not found
                return(null);
            }
        }
Beispiel #25
0
        public void TestNtReadVirtualMemory()
        {
            const int testNumber = 1024;

            Marshal.WriteInt32(_testAddress, testNumber);

            var syscall = new Syscall <Delegates.ReadProcessMemory>();

            Span <byte> bytes = stackalloc byte[sizeof(int)];

            var status = syscall.Method(_process.SafeHandle, _testAddress, out bytes[0], bytes.Length, out _);

            if (status != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
            }

            Assert.Equal(testNumber, MemoryMarshal.Read <int>(bytes));
        }
Beispiel #26
0
        static PlatformInfo()
        {
            // see why not use Environment.OSVersion.Version:
            // http://stackoverflow.com/questions/17399302/how-can-i-detect-windows-8-1-in-a-desktop-application
            // http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx

            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                var ver = Ntdll.RtlGetVersion();

                IsWinVistaUp = ver >= new Version(6, 0, 0);
                //IsWin7Up = ver >= new Version(6, 1, 0);
                //IsWin8Up = ver >= new Version(6, 2, 0);
                IsWin81Up = ver >= new Version(6, 3, 0);
                //IsWin10Up = ver >= new Version(10, 0, 0);
            }

            Is64BitProcess = IntPtr.Size == 8;
        }
        private static bool TryGetExecutableNameViaNtByPid(int processId, out string executableName)
        {
            bool executableNameRetrieved = false;

            executableName = "";

            var ntstatus = Ntdll.NtQuerySystemInformationInitial(
                Ntdll.SYSTEM_INFORMATION_CLASS.SystemProcessInformation,
                IntPtr.Zero,
                0,
                out int requiredBufferLength);

            if (ntstatus == Ntdll.NTSTATUS.STATUS_INFO_LENGTH_MISMATCH)
            {
                var buffer = Marshal.AllocHGlobal(requiredBufferLength);
                ntstatus = Ntdll.NtQuerySystemInformation(
                    Ntdll.SYSTEM_INFORMATION_CLASS.SystemProcessInformation,
                    buffer,
                    requiredBufferLength,
                    IntPtr.Zero);

                if (ntstatus == Ntdll.NTSTATUS.SUCCESS)
                {
                    Ntdll.SYSTEM_PROCESS_INFORMATION processInfo;
                    IntPtr entryPtr = buffer;
                    do
                    {
                        processInfo = Marshal.PtrToStructure <Ntdll.SYSTEM_PROCESS_INFORMATION>(entryPtr);
                        if (processInfo.UniqueProcessId == processId && processInfo.ImageName.Buffer != IntPtr.Zero)
                        {
                            executableName          = Marshal.PtrToStringUni(processInfo.ImageName.Buffer, processInfo.ImageName.Length / 2);
                            executableNameRetrieved = true;
                            break;
                        }
                        entryPtr += processInfo.NextEntryOffset;
                    } while (processInfo.NextEntryOffset != 0);
                }

                Marshal.FreeHGlobal(buffer);
            }

            return(executableNameRetrieved);
        }
        internal static T QueryInformation <T>(this ProcessThread thread, ThreadInformationType informationType) where T : unmanaged
        {
            using var threadHandle = Kernel32.OpenThread(AccessMask.SpecificRightsAll | AccessMask.StandardRightsAll, false, thread.Id);

            if (threadHandle.IsInvalid)
            {
                throw new Win32Exception();
            }

            Span <byte> informationBytes = stackalloc byte[Unsafe.SizeOf <T>()];
            var         status           = Ntdll.NtQueryInformationThread(threadHandle, informationType, out informationBytes[0], informationBytes.Length, IntPtr.Zero);

            if (status != NtStatus.Success)
            {
                throw new Win32Exception(Ntdll.RtlNtStatusToDosError(status));
            }

            return(MemoryMarshal.Read <T>(informationBytes));
        }
Beispiel #29
0
        /// <summary>
        /// Wrapper for the defautl WinApi NtQueryInformationProcess, makes the code more readable.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="process"></param>
        /// <param name="pic"></param>
        /// <returns></returns>
        public static T WinApiNtQueryInformationProcess <T>(GameSharpProcess process, ProcessInformationClass pic) where T : struct
        {
            T returnResult = default;

            IMemoryPointer ntResult = process.AllocateManagedMemory(Marshal.SizeOf <T>());

            uint result = Ntdll.NtQueryInformationProcess(process.NativeHandle, pic, ntResult.Address, Marshal.SizeOf <T>(), out int _);

            if (result == 0)
            {
                returnResult = ntResult.Read <T>();
            }
            else
            {
                LoggingService.Error(
                    $"Couldn't query NtQueryInformationProcess, Error code: {Marshal.GetLastWin32Error().ToString("X")}, " +
                    $"Return value of NtQueryInformationProcess function is 0x{result.ToString("X")}.");
            }

            return(returnResult);
        }
Beispiel #30
0
        internal TStructure CallFunction <TStructure>(CallingConvention callingConvention, IntPtr functionAddress, params long[] parameters) where TStructure : unmanaged
        {
            var returnBuffer = Memory.Allocate(Unsafe.SizeOf <TStructure>(), ProtectionType.ReadWrite);

            // Write the shellcode used to perform the function call into a buffer in the remote process

            var shellcode = Assembler.AssembleCallDescriptor(new CallDescriptor(functionAddress, callingConvention, IsWow64, parameters, returnBuffer));

            var shellcodeBuffer = Memory.Allocate(shellcode.Length, ProtectionType.ExecuteReadWrite);

            Memory.Write(shellcodeBuffer, shellcode);

            // Create a thread in the remote process to execute the shellcode

            var ntStatus = Ntdll.RtlCreateUserThread(_processHandle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, shellcodeBuffer, IntPtr.Zero, out var threadHandle, IntPtr.Zero);

            if (ntStatus != NtStatus.Success)
            {
                throw new Win32Exception($"Failed to call RtlCreateUserThread with error code {Ntdll.RtlNtStatusToDosError(ntStatus)}");
            }

            if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)
            {
                throw new Win32Exception($"Failed to call WaitForSingleObject with error code {Marshal.GetLastWin32Error()}");
            }

            threadHandle.Dispose();

            Memory.Free(shellcodeBuffer);

            try
            {
                return(Memory.Read <TStructure>(returnBuffer));
            }

            finally
            {
                Memory.Free(returnBuffer);
            }
        }