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

来源:互联网 发布:拖欠淘宝贷款犯罪吗 编辑:程序博客网 时间:2024/04/30 03:24

前言:

  这两天在做一个自动化测试的小工具,主要功能:给定一个进程的名字,给定若干个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.hauthor: nuaazdhdate: 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 listtypedef std::list<DWORD>PIDList;// Process ID (DWORD) listtypedef std::map<CString,BOOL> DllStatusMap;// < CString: DLL's name, BOOL: injection statustypedef std::map<DWORD,DllStatusMap> ProcessDllMap;// DWORD: process's id; DllInjectionStatus: list of dlls which are injectedtypedef std::map<CString,std::list<DWORD>> DllProcessMap;// CString: DLL's name, size_t: total counts in ProcessInjectionStatusclass CProcessUtil{public:CProcessUtil(void);~CProcessUtil(void);// process function listPIDList GetPIDListByProcessName( CString processName );// get a list of PID by the given name of a processDllStatusMap FindDllsInProcess( DWORD pid, StringList dllList );// search all DLLs associate with a process to check whether a given list DLL exist in it// service function listCString QueryServiceStatusByName( CString serviceName );// query the status of a specific system service by given nameBOOL GetSystemOperationPrivilege();// get system privilege private:void CheckDllInList( DllStatusMap &dllsInProcess, CString dllName );// check whether a dll given by parameter:dllName exist in a dlllsInProcessTCHAR* 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 systemInput: processName: the name of processReturn:PIDList: a list of DWORD, each one is an id of a process*/PIDList CProcessUtil::GetPIDListByProcessName( CString processName ){// return listPIDList mlist;// convert CString to TCHARint 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 snapshotBOOL 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 memoryCloseHandle(hProcessSnap);delete[] processPath;processPath=NULL;// return listreturn mlist;}/*Find a list of dlls given by dllList in a pid's all modulesInput:  pid: a specific id of a given processallList: a list of dlls' names with CString typeOutput: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 processHMODULE 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 nameExtraDllNameInPath(&szModName[0]);// convert from TCHAR* to CStringCString 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 dlllsInProcessInput: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 outOutput: 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 statereturn fullString;}}//if}//while_pclose(pipe);return statusStr;}/*Get System previlige */BOOL CProcessUtil::GetSystemOperationPrivilege(){// TODO: Add your control notification handler code hereHANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structureOpenProcessToken(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 settkp.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



0 0
原创粉丝点击