【文起】豆子爱蟹儿,没有你,我不可能坚持不懈的去思考,为了我们的幸福奋斗
第四章的程序
1、 首先理解下面这个函数:
HANDLE CreateToolhelp32Snapshot( DWORD dwFlags,DWORD th32ProcessID)
dwFlags的取值如下:
u TH32CS_INHERIT - 声明快照句柄是可继承的。
u TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。
u TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。
u TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的进程的所有的模块。
u TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程。
u TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。
th32ProcessID 取值为0,则认为取系统值。
如CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
就是给系统中所有进程取快照,此时一种模块只会出现一次(可能很多进程调用了同一个模块,但是取出的模块只会有一个)
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, th32ProcessID);
给进程ID为th32ProcessID 的进程取快照,此时会把该进程下所有的模块都会取出来。
2、 方法:
2.1取出系统中所有进程,添加到CComBox中
void CProcessInformationDlg::GetProcessInfo()
{
CComboBox *pBox = (CComboBox *)GetDlgItem(IDC_COMBO1);
pBox->ResetContent();
pBox->RedrawWindow(NULL,0,0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (INVALID_HANDLE_VALUE == hProcessSnap )
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
BOOL bMore = Process32First(hProcessSnap,&pe32);
while (bMore)
{
TCHAR sz[1024];
PCTSTR pszExeFile = _tcsrchr(pe32.szExeFile,TEXT('\\'));
if (NULL == pszExeFile)
{
pszExeFile = pe32.szExeFile;
}
else
{
pszExeFile++;
}
wsprintf(sz,TEXT("%s (0x%08x)"),pszExeFile,pe32.th32ProcessID);
//int n = pBox->GetCount();
pBox->AddString(sz);
bMore = Process32Next(hProcessSnap,&pe32);
}
pBox->SetCurSel(0);
GetProcessDetailInfo();
CloseHandle(hProcessSnap);
}
2.2取出该进程的详细信息到CListBox中,包括进程名,进程ID;所调用的模块信息;包含的线程信息。
void CProcessInformationDlg::GetProcessDetailInfo()
{
CString csProcess;
DWORD dwProcessID;
CListBox *plist = (CListBox*)GetDlgItem(IDC_LIST1);
CComboBox *pBox = (CComboBox *)GetDlgItem(IDC_COMBO1);
plist->ResetContent();
int i = pBox->GetCurSel();
if (-1 == i)
{
AfxMessageBox(_T("ERR"));
}
pBox->GetLBText(i,csProcess);
/* 自己封装一个函数 */
CStingToDword(csProcess,&dwProcessID);
PROCESSENTRY32 pe32;
pe32.th32ProcessID = dwProcessID;
pe32.dwSize = sizeof(pe32);
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,dwProcessID);
if (INVALID_HANDLE_VALUE == hSnap )
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
BOOL bMore = Process32First(hSnap,&pe32);
while (bMore)
{
if(dwProcessID == pe32.th32ProcessID )
{
TCHAR sz[1024];
PCTSTR pszExeFile = pe32.szExeFile;
wsprintf(sz,TEXT("FileName:%s\r\n"),pszExeFile);
plist->AddString(sz);
wsprintf(sz,TEXT(" PID = 0x%08x, ParentPID = 0x%08x, PriorityClass = %u, Thread = %u, Heaps = %u"),
pe32.th32ProcessID,pe32.th32ParentProcessID,pe32.pcPriClassBase,pe32.cntThreads,pe32.th32DefaultHeapID);
plist->AddString(sz);
break;
}
else
{
bMore = Process32Next(hSnap,&pe32);
}
}
plist->AddString(_T(""));
plist->AddString(_T("Modules Information:"));
plist->AddString(_T("Usage BaseAddr(Image) Size Module"));
MODULEENTRY32 modle32;
modle32.th32ProcessID = dwProcessID;
modle32.dwSize = sizeof(modle32);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwProcessID);
if (INVALID_HANDLE_VALUE == hSnap )
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
bMore = Module32First(hSnap,&modle32);
while(bMore)
{
if (dwProcessID == modle32.th32ProcessID)
{
TCHAR sz[1024] = {0};
wsprintf(sz,TEXT(" %5d %p %8u %s"),
modle32.ProccntUsage,modle32.modBaseAddr,modle32.modBaseSize,modle32.szExePath);
plist->AddString(sz);
}
bMore = Module32Next(hSnap,&modle32);
}
plist->AddString(_T(""));
plist->AddString(_T("Thread Information:"));
plist->AddString(_T(" TID Priority"));
THREADENTRY32 th32;
th32.th32OwnerProcessID = dwProcessID;
th32.dwSize = sizeof(th32);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwProcessID);
if (INVALID_HANDLE_VALUE == hSnap)
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
bMore = Thread32First(hSnap,&th32);
while(bMore)
{
if (dwProcessID == th32.th32OwnerProcessID)
{
TCHAR sz[1024] = {0};
wsprintf(sz,TEXT(" 0x%08x %u"),
th32.th32ThreadID,th32.tpBasePri);
plist->AddString(sz);
}
bMore = Thread32Next(hSnap,&th32);
}
CloseHandle(hSnap);
}
2.3点击module的Menu,将module信息显示到CCombox中
void CProcessInformationDlg::GetModuleInfo()
{
CComboBox *pBox = (CComboBox *)GetDlgItem(IDC_COMBO1);
pBox->ResetContent();
pBox->RedrawWindow(NULL,0);
MODULEENTRY32 module32;
module32.dwSize = sizeof(module32);
HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
if (INVALID_HANDLE_VALUE == hModuleSnap)
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
BOOL bModule = Module32First(hModuleSnap,&module32);
while (bModule)
{
TCHAR sz[1024];
wsprintf(sz,TEXT("%s"),module32.szModule);
pBox->AddString(sz);
bModule = Module32Next(hModuleSnap,&module32);
}
pBox->SetCurSel(0);
GetModuleDetailInfo();
CloseHandle(hModuleSnap);
}
2.4 将模块详细信息写入CListBox中,包含调用该模块的process信息
这个函数有一个需要注意的地方。我们寻找调用模块的进程信息时,只能把系统中所有进程轮询,然后将每一个进程ID传入,快照出其模块信息,再去比对模块的szModule。
无法直接根据模块信息去找出调用其进程的方法。此点难住我很久,希望对你有用。
void CProcessInformationDlg::GetModuleDetailInfo()
{
WCHAR lpsz[256] = {0};
CListBox *plist = (CListBox *)GetDlgItem(IDC_LIST1);
plist->ResetContent();
CComboBox *pcom = (CComboBox *)GetDlgItem(IDC_COMBO1);
int i = pcom->GetCurSel();
pcom->GetLBText(i,lpsz);
MODULEENTRY32 module32;
module32.dwSize = sizeof(module32);
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
if (INVALID_HANDLE_VALUE == hModuleSnap)
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
BOOL bMore = Module32First(hModuleSnap,&module32);
while (bMore)
{
if (0 == _tcscmp(lpsz,module32.szModule))
{
WCHAR sz[1024] = {0};
wsprintf(sz,TEXT("PathName:%s"),module32.szExePath);
_tcscpy(lpsz,module32.szExePath);
plist->AddString(sz);
break;
}
bMore = Module32Next(hModuleSnap,&module32);
}
plist->AddString(_T("Process Information:"));
plist->AddString(_T(" PID BaseAddr Process"));
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (INVALID_HANDLE_VALUE == hProcessSnap)
{
AfxMessageBox(_T("Call CreateToolhelp32Snapshot failed"));
}
BOOL bMoreProcess = Process32First(hProcessSnap,&pe32);
while (bMoreProcess)
{
MODULEENTRY32 md32;
md32.dwSize = sizeof(md32);
md32.th32ProcessID = pe32.th32ProcessID;
HANDLE hMdSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe32.th32ProcessID);
bMore = Module32First(hMdSnap,&md32);
while(bMore)
{
if (0 == _tcscmp(lpsz,md32.szExePath) )
{
WCHAR wsz[1024] = {0};
wsprintf(wsz,TEXT(" 0x%8d %p %s"),
pe32.th32ProcessID,md32.modBaseAddr,pe32.szExeFile);
plist->AddString(wsz);
}
bMore = Module32Next(hMdSnap,&md32);
}
CloseHandle(hMdSnap);
bMoreProcess = Process32Next(hProcessSnap,&pe32);
}
CloseHandle(hProcessSnap);
CloseHandle(hModuleSnap);
}
3、至此完成书上所说例子,能详细显示出系统中进程、线程、模块的信息。
【文尾】
如果文章对您有帮助,请留下对我和蟹儿的祝福。如果需要源代码,请留下对我和蟹儿的祝福以及您的邮箱,我会在第一时间将源代码发至您邮箱。