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 ;
}