diff --git a/Memory/Structures/Imports.cs b/Memory/Structures/Imports.cs index 5ea65e5..e23731e 100644 --- a/Memory/Structures/Imports.cs +++ b/Memory/Structures/Imports.cs @@ -386,6 +386,18 @@ public struct MODULEENTRY32 internal string szExePath; } - + [DllImport("ntdll.dll", SetLastError = true)] + internal static extern int NtQueryInformationThread( + IntPtr threadHandle, + ThreadInfoClass threadInformationClass, + IntPtr threadInformation, + int threadInformationLength, + IntPtr returnLengthPtr); + public enum ThreadInfoClass : int + { + ThreadQuerySetWin32StartAddress = 9 + } + + } } \ No newline at end of file diff --git a/Memory/memory.cs b/Memory/memory.cs index 9b8fade..33ed81e 100644 --- a/Memory/memory.cs +++ b/Memory/memory.cs @@ -1023,6 +1023,34 @@ public void GetThreads() } } + /// + /// Get thread base address by ID. Provided by github.com/osadrac + /// + /// + /// + /// + public static IntPtr GetThreadStartAddress(int threadId) + { + var hThread = OpenThread(ThreadAccess.QUERY_INFORMATION, false, (uint)threadId); + if (hThread == IntPtr.Zero) + throw new Win32Exception(); + var buf = Marshal.AllocHGlobal(IntPtr.Size); + try + { + var result = Imps.NtQueryInformationThread(hThread, + ThreadInfoClass.ThreadQuerySetWin32StartAddress, + buf, IntPtr.Size, IntPtr.Zero); + if (result != 0) + throw new Win32Exception(string.Format("NtQueryInformationThread failed; NTSTATUS = {0:X8}", result)); + return Marshal.ReadIntPtr(buf); + } + finally + { + CloseHandle(hThread); + Marshal.FreeHGlobal(buf); + } + } + /// /// suspend a thread by ID ///