# 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 traumatic brain injury;
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 ("the starting address of thread % 08x is % P/N "),
TID,
Startaddr );
Status = zwqueryinformationthread (thread,
Threadbasicinformation,
& Traumatic brain injury,
Sizeof (traumatic brain injury ),
Null );
If (status <0)
{
Closehandle (thread );
Setlasterror (rtlntstatustodoserror (Status ));
Return false;
};
_ Tprintf (text ("process ID of thread % 08x is % 08x/N "),
TID,
(DWORD) traumatic brain injury. clientid. uniqueprocess );
Process =: OpenProcess (process_all_access,
False,
(DWORD) traumatic brain injury. clientid. uniqueprocess );
If (process = NULL)
{
DWORD error =: getlasterror ();
Closehandle (thread );
Setlasterror (error );
Return false;
};
Tchar modname [0x100];
: Getmodulefilenameex (process, null, modname, 0x100 );
_ Tprintf (text ("the process image of thread % 08x is % s/n "),
TID,
Modname );
Getmappedfilename (process,
Startaddr,
Modname,
0x100 );
_ Tprintf (text ("thread % 08x executable code module % 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 = createconlhelp32snapshot (th32cs_snapthread, 0 );
Threadentry32 Te;
Te. dwsize = sizeof (TE );
If (thread32first (H, & Te ))
{
Do
{
If (showthreadinfo (TE. th32threadid ))
{
}
Else
{
_ Tprintf (text ("unable to obtain information about thread % 08x, error code: % d/N "),
Te. th32threadid, getlasterror ());
};
} While (thread32next (H, & Te ));
};
Closehandle (h );
};