资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

如何根据线程号获取模块信息

在得到线程之后,便可以通过openThread得到HANDLE,之后通过ZwQueryInformationThread获取线程信息。

阳新网站制作公司哪家好,找创新互联建站!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。创新互联建站从2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联建站

Part1 准备:

#include

#include

#include

#pragmacomment(lib,"psapi.lib")  

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;

主函数中需要做的准备工作:

    setlocale (LC_ALL, ".ACP");

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

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

Part 2 获取相关信息

    THREAD_BASIC_INFORMATION    tbi;

    PVOID                       startaddr;

    LONG                        status;

    HANDLE                      thread, process;

        

    thread = ::OpenThread (THREAD_ALL_ACCESS, FALSE, dwThreadId);

    if (thread == NULL)

{

printf("cannot open thread handle\n");

        return FALSE;

}

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

    if (status < 0)

    {

        CloseHandle (thread);

printf("cannot get status1\n");

        return FALSE;

    };

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

    status = ZwQueryInformationThread (thread, 

            ThreadBasicInformation, 

            &tbi, 

            sizeof (tbi), 

            NULL);

    if (status < 0)

{

        CloseHandle (thread);

printf("cannot get status2\n");

        return FALSE;

};

printf("线程 %08x 所在进程ID为 %08x\n", dwThreadId, (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);

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

GetMappedFileName(process, 

startaddr, 

modname, 

0x100);

        std::string stName(pName);

std::string stModName(modname);

if(stModName.find(stName) != std::string::npos)

{

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

ret = TRUE;

}

CloseHandle (process);

CloseHandle (thread);


文章名称:如何根据线程号获取模块信息
文章起源:http://cdkjz.cn/article/ppodsi.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220