如果可能的话,为用于创建线程的函数创建宏定义,然后在创建后将线程 ID/句柄存储在某个映射中,该映射将包含以下类型对:[ThreadID] -> [__FILE__+__LINE__ ] 。这将允许您检查线程内部的创建位置。
一个更高级的方法是使用 api 钩子,但那是很多编码。因此,您可以使用http://codefromthe70s.org/mhook22.aspx 和挂钩 CreateThread 的 api 挂钩。当您的自定义 CreateThread 函数被执行时,您可以执行原始 CreateThread 并使用其返回的句柄更新地图,如第一段所示。问题是您必须存储调用堆栈数据才能找到执行此调用的位置。您可以为此使用http://www.codeproject.com/Articles/11132/Walking-the-callstack。
即使使用第一个解决方案,您也可能会发现 __FILE__+__LINE__ 没有为您提供足够的信息,并且调用堆栈是必须的。
我用 mhook 制作了一个小型测试应用程序 - 下面是一些可能有用的代码:
typedef HANDLE(WINAPI *CreateThread_t)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
CreateThread_t fCreateThread = (CreateThread_t)GetProcAddress(LoadLibrary(L"Kernel32.dll"), "CreateThread");
HANDLE
WINAPI
MyCreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
)
{
HANDLE hret = fCreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
// Here you can add thread entry for hret with current callstack.
// You will probably want to create this thread suspended, to make
// sure it wont get executed before map gets updated. Resume it after
// map update.
//if (lpStartAddress == MyThreadProcToMonitor) {
// log things
//}
return hret;
}
int main() {
// This will hook create thread
Mhook_SetHook((PVOID*)&fCreateThread, MyCreateThread);
// App logic here
Mhook_Unhook((PVOID*)&fCreateThread);
}