如何枚举一个进程中所有的线程

Zark 2005-02-03 04:59:13
已知一个进程,即已有进程的HANDLE或进程的PID(同时具有足够的权限). 如保才能枚举出此进程中所有的线程? (至少获得所有线程的HANDLE或ID).
...全文
725 点赞 收藏 18
写回复
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
tankbattle 2005-02-25
想要不让别人用CreateRemoteThread入侵进程,只有你用另一个账号运行进程,而这个帐号权限不够才行吧,我也不明白为什么windows要留这样一个后门,许多木马可以这样藏身。
回复
ayanamiwww 2005-02-25
好,我也需要这个

Mark
回复
q2a2z2 2005-02-22
mark
回复
pepsi1980 2005-02-05
应该在创建的时候拦截。
回复
xzqchat 2005-02-05
后一个问题有点奇怪?这样的区别感觉没有意义。

一、如果想保护自己的机器,那么首先自己的程序要抢先运行,从而拦截 CreateRemoteThread,才可能知道。

二、至于说,是 CreateRemoteThread 还是 CreateThread 地判断来保证不被注入,个人觉得完全没有意思。
因为,我可以在 CreateRemoteThread 中在 CreateThread,这样,你是无法达到你的目的的。因为,我用
CreateThread 创建的还在,我却可以退出 CreateRemoteThread 的。
回复
DentistryDoctor 2005-02-04
得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?
应该无法判断吧。
回复
kingzai 2005-02-04
不太好判断.
windows系统创建一个线程的唯一方法是调用API CreatThread函数(__beginthreadex之类的都要在内部调用他创建新线程)。windows核心编程说,在win2000下,系统用CreateRemoteThread函数来创建线程,CreateThread在内部调用CreateRemoteThread。
回复
hyamw 2005-02-04
这个就不会了。 汗~ :(
回复
Zark 2005-02-03
十分感谢诸位的帮助.

再追问一句,得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?
回复
smartzkh 2005-02-03
努力学习一下
回复
Jimmy_Xia 2005-02-03
收藏
回复
xuzheng318 2005-02-03
windows程序设计!
回复
kingzai 2005-02-03
The following example obtains a list of running threads for the specified process. First, the RefreshThreadList function takes a snapshot of the currently executing threads in the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Thread32First and Thread32Next functions. The parameter for RefreshThreadList is the identifier of the process whose threads will be listed.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL RefreshThreadList (DWORD dwOwnerPID)
{
HANDLE hThreadSnap = NULL;
BOOL bRet = FALSE;
THREADENTRY32 te32 = {0};

// Take a snapshot of all threads currently in the system.

hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return (FALSE);

// Fill in the size of the structure before using it.

te32.dwSize = sizeof(THREADENTRY32);

// Walk the thread snapshot to find all threads of the process.
// If the thread belongs to the process, add its information
// to the display list.

if (Thread32First(hThreadSnap, &te32))
{
do
{
if (te32.th32OwnerProcessID == dwOwnerPID)
{
printf( "\nTID\t\t%d\n", te32.th32ThreadID);
printf( "Owner PID\t%d\n", te32.th32OwnerProcessID);
printf( "Delta Priority\t%d\n", te32.tpDeltaPri);
printf( "Base Priority\t%d\n", te32.tpBasePri);
}
}
while (Thread32Next(hThreadSnap, &te32));
bRet = TRUE;
}
else
bRet = FALSE; // could not walk the list of threads

// Do not forget to clean up the snapshot object.

CloseHandle (hThreadSnap);

return (bRet);
}
回复
DentistryDoctor 2005-02-03
建议楼阅读<Windows核心编程>

回复
leecyi 2005-02-03
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL GetProcessList ()
{
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};

// Take a snapshot of all processes in the system.

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == (HANDLE)-1)
return (FALSE);

// Fill in the size of the structure before using it.

pe32.dwSize = sizeof(PROCESSENTRY32);

// Walk the snapshot of the processes, and for each process,
// display information.

if (Process32First(hProcessSnap, &pe32))
{
DWORD dwPriorityClass;
BOOL bGotModule = FALSE;
MODULEENTRY32 me32 = {0};

do
{
bGotModule = GetProcessModule(pe32.th32ProcessID,
pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32));

if (bGotModule)
{
HANDLE hProcess;

// Get the actual priority class.
hProcess = OpenProcess (PROCESS_ALL_ACCESS,
FALSE, pe32.th32ProcessID);
dwPriorityClass = GetPriorityClass (hProcess);
CloseHandle (hProcess);

// Print the process's information.
printf( "\nPriority Class Base\t%d\n",
pe32.pcPriClassBase);
printf( "PID\t\t\t%d\n", pe32.th32ProcessID);
printf( "Thread Count\t\t%d\n", pe32.cntThreads);
printf( "Module Name\t\t%s\n", me32.szModule);
printf( "Full Path\t\t%s\n\n", me32.szExePath);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = TRUE;
}
else
bRet = FALSE; // could not walk the list of processes

// Do not forget to clean up the snapshot object.

CloseHandle (hProcessSnap);
return (bRet);
}
回复
leecyi 2005-02-03
// If Windows NT:
if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
{

// Load library and get the procedures explicitly. We do
// this so that we don't have to worry about modules using
// this code failing to load under Windows 95, because
// it can't resolve references to the PSAPI.DLL.
hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
if( hInstLib == NULL )
return FALSE ;

hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
if( hInstLib2 == NULL )
return FALSE ;

// Get procedure addresses.
lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
GetProcAddress( hInstLib, "EnumProcesses" ) ;
lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
DWORD, LPDWORD)) GetProcAddress( hInstLib,
"EnumProcessModules" ) ;
lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
LPTSTR, DWORD )) GetProcAddress( hInstLib,
"GetModuleFileNameExA" ) ;
lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
if( lpfEnumProcesses == NULL ||
lpfEnumProcessModules == NULL ||
lpfGetModuleFileNameEx == NULL ||
lpfVDMEnumTaskWOWEx == NULL)
{
FreeLibrary( hInstLib ) ;
FreeLibrary( hInstLib2 ) ;
return FALSE ;
}

// Call the PSAPI function EnumProcesses to get all of the
// ProcID's currently in the system.
// NOTE: In the documentation, the third parameter of
// EnumProcesses is named cbNeeded, which implies that you
// can call the function once to find out how much space to
// allocate for a buffer and again to fill the buffer.
// This is not the case. The cbNeeded parameter returns
// the number of PIDs returned, so if your buffer size is
// zero cbNeeded returns zero.
// NOTE: The "HeapAlloc" loop here ensures that we
// actually allocate a buffer large enough for all the
// PIDs in the system.
dwSize2 = 256 * sizeof( DWORD ) ;
lpdwPIDs = NULL ;
do
{
if( lpdwPIDs )
{
HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
dwSize2 *= 2 ;
}
lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );
if( lpdwPIDs == NULL )
{
FreeLibrary( hInstLib ) ;
FreeLibrary( hInstLib2 ) ;
return FALSE ;
}
if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
{
HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
FreeLibrary( hInstLib ) ;
FreeLibrary( hInstLib2 ) ;
return FALSE ;
}
}while( dwSize == dwSize2 ) ;

// How many ProcID's did we get?
dwSize /= sizeof( DWORD ) ;

// Loop through each ProcID.
for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
{
szFileName[0] = 0 ;
// Open the process (if we can... security does not
// permit every process in the system).
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, lpdwPIDs[ dwIndex ] ) ;
if( hProcess != NULL )
{
// Here we call EnumProcessModules to get only the
// first module in the process this is important,
// because this will be the .EXE module for which we
// will retrieve the full path name in a second.
if( lpfEnumProcessModules( hProcess, &hMod,
sizeof( hMod ), &dwSize2 ) )
{
// Get Full pathname:
if( !lpfGetModuleFileNameEx( hProcess, hMod,
szFileName, sizeof( szFileName ) ) )
{
szFileName[0] = 0 ;
}
}
CloseHandle( hProcess ) ;
}
// Regardless of OpenProcess success or failure, we
// still call the enum func with the ProcID.
if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
break ;

// Did we just bump into an NTVDM?
if( _stricmp( szFileName+(strlen(szFileName)-9),
"NTVDM.EXE")==0)
{
// Fill in some info for the 16-bit enum proc.
sInfo.dwPID = lpdwPIDs[dwIndex] ;
sInfo.lpProc = lpProc ;
sInfo.lParam = lParam ;
sInfo.bEnd = FALSE ;
// Enum the 16-bit stuff.
lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
(TASKENUMPROCEX) Enum16,
(LPARAM) &sInfo);

// Did our main enum func say quit?
if(sInfo.bEnd)
break ;
}
}

HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
FreeLibrary( hInstLib2 ) ;

// If Windows 95:
}else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{


hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
if( hInstLib == NULL )
return FALSE ;

// Get procedure addresses.
// We are linking to these functions of Kernel32
// explicitly, because otherwise a module using
// this code would fail to load under Windows NT,
// which does not have the Toolhelp32
// functions in the Kernel 32.
lpfCreateToolhelp32Snapshot=
(HANDLE(WINAPI *)(DWORD,DWORD))
GetProcAddress( hInstLib,
"CreateToolhelp32Snapshot" ) ;
lpfProcess32First=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32First" ) ;
lpfProcess32Next=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32Next" ) ;
if( lpfProcess32Next == NULL ||
lpfProcess32First == NULL ||
lpfCreateToolhelp32Snapshot == NULL )
{
FreeLibrary( hInstLib ) ;
return FALSE ;
}

// Get a handle to a Toolhelp snapshot of the systems
// processes.
hSnapShot = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, 0 ) ;
if( hSnapShot == INVALID_HANDLE_VALUE )
{
FreeLibrary( hInstLib ) ;
return FALSE ;
}

// Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32) ;
bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

// While there are processes, keep looping.
while( bFlag )
{
// Call the enum func with the filename and ProcID.
if(lpProc( procentry.th32ProcessID, 0,
procentry.szExeFile, lParam ))
{
procentry.dwSize = sizeof(PROCESSENTRY32) ;
bFlag = lpfProcess32Next( hSnapShot, &procentry );
}else
bFlag = FALSE ;
}


}else
return FALSE ;

// Free the library.
FreeLibrary( hInstLib ) ;

return TRUE ;
}

回复
leecyi 2005-02-03
/*********************
EnumProc.h
*********************/
#include <windows.h>

typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
LPARAM ) ;

BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

/*********************
EnumProc.c (or .cpp)
*********************/
#include "EnumProc.h"
#include <tlhelp32.h>
#include <vdmdbg.h>

typedef struct
{
DWORD dwPID ;
PROCENUMPROC lpProc ;
DWORD lParam ;
BOOL bEnd ;
} EnumInfoStruct ;

BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

// The EnumProcs function takes a pointer to a callback function
// that will be called once per process in the system providing
// process EXE filename and process ID.
// Callback function definition:
// BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
//
// lpProc -- Address of callback routine.
//
// lParam -- A user-defined LPARAM value to be passed to
// the callback routine.
BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
{
OSVERSIONINFO osver ;
HINSTANCE hInstLib ;
HINSTANCE hInstLib2 ;
HANDLE hSnapShot ;
PROCESSENTRY32 procentry ;
BOOL bFlag ;
LPDWORD lpdwPIDs ;
DWORD dwSize, dwSize2, dwIndex ;
HMODULE hMod ;
HANDLE hProcess ;
char szFileName[ MAX_PATH ] ;
EnumInfoStruct sInfo ;

// ToolHelp Function Pointers.
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

// PSAPI Function Pointers.
BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
DWORD, LPDWORD );
DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
LPTSTR, DWORD );

// VDMDBG Function Pointers.
INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
TASKENUMPROCEX fp, LPARAM );


// Check to see if were running under Windows95 or
// Windows NT.
osver.dwOSVersionInfoSize = sizeof( osver ) ;
if( !GetVersionEx( &osver ) )
{
return FALSE ;
}

回复
hyamw 2005-02-03
CreateToolhelp32Snapshot
Takes a snapshot of the processes and the heaps, modules, and threads used by the processes.

HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);

Parameters
dwFlags
Specifies portions of the system to include in the snapshot. This parameter can be one of the following: Value Meaning
TH32CS_INHERIT Indicates that the snapshot handle is to be inheritable.
TH32CS_SNAPALL Equivalent to specifying TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD.
TH32CS_SNAPHEAPLIST Includes the heap list of the specified process in the snapshot.
TH32CS_SNAPMODULE Includes the module list of the specified process in the snapshot.
TH32CS_SNAPPROCESS Includes the process list in the snapshot.
TH32CS_SNAPTHREAD Includes the thread list in the snapshot.


th32ProcessID
Specifies the process identifier. This parameter can be zero to indicate the current process. This parameter is used when the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value is specified. Otherwise, it is ignored.


使用TH32CS_SNAPTHREAD作为参数
回复
发动态
发帖子
进程/线程/DLL
创建于2007-09-28

1.5w+

社区成员

VC/MFC 进程/线程/DLL
申请成为版主
社区公告
暂无公告