Inheritance: Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
        /// <summary>
        /// Converts an handle into a <see cref="ProcessThread"/> object assuming this is a thread handle.
        /// </summary>
        /// <param name="threadHandle">A valid handle to an opened thread.</param>
        /// <returns>A <see cref="ProcessThread"/> object from the specified handle.</returns>
        public static ProcessThread HandleToThread(SafeMemoryHandle threadHandle)
        {
            // Search the thread by iterating the processes list
            foreach (var process in Process.GetProcesses())
            {
                var ret = process.Threads.Cast<ProcessThread>().FirstOrDefault(t => t.Id == HandleToThreadId(threadHandle));
                if (ret != null)
                    return ret;
            }

            // If no thread was found, throws a exception like the First() function with no element
            throw new InvalidOperationException("Sequence contains no matching element");
        }
Exemple #2
0
        /// <summary>
        /// Releases a region of memory within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to a process.</param>
        /// <param name="address">A pointer to the starting address of the region of memory to be freed.</param>
        public static void Free(SafeMemoryHandle processHandle, IntPtr address)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");

            // Free the memory
            if (!NativeMethods.VirtualFreeEx(processHandle, address, 0, MemoryReleaseFlags.Release))
            {
                // If the memory wasn't correctly freed, throws an exception
                throw new Win32Exception(string.Format("The memory page 0x{0} cannot be freed.", address.ToString("X")));
            }    
        }
        /// <summary>
        /// Converts an handle into a process id assuming this is a process handle.
        /// </summary>
        /// <param name="processHandle">A valid handle to an opened process.</param>
        /// <returns>A process id from the specified handle.</returns>
        public static int HandleToProcessId(SafeMemoryHandle processHandle)
        {
            // Check if the handle is valid
            ValidateAsArgument(processHandle, "processHandle");

            // Find the process id
            var ret = NativeMethods.GetProcessId(processHandle);

            // If the process id is valid
            if (ret != 0)
                return ret;

            // Else the function failed, throws an exception
            throw new Win32Exception("Couldn't find the process id of the specified handle.");
        }
Exemple #4
0
        /// <summary>
        /// Reserves a region of memory within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">The handle to a process.</param>
        /// <param name="size">The size of the region of memory to allocate, in bytes.</param>
        /// <param name="protectionFlags">The memory protection for the region of pages to be allocated.</param>
        /// <param name="allocationFlags">The type of memory allocation.</param>
        /// <returns>The base address of the allocated region.</returns>
        public static IntPtr Allocate(SafeMemoryHandle processHandle, int size, MemoryProtectionFlags protectionFlags = MemoryProtectionFlags.ExecuteReadWrite,
            MemoryAllocationFlags allocationFlags = MemoryAllocationFlags.Commit)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            
            // Allocate a memory page
            var ret = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, size, allocationFlags, protectionFlags);

            // Check whether the memory page is valid
            if (ret != IntPtr.Zero)
                return ret;

            // If the pointer isn't valid, throws an exception
            throw new Win32Exception(string.Format("Couldn't allocate memory of {0} byte(s).", size));
        }
        /// <summary>
        /// Retrieves the context of the specified thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread whose context is to be retrieved.</param>
        /// <param name="contextFlags">Determines which registers are returned or set.</param>
        /// <returns>A <see cref="ThreadContext"/> structure that receives the appropriate context of the specified thread.</returns>
        public static ThreadContext GetThreadContext(SafeMemoryHandle threadHandle, ThreadContextFlags contextFlags = ThreadContextFlags.Full)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(threadHandle, "threadHandle");

            // Allocate a thread context structure
            var context = new ThreadContext {ContextFlags = contextFlags};

            // Set the context flag

            // Get the thread context
            if (NativeMethods.GetThreadContext(threadHandle, ref context))
                return context;

            // Else couldn't get the thread context, throws an exception
            throw new Win32Exception("Couldn't get the thread context.");
        }
        /// <summary>
        /// Creates a thread that runs in the virtual address space of another process.
        /// </summary>
        /// <param name="processHandle">A handle to the process in which the thread is to be created.</param>
        /// <param name="startAddress">A pointer to the application-defined function to be executed by the thread and represents the starting address of the thread in the remote process.</param>
        /// <param name="parameter">A pointer to a variable to be passed to the thread function.</param>
        /// <param name="creationFlags">The flags that control the creation of the thread.</param>
        /// <returns>A handle to the new thread.</returns>
        public static SafeMemoryHandle CreateRemoteThread(SafeMemoryHandle processHandle, IntPtr startAddress, IntPtr parameter, ThreadCreationFlags creationFlags = ThreadCreationFlags.Run)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(startAddress, "startAddress");

            // Create the remote thread
            int threadId;
            var ret = NativeMethods.CreateRemoteThread(processHandle, IntPtr.Zero, 0, startAddress, parameter, creationFlags, out threadId);

            // If the thread is created
            if (!ret.IsClosed && !ret.IsInvalid)
                return ret;

            // Else couldn't create thread, throws an exception
            throw new Win32Exception(string.Format("Couldn't create the thread at 0x{0}.", startAddress.ToString("X")));
        }
Exemple #7
0
        /// <summary>
        ///     Retrieves the termination status of the specified thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread.</param>
        /// <returns>
        ///     Nullable type: the return value is A pointer to a variable to receive the thread termination status or
        ///     <code>null</code> if it is running.
        /// </returns>
        public static IntPtr? GetExitCodeThread(SafeMemoryHandle threadHandle)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Create the variable storing the output exit code
            IntPtr exitCode;

            // Get the exit code of the thread
            if (!NativeMethods.GetExitCodeThread(threadHandle, out exitCode))
                throw new Win32Exception("Couldn't get the exit code of the thread.");

            // If the thread is still active
            if (exitCode == new IntPtr(259))
                return null;

            return exitCode;
        }
Exemple #8
0
        /// <summary>
        ///     Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">
        ///     A pointer to the base address of the region of pages whose access protection attributes are to be
        ///     changed.
        /// </param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a <see cref="Native.MemoryBasicInformation" /> structure.</returns>
        public static MemoryProtectionFlags ChangeProtection(SafeMemoryHandle processHandle, IntPtr address, int size, MemoryProtectionFlags protection)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");

            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            // Change the protection in the target process
            if (NativeMethods.VirtualProtectEx(processHandle, address, size, protection, out oldProtection))
            {
                // Return the old protection
                return oldProtection;
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(string.Format("Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.", address.ToString("X"), size, protection));
        }
Exemple #9
0
 /// <summary>
 ///     Performs a pattern scan.
 /// </summary>
 /// <param name="processHandle">The process the <see cref="ProcessModule" /> containing the data resides in.</param>
 /// <param name="processModule">The <see cref="ProcessModule" /> that contains the pattern data resides in.</param>
 /// <param name="data">The array of bytes containing the data to search for matches in.</param>
 /// <param name="mask">
 ///     The mask that defines the byte pattern we are searching for.
 ///     <example>
 ///         <code>
 /// var bytes = new byte[]{55,45,00,00,55} ;
 /// var mask = "xx??x";
 /// </code>
 ///     </example>
 /// </param>
 /// <param name="offsetToAdd">The offset to add to the offset result found from the pattern.</param>
 /// <param name="reBase">If the address should be rebased to this  Instance's base address.</param>
 /// <param name="wildCardChar">
 ///     [Optinal] The 'wild card' defines the <see cref="char" /> value that the mask uses to differentiate
 ///     between pattern data that is relevant, and pattern data that should be ignored. The default value is 'x'.
 /// </param>
 /// <param name="pattern">The byte array that contains the pattern of bytes we're looking for.</param>
 /// <returns>A new <see cref="PatternScanResult" /> instance.</returns>
 public static PatternScanResult Find(SafeMemoryHandle processHandle, ProcessModule processModule, byte[] data,
     byte[] pattern,
     string mask, int offsetToAdd, bool reBase, char wildCardChar = 'x')
 {
     for (var offset = 0; offset < data.Length; offset++)
     {
         if (mask.Where((m, b) => m == 'x' && pattern[b] != data[b + offset]).Any()) continue;
         var found = MemoryCore.Read<IntPtr>(processHandle,
             processModule.BaseAddress + offset + offsetToAdd);
         var result = new PatternScanResult
         {
             OriginalAddress = found,
             Address = reBase ? found : found.Subtract(processModule.BaseAddress),
             Offset = (IntPtr) offset
         };
         return result;
     }
     // If this is reached, the pattern was not found.
     throw new Exception("The pattern scan for the pattern mask: " + "[" + mask + "]" + " was not found.");
 }
Exemple #10
0
        /// <summary>
        ///     Waits an infinite amount of time for the specified object to become signaled.
        /// </summary>
        /// <param name="handle">A handle to the object.</param>
        /// <returns>If the function succeeds, the return value indicates the event that caused the function to return.</returns>
        public static WaitValues WaitForSingleObject(SafeMemoryHandle handle)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(handle, "handle");

            // Wait for single object
            var ret = NativeMethods.WaitForSingleObject(handle, 0xFFFFFFFF);

            // If the function failed
            if (ret == WaitValues.Failed)
                throw new Win32Exception("The WaitForSingleObject function call failed.");

            return ret;
        }
Exemple #11
0
        /// <summary>
        ///     Waits until the specified object is in the signaled state or the time-out interval elapses.
        /// </summary>
        /// <param name="handle">A handle to the object.</param>
        /// <param name="timeout">
        ///     The time-out interval. If this parameter is NULL, the function does not enter a wait state if the
        ///     object is not signaled; it always returns immediately.
        /// </param>
        /// <returns>Indicates the <see cref="WaitValues" /> event that caused the function to return.</returns>
        public static WaitValues WaitForSingleObject(SafeMemoryHandle handle, TimeSpan? timeout)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(handle, "handle");

            // Wait for single object
            var ret = NativeMethods.WaitForSingleObject(handle,
                timeout.HasValue ? Convert.ToUInt32(timeout.Value.TotalMilliseconds) : 0);

            // If the function failed
            if (ret == WaitValues.Failed)
                throw new Win32Exception("The WaitForSingleObject function call failed.");

            return ret;
        }
Exemple #12
0
        /// <summary>
        ///     Terminates a thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread to be terminated.</param>
        /// <param name="exitCode">The exit code for the thread.</param>
        public static void TerminateThread(SafeMemoryHandle threadHandle, int exitCode)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Terminate the thread
            var ret = NativeMethods.TerminateThread(threadHandle, exitCode);

            // If the function failed
            if (!ret)
                throw new Win32Exception("Couldn't terminate the thread.");
        }
Exemple #13
0
 public static extern bool SetThreadContext(SafeMemoryHandle hThread,
     [MarshalAs(UnmanagedType.Struct)] ref ThreadContext lpContext);
Exemple #14
0
 public static extern uint SuspendThread(SafeMemoryHandle hThread);
Exemple #15
0
 /// <summary>
 /// Finds the Process Environment Block address of a specified process.
 /// </summary>
 /// <param name="processHandle">A handle of the process.</param>
 /// <returns>A <see cref="IntPtr"/> pointer of the PEB.</returns>
 public static IntPtr FindPeb(SafeMemoryHandle processHandle)
 {
     return(MemoryCore.NtQueryInformationProcess(processHandle).PebBaseAddress);
 }
Exemple #16
0
 public static extern bool TerminateThread(SafeMemoryHandle hThread, int dwExitCode);
Exemple #17
0
 public static extern IntPtr VirtualAllocEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
     MemoryAllocationFlags flAllocationType, MemoryProtectionFlags flProtect);
 /// <summary>
 /// Converts an handle into a <see cref="Process"/> object assuming this is a process handle.
 /// </summary>
 /// <param name="processHandle">A valid handle to an opened process.</param>
 /// <returns>A <see cref="Process"/> object from the specified handle.</returns>
 public static Process HandleToProcess(SafeMemoryHandle processHandle)
 {
     // Search the process by iterating the processes list
     return Process.GetProcesses().First(p => p.Id == HandleToProcessId(processHandle));
 }
        /// <summary>
        /// Validates an handle to fit correctly as argument.
        /// </summary>
        /// <param name="handle">A handle to validate.</param>
        /// <param name="argumentName">The name of the argument that represents the handle in its original function.</param>
        public static void ValidateAsArgument(SafeMemoryHandle handle, string argumentName)
        {
            // Check if the handle is not null
            if (handle == null)
                throw new ArgumentNullException(argumentName);

            // Check if the handle is valid
            if(handle.IsClosed || handle.IsInvalid)
                throw new ArgumentException("The handle is not valid or closed.", argumentName);
        }
Exemple #20
0
        /// <summary>
        /// Retrieves information about a range of pages within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory information is queried.</param>
        /// <param name="baseAddress">A pointer to the base address of the region of pages to be queried.</param>
        /// <returns>A <see cref="Native.MemoryBasicInformation"/> structures in which information about the specified page range is returned.</returns>
        public static MemoryBasicInformation Query(SafeMemoryHandle processHandle, IntPtr baseAddress)
        {
            // Allocate the structure to store information of memory
            MemoryBasicInformation memoryInfo;

            // Query the memory region
            if(NativeMethods.VirtualQueryEx(processHandle, baseAddress, out memoryInfo, MarshalType<MemoryBasicInformation>.Size) != 0)
                return memoryInfo;

            // Else the information couldn't be got
            throw new Win32Exception(string.Format("Couldn't query information about the memory region 0x{0}", baseAddress.ToString("X")));
        }
 /// <summary>
 /// Finds the Process Environment Block address of a specified process.
 /// </summary>
 /// <param name="processHandle">A handle of the process.</param>
 /// <returns>A <see cref="IntPtr"/> pointer of the PEB.</returns>
 public static IntPtr FindPeb(SafeMemoryHandle processHandle)
 {
     return MemoryCore.NtQueryInformationProcess(processHandle).PebBaseAddress;
 }
Exemple #22
0
        /// <summary>
        /// Writes data to an area of memory in a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process memory to be modified.</param>
        /// <param name="address">A pointer to the base address in the specified process to which data is written.</param>
        /// <param name="byteArray">A buffer that contains data to be written in the address space of the specified process.</param>
        /// <returns>The number of bytes written.</returns>
        public static int WriteBytes(SafeMemoryHandle processHandle, IntPtr address, byte[] byteArray)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");

            // Create the variable storing the number of bytes written
            int nbBytesWritten;

            // Write the data to the target process
            if (NativeMethods.WriteProcessMemory(processHandle, address, byteArray, byteArray.Length, out nbBytesWritten))
            {
                // Check whether the length of the data written is equal to the inital array
                if (nbBytesWritten == byteArray.Length)
                    return nbBytesWritten;
            }

            // Else the data couldn't be written, throws an exception
            throw new Win32Exception(string.Format("Couldn't write {0} bytes to 0x{1}", byteArray.Length, address.ToString("X")));
        }
Exemple #23
0
 /// <summary>
 /// Finds the Thread Environment Block address of a specified thread.
 /// </summary>
 /// <param name="threadHandle">A handle of the thread.</param>
 /// <returns>A <see cref="IntPtr"/> pointer of the TEB.</returns>
 public static IntPtr FindTeb(SafeMemoryHandle threadHandle)
 {
     return ThreadCore.NtQueryInformationThread(threadHandle).TebBaseAdress;
 }
Exemple #24
0
 public static extern bool VirtualFreeEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
     MemoryReleaseFlags dwFreeType);
Exemple #25
0
        /// <summary>
        /// Reads an array of bytes in the memory form the target process.
        /// </summary>
        /// <param name="processHandle">A handle to the process with memory that is being read.</param>
        /// <param name="address">A pointer to the base address in the specified process from which to read.</param>
        /// <param name="size">The number of bytes to be read from the specified process.</param>
        /// <returns>The collection of read bytes.</returns>
        public static byte[] ReadBytes(SafeMemoryHandle processHandle, IntPtr address, int size)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");
            
            // Allocate the buffer
            var buffer = new byte[size];
            int nbBytesRead;

            // Read the data from the target process
            if (NativeMethods.ReadProcessMemory(processHandle, address, buffer, size, out nbBytesRead) && size == nbBytesRead)
                return buffer;

            // Else the data couldn't be read, throws an exception
            throw new Win32Exception(string.Format("Couldn't read {0} byte(s) from 0x{1}.", size, address.ToString("X")));
        }
Exemple #26
0
        /// <summary>
        ///     Retrieves a descriptor table entry for the specified selector and thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread containing the specified selector.</param>
        /// <param name="selector">The global or local selector value to look up in the thread's descriptor tables.</param>
        /// <returns>A pointer to an <see cref="LdtEntry" /> structure that receives a copy of the descriptor table entry.</returns>
        public static LdtEntry GetThreadSelectorEntry(SafeMemoryHandle threadHandle, uint selector)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Get the selector entry
            LdtEntry entry;
            if (NativeMethods.GetThreadSelectorEntry(threadHandle, selector, out entry))
                return entry;

            // Else couldn't get the selector entry, throws an exception
            throw new Win32Exception($"Couldn't get the selector entry for this selector: {selector}.");
        }
Exemple #27
0
        /// <summary>
        /// Retrieves information about a range of pages within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory information is queried.</param>
        /// <param name="addressFrom">A pointer to the starting address of the region of pages to be queried.</param>
        /// <param name="addressTo">A pointer to the ending address of the region of pages to be queried.</param>
        /// <returns>A collection of <see cref="Native.MemoryBasicInformation"/> structures.</returns>
        public static IEnumerable<MemoryBasicInformation> Query(SafeMemoryHandle processHandle, IntPtr addressFrom, IntPtr addressTo)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            
            // Convert the addresses to Int64
            var numberFrom = addressFrom.ToInt64();
            var numberTo = addressTo.ToInt64();

            // The first address must be lower than the second
            if (numberFrom >= numberTo)
                throw new ArgumentException("The starting address must be lower than the ending address.", "addressFrom");
            
            // Create the variable storing the result of the call of VirtualQueryEx
            int ret;

            // Enumerate the memory pages
            do
            {
                // Allocate the structure to store information of memory
                MemoryBasicInformation memoryInfo;

                // Get the next memory page
                ret = NativeMethods.VirtualQueryEx(processHandle, new IntPtr(numberFrom), out memoryInfo, MarshalType<MemoryBasicInformation>.Size);

                // Increment the starting address with the size of the page
                numberFrom += memoryInfo.RegionSize;

                // Return the memory page
                if(memoryInfo.State != MemoryStateFlags.Free)
                    yield return memoryInfo;

            } while (numberFrom < numberTo && ret != 0);
        }
Exemple #28
0
        /// <summary>
        ///     Retrieves information about the specified thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread to query.</param>
        /// <returns>A <see cref="ThreadBasicInformation" /> structure containg thread information.</returns>
        public static ThreadBasicInformation NtQueryInformationThread(SafeMemoryHandle threadHandle)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Create a structure to store thread info
            var info = new ThreadBasicInformation();

            // Get the thread info
            var ret = NativeMethods.NtQueryInformationThread(threadHandle, 0, ref info,
                MarshalType<ThreadBasicInformation>.Size, IntPtr.Zero);

            // If the function succeeded
            if (ret == 0)
                return info;

            // Else, couldn't get the thread info, throws an exception
            throw new ApplicationException($"Couldn't get the information from the thread, error code '{ret}'.");
        }
Exemple #29
0
        /// <summary>
        ///     Sets the context for the specified thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread whose context is to be set.</param>
        /// <param name="context">
        ///     A pointer to a <see cref="ThreadContext" /> structure that contains the context to be set in the
        ///     specified thread.
        /// </param>
        public static void SetThreadContext(SafeMemoryHandle threadHandle, ThreadContext context)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Set the thread context
            if (!NativeMethods.SetThreadContext(threadHandle, ref context))
                throw new Win32Exception("Couldn't set the thread context.");
        }
Exemple #30
0
        /// <summary>
        ///     Suspends the specified thread.
        /// </summary>
        /// <param name="threadHandle">A handle to the thread that is to be suspended.</param>
        /// <returns>The thread's previous suspend count.</returns>
        public static uint SuspendThread(SafeMemoryHandle threadHandle)
        {
            // Check if the handle is valid
            HandleManipulationHelper.ValidateAsArgument(threadHandle, "threadHandle");

            // Suspend the thread
            var ret = NativeMethods.SuspendThread(threadHandle);

            // If the function failed
            if (ret == uint.MaxValue)
                throw new Win32Exception("Couldn't suspend the thread.");

            return ret;
        }
Exemple #31
0
        /// <summary>
        /// etrieves information about the specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process to query.</param>
        /// <returns>A <see cref="ProcessBasicInformation"/> structure containg process information.</returns>
        public static ProcessBasicInformation NtQueryInformationProcess(SafeMemoryHandle processHandle)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");

            // Create a structure to store process info
            var info = new ProcessBasicInformation();

            // Get the process info
            var ret = NativeMethods.NtQueryInformationProcess(processHandle, ProcessInformationClass.ProcessBasicInformation, ref info, info.Size, IntPtr.Zero);

            // If the function succeeded
            if (ret == 0)
                return info;

            // Else, couldn't get the process info, throws an exception
            throw new ApplicationException(string.Format("Couldn't get the information from the process, error code '{0}'.", ret));
        }
Exemple #32
0
 /// <summary>
 ///     Finds the Thread Environment Block address of a specified thread.
 /// </summary>
 /// <param name="threadHandle">A handle of the thread.</param>
 /// <returns>A <see cref="IntPtr" /> pointer of the TEB.</returns>
 public static IntPtr FindTeb(SafeMemoryHandle threadHandle)
 {
     return(ThreadCore.NtQueryInformationThread(threadHandle).TebBaseAdress);
 }