www.pudn.com > ProcessProtect.rar > Protect.cpp


// Protect.cpp: implementation of the CProtect class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Protect.h" 
#include "psapi.h" 
#include "process.h" 
#pragma comment(lib,"psapi.lib") 
#define RESERVED_HANDLE_COUNT	2 
 
 
 
extern HANDLE g_hNewProcessEvent ; 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
DWORD CProtect::m_dwLastError = NULL ; 
 
 
CProtect::CProtect() 
{ 
	m_hCheckThread = NULL ; 
	m_hExitCheckThreadEvent = NULL ; 
	m_hNewProcessEvent = NULL ; 
	m_hStartupProcessMutex = NULL ; 
} 
 
CProtect::~CProtect() 
{ 
	::CloseHandle(m_hNewProcessEvent) ; 
	::CloseHandle(m_hStartupProcessMutex) ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::AddProcessId 
// 功能描述: 加入新的进程到保护队列中 
// 参数    : DWORD dwProcessId指定要加入到队列的进程ID 
// 返回值  : HANDLE 成功加入到保护队列返回保护名柄,否则返回NULL 
// 
//-------------------------------------------------------------------- 
HANDLE CProtect::AddProcessId(DWORD dwProcessId) 
{ 
	HANDLE hRet = (HANDLE)-1 ; 
	m_dwLastError = NULL ; 
	HANDLE hProcess = NULL ; 
	TCHAR szFileName[MAX_PATH] = {NULL} ; 
	::EnterCriticalSection(&m_criticalSection) ; 
	if(dwProcessId == ::GetCurrentProcessId()) 
	{ 
		m_dwLastError = PROCESSPROTECTE_OWNER_PROCESSID ;//不能对自身进程进行保护 
		goto __EXIT ; 
	} 
	if(GetProcessProtectCount() >= MAX_HANDLE_COUNT) 
	{ 
		m_dwLastError = PROCESSPROTECTE_PROTECTING_QUEUE_FULL ;//保存保护进程的队列已满 
		goto __EXIT ; 
	} 
	if(FindProcessProtectInfo(dwProcessId) != -1) 
	{ 
		m_dwLastError = PROCESSPROTECTE_EXSITING_PROCESSID ;//要保护的进程已在队列中 
		goto __EXIT ; 
	} 
 
	SetDebugPrivilege(TRUE) ; 
	hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId) ; 
	SetDebugPrivilege(FALSE) ; 
	if(hProcess == NULL) 
	{ 
		m_dwLastError = PROCESSPROTECTE_INVALID_PROCESSID ;//不能打开进程句柄 
		goto __EXIT ; 
	} 
 
	::GetModuleFileNameEx(hProcess,NULL,szFileName,MAX_PATH) ; 
	PROCESS_PROTECT_INFO processInfo ; 
	processInfo.pszFileName = new TCHAR[::lstrlen(szFileName)+1] ; 
	if(processInfo.pszFileName == NULL) 
	{ 
		::CloseHandle(hProcess) ; 
		m_dwLastError = PROCESSPROTECTE_OUTOF_MEMORY ;//申请可执行文件名的存放空间失败 
		goto __EXIT ; 
	} 
	::ZeroMemory(processInfo.pszFileName,::lstrlen(szFileName)+1) ; 
	processInfo.dwProcessId = dwProcessId ; 
	processInfo.hProcess = hProcess ; 
	::lstrcpy(processInfo.pszFileName,szFileName) ; 
	hRet = (HANDLE)GetFreeIndex() ; 
	m_ProcessProtectInfo[(int)hRet] = processInfo ; 
	::SetEvent(m_hNewProcessEvent) ;//设置添加新保护进程ID通知事件 
__EXIT: 
	::LeaveCriticalSection(&m_criticalSection) ; 
	return hRet ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::RemoveProcessId 
// 功能描述: 从保护队列中删除需要保存的进程 
// 参数    : HANDLE hUserHandle由AddProcessId返回的句柄 
// 返回值  : BOOL 成功移除返回TRUE,失败返回TRUE 
// 
//-------------------------------------------------------------------- 
BOOL CProtect::RemoveProcessId(HANDLE hUserHandle) 
{ 
	m_dwLastError = NULL ; 
	int nIndex = (int)hUserHandle ; 
	if(nIndex < 0 || nIndex >= MAX_HANDLE_COUNT) 
	{ 
		m_dwLastError = PROCESSPROTECTE_NOT_FOUND_PROCESSID ;//要删除的进程ID找不到 
		return FALSE ; 
	} 
	BOOL bRet = FALSE ; 
	::EnterCriticalSection(&m_criticalSection) ; 
	if(m_ProcessProtectInfo[nIndex].dwProcessId) 
	{ 
		::CloseHandle(m_ProcessProtectInfo[nIndex].hProcess) ; 
		delete[] m_ProcessProtectInfo[nIndex].pszFileName ; 
		::ZeroMemory(&m_ProcessProtectInfo[nIndex],sizeof(PROCESS_PROTECT_INFO)) ; 
		::SetEvent(m_hNewProcessEvent) ; 
		bRet = TRUE ; 
	} 
	else 
	{ 
		m_dwLastError = PROCESSPROTECTE_NOT_FOUND_PROCESSID ;//要删除的进程ID找不到 
	} 
	::LeaveCriticalSection(&m_criticalSection) ; 
	return bRet ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::SetDebugPrivilege 
// 功能描述: 调整指定进行的调试特权是否有效 
// 参数    : BOOL bEnable指定调试特权是否有效 
// 返回值  : BOOL 成功设置返回TRUE,失败返回FALSE 
// 
//-------------------------------------------------------------------- 
BOOL CProtect::SetDebugPrivilege(BOOL bEnable) 
{ 
	BOOL bRet = FALSE ; 
	HANDLE hToken = NULL ; 
	HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,::GetCurrentProcessId()) ; 
	if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&hToken)) 
	{ 
		goto __EXIT ; 
	} 
	LUID Luid ; 
	if(!::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid)) 
	{ 
		goto __EXIT ; 
	} 
	TOKEN_PRIVILEGES newPrivilege ; 
	newPrivilege.PrivilegeCount = 1 ; 
	newPrivilege.Privileges[0].Luid = Luid ; 
	newPrivilege.Privileges[0].Attributes = //设置调试特权属性 
											bEnable ?  
											SE_PRIVILEGE_ENABLED :  
											SE_PRIVILEGE_ENABLED_BY_DEFAULT ; 
	if(!::AdjustTokenPrivileges(hToken,FALSE,&newPrivilege, 
		sizeof(TOKEN_PRIVILEGES),NULL,NULL)) 
	{ 
		goto __EXIT ; 
	} 
	bRet = TRUE ; 
__EXIT: 
	if(hProcess) 
	{ 
		::CloseHandle(hProcess) ; 
	} 
	if(hToken) 
	{ 
		::CloseHandle(hToken) ; 
	} 
	return bRet ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : __stdcall CProtect::CheckProcessThreadProc 
// 功能描述: 检查进程是否被关闭线程 
// 参数    : LPVOID pContext传递CProtect类的对象指针 
// 返回值  : unsigned int 总是返回NULL 
// 
//-------------------------------------------------------------------- 
unsigned int __stdcall CProtect::CheckProcessThreadProc(LPVOID pContext) 
{ 
	CProtect* pObject = (CProtect*)pContext ; 
	LPCRITICAL_SECTION pCriticalSection = &pObject->m_criticalSection ; 
	HANDLE hMutex = pObject->m_hStartupProcessMutex ; 
	HANDLE arrayHandle[RESERVED_HANDLE_COUNT+MAX_HANDLE_COUNT] =  
	{ 
		pObject->m_hExitCheckThreadEvent, 
		pObject->m_hNewProcessEvent  
	} ; 
	int nHandleCount = RESERVED_HANDLE_COUNT ; 
 
	do 
	{ 
		DWORD dwResult =  
			::WaitForMultipleObjects(nHandleCount,arrayHandle,FALSE,INFINITE) ; 
		int nIndex = dwResult - WAIT_OBJECT_0 ; 
		 
		if(nIndex == 0)//退出线程 
		{ 
			break ; 
		} 
		else if(nIndex == 1)//有新的进程需要监视 
		{ 
			::EnterCriticalSection(pCriticalSection) ; 
			::ResetEvent(arrayHandle[nIndex]) ; 
			nHandleCount = pObject->ResetProcessHandle(arrayHandle+RESERVED_HANDLE_COUNT) ; 
			nHandleCount += RESERVED_HANDLE_COUNT ; 
			::LeaveCriticalSection(pCriticalSection) ; 
		} 
		else if(nIndex>=RESERVED_HANDLE_COUNT && nIndexGetProcessProtectInfo(arrayHandle[nIndex],&processInfo) ; 
			if(nArrayId != -1 && ::WaitForSingleObject(processInfo.hProcess,NULL) == WAIT_OBJECT_0) 
			{ 
				DWORD dwNewProcessId = NULL ; 
				HANDLE hNewProcess = pObject->StartupProcess(processInfo.pszFileName,&dwNewProcessId) ; 
				::CloseHandle(processInfo.hProcess) ; 
				if(hNewProcess) 
				{ 
					pObject->m_ProcessProtectInfo[nArrayId].dwProcessId = dwNewProcessId ; 
					pObject->m_ProcessProtectInfo[nArrayId].hProcess = hNewProcess ; 
				} 
				else 
				{ 
					delete[] processInfo.pszFileName ; 
					::ZeroMemory(&pObject->m_ProcessProtectInfo[nArrayId],sizeof(PROCESS_PROTECT_INFO)) ; 
				} 
			} 
			nHandleCount = pObject->ResetProcessHandle(arrayHandle+RESERVED_HANDLE_COUNT) ; 
			nHandleCount += RESERVED_HANDLE_COUNT ; 
			::LeaveCriticalSection(pCriticalSection) ; 
			::ReleaseMutex(hMutex) ; 
		} 
	}while(TRUE) ; 
 
	return NULL ; 
} 
 
 
 
 
 
int CProtect::GetProcessProtectInfo(HANDLE hProcess, PPROCESS_PROTECT_INFO pProcessProtectInfo) 
{ 
	int nRet = -1 ; 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(m_ProcessProtectInfo[nIndex].hProcess == hProcess) 
		{ 
			*pProcessProtectInfo = m_ProcessProtectInfo[nIndex] ; 
			nRet = nIndex ; 
			break ; 
		} 
	} 
	return nRet ; 
} 
 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::GetLastError 
// 功能描述: 取得最后一次错误值 
// 返回值  : DWORD 返回最后一次错误值,如果没有错误返回NULL 
// 
//-------------------------------------------------------------------- 
DWORD CProtect::GetLastError() 
{ 
	return m_dwLastError ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::Init 
// 功能描述: 初始化进程保护模块 
// 返回值  : BOOL 成功初始化返回TRUE,否则返回FALSE 
// 
//-------------------------------------------------------------------- 
BOOL CProtect::Init() 
{ 
	m_dwLastError = NULL ; 
	unsigned int dwThreadId = NULL ; 
	if(m_hCheckThread) 
	{ 
		m_dwLastError = PROCESSPROTECTE_INITIALIZED ; 
		return FALSE ; 
	} 
	m_hNewProcessEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL) ; 
	m_hExitCheckThreadEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL) ; 
	m_hStartupProcessMutex = ::CreateMutex(NULL,FALSE,"__STARTUP_PROCESS_MUTEX_NAME") ; 
	if(!m_hNewProcessEvent || !m_hExitCheckThreadEvent || !m_hStartupProcessMutex) 
	{ 
		goto __FAILURE ; 
	} 
	try 
	{ 
		::InitializeCriticalSection(&m_criticalSection) ; 
	} 
	catch(...) 
	{ 
		goto __FAILURE ; 
	} 
	m_hCheckThread = (HANDLE) 
			::_beginthreadex(NULL,NULL,CheckProcessThreadProc,this,NULL,&dwThreadId) ; 
	if(!m_hCheckThread) 
	{ 
		::DeleteCriticalSection(&m_criticalSection) ; 
		goto __FAILURE ; 
	} 
	::ZeroMemory(m_ProcessProtectInfo,sizeof(PROCESS_PROTECT_INFO)*MAX_HANDLE_COUNT) ; 
	if(FALSE) 
	{ 
__FAILURE: 
		if(m_hNewProcessEvent) 
		{ 
			::CloseHandle(m_hNewProcessEvent) ; 
			m_hNewProcessEvent = NULL ; 
		} 
		if(m_hExitCheckThreadEvent) 
		{ 
			::CloseHandle(m_hExitCheckThreadEvent) ; 
			m_hExitCheckThreadEvent = NULL ; 
		} 
		if(m_hStartupProcessMutex) 
		{ 
			::CloseHandle(m_hStartupProcessMutex) ; 
			m_hStartupProcessMutex = NULL ; 
		} 
		m_dwLastError = PROCESSPROTECTE_INITIALIZE_FAILS ; 
		return FALSE ; 
	} 
 
	return TRUE ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::Release 
// 功能描述: 释放进程保护模块的所有资源,如果再次设置进程保护,请调用Init() 
// 返回值  : void  
// 
//-------------------------------------------------------------------- 
void CProtect::Release() 
{ 
	if(m_hCheckThread) 
	{ 
		::SetEvent(m_hExitCheckThreadEvent) ; 
		::WaitForSingleObject(m_hCheckThread,INFINITE) ; 
		::CloseHandle(m_hCheckThread) ; 
		::CloseHandle(m_hExitCheckThreadEvent) ; 
		::CloseHandle(m_hNewProcessEvent) ; 
		::CloseHandle(m_hStartupProcessMutex) ; 
		::DeleteCriticalSection(&m_criticalSection) ; 
		m_hCheckThread = NULL ; 
		m_hExitCheckThreadEvent = NULL ; 
		m_hNewProcessEvent = NULL ; 
		m_hStartupProcessMutex = NULL ; 
	} 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(m_ProcessProtectInfo[nIndex].dwProcessId) 
		{ 
			::CloseHandle(m_ProcessProtectInfo[nIndex].hProcess) ; 
			delete[] m_ProcessProtectInfo[nIndex].pszFileName ; 
		} 
	} 
	return ; 
} 
 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::StartupProcess 
// 功能描述: 创建一个进程 
// 参数    : LPTSTR pszFileName指定要创建进程的路径以及文件名 
// 返回值  : HANDLE 返回新创建的进程句柄 
// 
//-------------------------------------------------------------------- 
HANDLE CProtect::StartupProcess(LPTSTR pszFileName,LPDWORD pdwProcessId) 
{ 
	STARTUPINFO startupInfo ; 
	::ZeroMemory(&startupInfo,sizeof(STARTUPINFO)) ; 
	startupInfo.cb = sizeof(STARTUPINFO) ; 
	startupInfo.wShowWindow = SW_SHOWDEFAULT ; 
	PROCESS_INFORMATION processInfo ; 
	if(!::CreateProcess(NULL,pszFileName,NULL,NULL,FALSE,NULL,NULL,NULL,&startupInfo,&processInfo)) 
	{ 
		return NULL ; 
	} 
	else 
	{ 
		::WaitForInputIdle(processInfo.hProcess,INFINITE) ; 
	} 
	::CloseHandle(processInfo.hThread) ; 
	if(pdwProcessId) 
	{ 
		*pdwProcessId = processInfo.dwProcessId ; 
	} 
 
	return processInfo.hProcess ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::ResetProcessHandle 
// 功能描述: 刷新进程句柄放到指定的句柄缓冲区中 
// 参数    : HANDLE *pArrayHandle保存进程句柄的缓冲首指针 
// 返回值  : int 返回缓冲长度 
// 
//-------------------------------------------------------------------- 
int CProtect::ResetProcessHandle(HANDLE *pArrayHandle) 
{ 
	int nRet = 0 ; 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(m_ProcessProtectInfo[nIndex].dwProcessId) 
		{ 
			pArrayHandle[nRet++] = m_ProcessProtectInfo[nIndex].hProcess ; 
		} 
	} 
	return nRet ; 
} 
 
 
//-------------------------------------------------------------------- 
// 
// 函数名  : CProtect::GetProcessProtectCount 
// 功能描述: 取得已入队列的需要保护的进程总数 
// 返回值  : DWORD 返回保护进程的总数 
// 
//-------------------------------------------------------------------- 
DWORD CProtect::GetProcessProtectCount() 
{ 
	DWORD dwRet = NULL ; 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(m_ProcessProtectInfo[nIndex].dwProcessId) 
		{ 
			dwRet++ ; 
		} 
	} 
	return dwRet ; 
} 
 
 
int CProtect::FindProcessProtectInfo(DWORD dwProcessId) 
{ 
	int nRet = -1 ; 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(m_ProcessProtectInfo[nIndex].dwProcessId == dwProcessId) 
		{ 
			nRet = nIndex ; 
			break ; 
		} 
	} 
	return nRet ; 
} 
 
int CProtect::GetFreeIndex() 
{ 
	int nRet = -1 ; 
	for(int nIndex = 0; nIndex < MAX_HANDLE_COUNT; nIndex++) 
	{ 
		if(!m_ProcessProtectInfo[nIndex].dwProcessId) 
		{ 
			nRet = nIndex ; 
			break ; 
		} 
	} 
	return nRet ; 
}