根据线程ID找出其所在的模块名

从硬盘中找出来的一段代码。已不知道原始出处了。贴出来。

#define   WIN32_LEAN_AND_MEAN  
#define   _WIN32_WINNT   0x400  
#include   <stdio.h>  
#include   <tchar.h>  
#include   <locale.h>  
#include   <windows.h>  
#include   <psapi.h>  
#include   <Tlhelp32.h>  

#pragma   comment   (lib,   "psapi.lib")  

//  
//   Thread   Information   Classes  
//  

typedef   enum   _THREADINFOCLASS   {  
ThreadBasicInformation,  
ThreadTimes,  
ThreadPriority,  
ThreadBasePriority,  
ThreadAffinityMask,  
ThreadImpersonationToken,  
ThreadDescriptorTableEntry,  
ThreadEnableAlignmentFaultFixup,  
ThreadEventPair_Reusable,  
ThreadQuerySetWin32StartAddress,  
ThreadZeroTlsCell,  
ThreadPerformanceCount,  
ThreadAmILastThread,  
ThreadIdealProcessor,  
ThreadPriorityBoost,  
ThreadSetTlsArrayAddress,  
ThreadIsIoPending,  
ThreadHideFromDebugger,  
ThreadBreakOnTermination,  
MaxThreadInfoClass  
}   THREADINFOCLASS;  

typedef   struct   _CLIENT_ID   {  
HANDLE   UniqueProcess;  
HANDLE   UniqueThread;  
}   CLIENT_ID;  
typedef   CLIENT_ID   *PCLIENT_ID;  

typedef   struct   _THREAD_BASIC_INFORMATION   {   //   Information   Class   0  
LONG           ExitStatus;  
PVOID         TebBaseAddress;  
CLIENT_ID   ClientId;  
LONG   AffinityMask;  
LONG   Priority;  
LONG   BasePriority;  
}   THREAD_BASIC_INFORMATION,   *PTHREAD_BASIC_INFORMATION;  

extern   "C"   LONG   (__stdcall   *ZwQueryInformationThread)   (  
IN   HANDLE   ThreadHandle,  
IN   THREADINFOCLASS   ThreadInformationClass,  
OUT   PVOID   ThreadInformation,  
IN   ULONG   ThreadInformationLength,  
OUT   PULONG   ReturnLength   OPTIONAL  
)   =   NULL;  


extern   "C"   LONG   (__stdcall   *RtlNtStatusToDosError)   (  
IN     ULONG   status)   =   NULL;  

BOOL   ShowThreadInfo   (DWORD   tid)  
{  
THREAD_BASIC_INFORMATION         tbi;  
PVOID                                               startaddr;  
LONG                                                 status;  
HANDLE                                             thread,   process;  

thread   =   ::OpenThread   (THREAD_ALL_ACCESS,   FALSE,   tid);  
if   (thread   ==   NULL)  
   return   FALSE;  

status   =   ZwQueryInformationThread   (thread,    
   ThreadQuerySetWin32StartAddress,    
   &startaddr,    
   sizeof   (startaddr),    
   NULL);  

if   (status   <   0)  
{  
   CloseHandle   (thread);  
   SetLastError   (RtlNtStatusToDosError   (status));  
   return   FALSE;  
};  

_tprintf   (TEXT   ("线程   %08x   的起始地址为   %p\n"),    
   tid,    
   startaddr);  

status   =   ZwQueryInformationThread   (thread,    
   ThreadBasicInformation,    
   &tbi,    
   sizeof   (tbi),    
   NULL);  

if   (status   <   0)  
{  
   CloseHandle   (thread);  
   SetLastError   (RtlNtStatusToDosError   (status));  
   return   FALSE;  
};  

_tprintf   (TEXT   ("线程   %08x   所在进程ID为   %08x\n"),    
   tid,    
   (DWORD)tbi.ClientId.UniqueProcess);  

process   =   ::OpenProcess   (PROCESS_ALL_ACCESS,    
   FALSE,    
   (DWORD)tbi.ClientId.UniqueProcess);  

if   (process   ==   NULL)  
{  
   DWORD   error   =   ::GetLastError   ();  
   CloseHandle   (thread);  
   SetLastError   (error);  
   return   FALSE;  
};  

TCHAR   modname   [0x100];  
::GetModuleFileNameEx   (process,   NULL,   modname,   0x100);  

_tprintf   (TEXT   ("线程   %08x   所在进程映象为   %s\n"),    
   tid,    
   modname);  

GetMappedFileName(process,    
   startaddr,    
   modname,    
   0x100);  

_tprintf   (TEXT   ("线程   %08x   可执行代码所在模块为   %s\n"),    
   tid,    
   modname);  

CloseHandle   (process);  
CloseHandle   (thread);  
return   TRUE;  
};  

int   main   (void)  
{  
setlocale   (LC_ALL,   ".ACP");  

HINSTANCE   hNTDLL   =   ::GetModuleHandle   (TEXT   ("ntdll"));  

(FARPROC&)ZwQueryInformationThread     =  
   ::GetProcAddress   (hNTDLL,   "ZwQueryInformationThread");  

(FARPROC&)RtlNtStatusToDosError           =  
   ::GetProcAddress   (hNTDLL,   "RtlNtStatusToDosError");  

HANDLE   h   =   CreateToolhelp32Snapshot   (TH32CS_SNAPTHREAD,   0);  
THREADENTRY32   te;  
te.dwSize   =   sizeof   (te);  
if   (Thread32First   (h,   &te))  
{  
   do  
   {  
    if   (ShowThreadInfo   (te.th32ThreadID))  
    {  
    }  
    else  
    {  
     _tprintf   (TEXT("无法获得线程   %08x   的相关信息,错误代码为   %d\n"),    
      te.th32ThreadID,   GetLastError   ());  
    };  
   }   while   (Thread32Next   (h,   &te));  
};  
CloseHandle   (h);  
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过线ID获取所在的模块地址,可以使用Windows API中的 `EnumProcessModules` 和 `GetModuleInformation` 函数。以下是一个示例代码: ```c++ #include <windows.h> #include <iostream> #include <psapi.h> int main() { DWORD processId = GetCurrentProcessId(); HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); if (hProcess == NULL) { std::cout << "Error: OpenProcess failed.\n"; return 1; } DWORD threadId = 1234; // 假设要获取的线ID为1234 HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId); if (hThread == NULL) { std::cout << "Error: OpenThread failed.\n"; CloseHandle(hProcess); return 1; } HMODULE hModules[1024]; DWORD cbNeeded; if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) { for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { MODULEINFO mi; if (GetModuleInformation(hProcess, hModules[i], &mi, sizeof(mi))) { if (mi.lpBaseOfDll <= hThread && hThread < (mi.lpBaseOfDll + mi.SizeOfImage)) { std::cout << "Thread " << threadId << " is in module " << (LPVOID)hModules[i] << std::endl; break; } } } } CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 在这个示例代码中,我们先打开当前进程和要查询的线程,然后使用 `EnumProcessModules` 函数获取当前进程中所有模块的句柄,使用 `GetModuleInformation` 函数获取每个模块的基址和大小,然后遍历每个模块,判断线程是否在该模块范围内。如果到了线程所在的模块,就输模块的地址。 注意,这个示例代码假设需要查询的线ID为1234,你需要将它替换为你实际需要查询的线ID

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值