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
///