精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源,禁止转载和任何形式的非法内容使用,违者必究
Norton工具包中有一个工具叫作CrashGuard,它在后台监控系统,在系统出非法操作时,它能够对非法操作进行控制。下面是我提供的一个例子,它能够查找系统的报错窗口并且提供了两种处理办法;这个技巧只是一个方向,用于拓宽大家的视野,请不要刻意去使用它。
原理如下:使用API函数EnumWindows来遍历所有窗口,在遍历时进行特征判断;判断有结果后根据选项进行处理。
工程描述如下:
common.h
#include <afxtempl.h>
#define TITLE_SIZE 64
#define PROCESS_SIZE MAX_PATH
BOOL KillProcessWithID(DWORD ErrorID, BOOL fForce);
BOOL SetPrivilege( HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege );
common.c
#include "stdafx.h"
#include <windows.h>
#include <winperf.h> // for Windows NT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h> // for Windows 95
#include "common.h"
BOOL KillProcessWithID(DWORD ErrorID, BOOL fForce)
{
HANDLE hProcess;
HANDLE hToken;
if(!OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken
)) {
DWORD m_error=GetLastError();
CString temp;
itoa(m_error,(LPTSTR)temp.GetBufferSetLength(10),10);
AfxMessageBox(temp);
return FALSE;
}
if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
{
CloseHandle(hToken);
return FALSE;
}
if (fForce)
{
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ErrorID);
if (hProcess)
{
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ErrorID);
if (hProcess == NULL)
{
return FALSE;
}
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
if (!TerminateProcess( hProcess, 1 ))
{
CloseHandle( hProcess );
return FALSE;
}
CloseHandle( hProcess );
CloseHandle(hToken);
return TRUE;
}
}
return TRUE;
}
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges( hToken, FALSE, tp,sizeof(TOKEN_PRIVILEGES),
&tpPrevious, &cbPrevious);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}
AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
}
UpdateData();
EnumWindows(EnumWindowsProc,(LPARAM)this);
上面需要的EnumWindowsProc的定义如下:
BOOL CALLBACK
EnumWindowsProc(
HWND hwnd,
LPARAM lParam
)
{
CErrorProcessDlg * m_pDlg=(CErrorProcessDlg *)lParam;
DWORD pid = 0;
CHAR buf[TITLE_SIZE];
if (!GetWindowThreadProcessId( hwnd, &pid )) {
return TRUE;
}
if (GetWindowText( hwnd, buf, sizeof(buf) ))
{
CString find(buf);
int j=find.Find("应用程序错误",1);
if(j>0) {
if(m_pDlg->m_iChoice==0) {//关闭窗口
SendMessage(hwnd,WM_DESTROY,NULL,NULL);
SendMessage(hwnd,WM_NCDESTROY,NULL,NULL);
}
else {//杀死进程
KillProcessWithID(pid,TRUE);
}
}
}
return TRUE;
}
本程序在NT4.0 + VC6.0环境下调试通过。