前言:
这两天在做一个自动化测试的小工具,主要功能:给定一个进程的名字,给定若干个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