VC++ 查看系统进程,获取进程关联的DLL列表

前言:

  这两天在做一个自动化测试的小工具,主要功能:给定一个进程的名字,给定若干个DLL文件名,要求检测这些DLL文件是否存在于指定的进程中;查询指定的系统服务是否在运行,记录其状态。

实现方法比较简单,主要用到了如下两个函数:

  CreateToolhelp32Snapshot():获取系统进程列表;

  EnumProcessModules():获取指定进程的所有模块;

得到系统的状态时利用_fopen()运行命令sc query XXX来实现的,使用_fopen和在cmd下运行是一个效果。测试中经常要测试”重启后、注销后、休眠后“等场景,我就列了一个这些快捷键,使用这些快捷键要求当前进程获得特权,所以

可以去MSDN上搜索这两个函数,看一下实例很容易写出来,本着拿来主义的思想,我把自己的代码整理(部分也是copy例程的)贡献出来,希望对大家有所帮助。

    实现的平台是VS2007,WIN7_SP1_x86,因为是MFC程序,所以为了使用方面我的参数大多采用CString类型。

      类中自定义了几个数据结构,主要是方便使用,简单解释一下:

PIDList := std::list<DWORD>,就是一个DWORD类型的list结构,PID号在系统中用DWORD表示的。因为同一个进程当前可能有多个实例在运行,但每个实例的PID号必然不同,所以这个结构的变量用来存储这些同名的进程列表;

DllStatusMap  := std::map<CString,BOOL>,是一个map类型,我当作关联数组来使用,CString存储的是DLL名称,BOOL表示当前的DLL有没有在指定的进程中加载;

ProcessDllMap :=std::map<DWORD,DllStatusMap>,也是一个map类型,还是当作关联数组使用,DWORD存储一个进程的ID号,DllStatusMap存储这个PID中,我们关系的那些DLL加载情况;

DllProcessMap :=std::map<CString,std::list<DWORD>>,这个是辅助的类型,从另一个角度统计DLL成功注入的进程列表,CString是DLL名称,list<DWORD>是加载了这个DLL的进程的列表。

函数列表:

PIDList GetPIDListByProcessName( CString processName )  根据进程名称获得运行实例的进程ID列表;
DllStatusMap FindDllsInProcess( DWORD pid, StringList dllList ) 根据指定的进程ID号,和关注的DLL文件名列表,得到一个关联数组,描述该进程中关注的DLL注入情况;
CString QueryServiceStatusByName( CString serviceName )根据给定的服务名称,查询服务的运行状态;
BOOL GetSystemOperationPrivilege()获得系统特权,用于进行关机、重启、休眠和注销等操作,获得特权成功后直接加一句 ExitWindowsEx(EWX_REBOOT | EWX_FORCE,SHTDN_REASON_FLAG_PLANNED);就可以进行重启了

提醒:要正常使用EnumProcessModules,需在Project-> Properties-> Linker->Input->Additional Dependencies 中输入Psapi.lib

下面是自己写的类文件,MFC的其他功能代码(包括输入验证、消息提醒、控件初始化等等不再给出,可以到最下面的资源链接下载~

P.S. 注释是用英文写的,限于作者渣子一样的英文水平,若有描述不清之处,请指正或无视~

/*
filename: ProcessUtil.h
author: nuaazdh
date: 2014-06-02

*/

#pragma once

#include "stdafx.h"
#include <atlstr.h>
#include <wtypes.h>
#include <list>
#include <map>
#include <tchar.h>
#include <tlhelp32.h>
#include <psapi.h>

typedef std::list<CString>	StringList;						// String list
typedef std::list<DWORD>	PIDList;						// Process ID (DWORD) list
typedef std::map<CString,BOOL> DllStatusMap;				// < CString: DLL's name, BOOL: injection status
typedef std::map<DWORD,DllStatusMap> ProcessDllMap;			// DWORD: process's id; DllInjectionStatus: list of dlls which are injected
typedef std::map<CString,std::list<DWORD>> DllProcessMap;	// CString: DLL's name, size_t: total counts in ProcessInjectionStatus

class CProcessUtil
{
public:
	CProcessUtil(void);
	~CProcessUtil(void);
		
	// process function list
	PIDList GetPIDListByProcessName( CString processName );				// get a list of PID by the given name of a process
	DllStatusMap FindDllsInProcess( DWORD pid, StringList dllList );	// search all DLLs associate with a process to check whether a given list DLL exist in it
	// service function list
	CString QueryServiceStatusByName( CString serviceName );			// query the status of a specific system service by given name
	BOOL GetSystemOperationPrivilege();									// get system privilege 
private:
	void CheckDllInList( DllStatusMap &dllsInProcess, CString dllName );	// check whether a dll given by parameter:dllName exist in a dlllsInProcess
	TCHAR* ExtraDllNameInPath( TCHAR* dllFullPath );		// extra module name from a full path
};

#include "StdAfx.h"
#include "ProcessUtil.h"


CProcessUtil::CProcessUtil(void)
{
}

CProcessUtil::~CProcessUtil(void)
{
}

/*
Get a list of process ids by searching current system
Input: 
	processName: the name of process
Return:
	PIDList: a list of DWORD, each one is an id of a process
*/
PIDList CProcessUtil::GetPIDListByProcessName( CString processName )
{
	// return list
	PIDList mlist;
	// convert CString to TCHAR
	int strLen = processName.GetLength();
	TCHAR* processPath = new TCHAR[strLen+1];
	ASSERT(processPath);
	lstrcpy(processPath,processName.GetBuffer(strLen));
	processName.ReleaseBuffer();

	HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	if(hProcessSnap==INVALID_HANDLE_VALUE){
		return mlist;
	}

	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(PROCESSENTRY32);
	// get all process's snapshot
	BOOL bMore=Process32First(hProcessSnap,&pe32);	
	while(bMore){
		bMore=Process32Next(hProcessSnap,&pe32);
		if(!_wcsicmp(pe32.szExeFile,processPath)){
			//PrintModules(pe32.th32ProcessID);
			mlist.push_back(pe32.th32ProcessID) ;
			continue;
		}
	}
	//clean snapshot object and free memory
	CloseHandle(hProcessSnap);
	delete[] processPath;
	processPath=NULL;
	// return list
	return mlist;

}

/*
Find a list of dlls given by dllList in a pid's all modules
Input:  
	pid: a specific id of a given process
	allList: a list of dlls' names with CString type
Output:	
	map: PID => ( DLL'sname => InjectioinStatus(TRUE/FLASE) )
*/
DllStatusMap CProcessUtil::FindDllsInProcess( DWORD pid, StringList dllList )
{
	// return value <DLL's name => exist in Process>
	DllStatusMap dllsInProcess;
	for (StringList::iterator slit=dllList.begin();
		slit!=dllList.end();
		++slit)
	{
		dllsInProcess[*slit] = FALSE;
	}

	// search for all modules in a specific process
	HMODULE hMods[1024];
	HANDLE hProcess;
	DWORD cbNeeded;

	// Get a handle to the process.
	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
		PROCESS_VM_READ,
		FALSE, pid );
	if (NULL == hProcess)
		return dllsInProcess;

	// Get a list of all the modules in this process.
	if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
	{
		for ( UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
		{
			TCHAR szModName[MAX_PATH];
			// Get the full path to the module's file.
			if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
				sizeof(szModName) / sizeof(TCHAR)))
			{
				// extra dll name
				ExtraDllNameInPath(&szModName[0]);
				// convert from TCHAR* to CString
				CString dllName;
				dllName.Format(_T("%s"),szModName);
				CheckDllInList(dllsInProcess,dllName);

			}//if
		}//for
	}//if
	// Release the handle to the process.
	CloseHandle( hProcess );

	return dllsInProcess;

}

/*
Check whether a DLL given by dllName exist in a dlllsInProcess
Input:
	dllsInProcess: <String,BOO> i.e. <DLL's name, does this DLL exist in a specific pid>
	dllName: the name of a DLL which is need to be figured out
Output: 
	null

*/
void CProcessUtil::CheckDllInList( DllStatusMap &dllsInProcess, CString dllName )
{
	for (DllStatusMap::iterator mpit=dllsInProcess.begin();
		mpit!=dllsInProcess.end();
		++mpit)
	{
		CString dllNameInList = mpit->first;
		if (!dllNameInList.CompareNoCase(dllName))
		{
			mpit->second = TRUE;
		}
	}

}

/* extract dll name from it's full path, e.g. input: C:\Windows\System32\abc.dll , return abc.dll
 */
TCHAR* CProcessUtil::ExtraDllNameInPath( TCHAR* dllFullPath )
{
	TCHAR *strPtr = dllFullPath;
	size_t len = wcslen(dllFullPath);
	size_t lastSlash=0;
	for(unsigned i=0;i<len;++i){
		if(dllFullPath[i]==_T('\\')){
			lastSlash = i;
		}
	}
	if(lastSlash==0){
		return strPtr;
	}else{
		wcsncpy_s(strPtr,len,&dllFullPath[lastSlash+1],len-lastSlash);
	}
	return strPtr;
}


/*
Make use of _fopen to query the status of a service given by serviceName
*/
CString CProcessUtil::QueryServiceStatusByName( CString serviceName )
{
	CString queryCmd = _T("sc query ") + serviceName;
	CString statusStr = _T("NULL");
	char cmd_charptr[100];
	memset(cmd_charptr,0,100);
	WideCharToMultiByte(CP_ACP,0,queryCmd,-1,cmd_charptr,80,NULL,NULL);
	FILE *pipe = _popen(cmd_charptr,"r");
	if(!pipe) return statusStr;
	char buffer[128];
	while(!feof(pipe)){
		if(fgets(buffer,128,pipe)!=NULL){
			char *pstr = strstr(buffer,"STATE");
			if(NULL != pstr){
				CString fullString(buffer);
				//CString statusString;
				int colon_pos = fullString.Find(':');
				//CString statusString = 
				fullString.Delete(0,colon_pos+4);// get the value after state
				return fullString;

			}
		}//if
	}//while
	_pclose(pipe);
	return statusStr;
}

/*
Get System previlige 
*/
BOOL CProcessUtil::GetSystemOperationPrivilege()
{
	// TODO: Add your control notification handler code here
	HANDLE hToken; // handle to process token 
	TOKEN_PRIVILEGES tkp; // pointer to token structure
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | 
		TOKEN_QUERY, &hToken); // Get the LUID for shutdown privilege.              
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
	tkp.PrivilegeCount = 1; // one privilege to set
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
	// Get shutdown privilege for this process. 
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
	// Cannot test the return value of AdjustTokenPrivileges.  
	if (GetLastError() != ERROR_SUCCESS){
		return FALSE;
	}else{
		return TRUE;
	}	
}


附完整的的MFC工程(要一分才能下载~~)

http://download.csdn.net/detail/nuaazdh/7441563



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值