因为http://undocumented.ntinternals.net上这个特定问题的大多数链接显然已经死了,NtQueryInfoThread和相关的THREADINFOCLASSes已经从Winternl.h中消失了。我现在坐在这里努力找到我知道的过程的TEB处理。 我尝试从ntdll.dll加载方法,这是另一种似乎有效的解决方案,但遗憾的是我仍未能获得所需的地址。
{{1}}
还有其他方法,也许使用公共api调用来获取线程的TEB? (因为MSDN声明不应再使用这种方法。)
最诚挚的问候,
亚历
答案 0 :(得分:1)
正常工作:S获取线程TEB的唯一方法是使用以下方法读取它:
NT_TIB* tib = (NT_TIB*)__readfsdword(0x18);
并从中读取基地址。
您的通话可能失败,因为您可能没有正确的权限来读取内存。尝试使用VirtualProtect
?
以下是有效的,但我只是在当前流程上进行了测试..
#include <iostream>
#include <windows.h>
typedef LONG NTSTATUS;
typedef DWORD KPRIORITY;
typedef WORD UWORD;
typedef struct _CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
enum THREADINFOCLASS
{
ThreadBasicInformation,
};
void* GetThreadStackTopAddress(HANDLE hProcess, HANDLE hThread)
{
bool loadedManually = false;
HMODULE module = GetModuleHandle("ntdll.dll");
if (!module)
{
module = LoadLibrary("ntdll.dll");
loadedManually = true;
}
NTSTATUS (__stdcall *NtQueryInformationThread)(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength);
NtQueryInformationThread = reinterpret_cast<decltype(NtQueryInformationThread)>(GetProcAddress(module, "NtQueryInformationThread"));
if (NtQueryInformationThread)
{
NT_TIB tib = {0};
THREAD_BASIC_INFORMATION tbi = {0};
NTSTATUS status = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), nullptr);
if (status >= 0)
{
ReadProcessMemory(hProcess, tbi.TebBaseAddress, &tib, sizeof(tbi), nullptr);
if (loadedManually)
{
FreeLibrary(module);
}
return tib.StackBase;
}
}
if (loadedManually)
{
FreeLibrary(module);
}
return nullptr;
}
void __stdcall Test()
{
for (int i = 0; i < 10; ++i)
{
printf("Hi. ");
Sleep(500);
}
}
int main()
{
std::cout<<GetThreadStackTopAddress(GetCurrentProcess(), GetCurrentThread())<<"\n";
DWORD threadID = 0;
HANDLE hThread = CreateThread(nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(Test), nullptr, 0, &threadID);
std::cout<<GetThreadStackTopAddress(GetCurrentProcess(), hThread)<<"\n\n";
CloseHandle(hThread);
Sleep(7000);
return 0;
}