Windows核心编程<读书笔记四之程序>显示系统中进程、线程、模块详细信息

 

【文起】豆子爱蟹儿,没有你,我不可能坚持不懈的去思考,为了我们的幸福奋斗

第四章的程序

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、至此完成书上所说例子,能详细显示出系统中进程、线程、模块的信息。

 

【文尾】

如果文章对您有帮助,请留下对我和蟹儿的祝福。如果需要源代码,请留下对我和蟹儿的祝福以及您的邮箱,我会在第一时间将源代码发至您邮箱。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值