1. 程式人生 > >VC++資訊保安程式設計(5)實現程序監視清除多餘程序

VC++資訊保安程式設計(5)實現程序監視清除多餘程序

建立多程序處理程式的時候,需要對多程序進行監視,例如QQ啟動多了,記憶體很卡,就得清除一些多餘程序。

詳細請見程式碼分析,實現程序監視與清除多餘程序

#include "stdafx.h"
#include "GetAllInfo.h"
#include "GetAllInfoDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

UINT Thread(LPVOID param){
CGetAllInfoDlg *mys=(CGetAllInfoDlg*)param;
   mys->OnGetProcess();
   do{
    mys->ScanProcess();

   }while(mys->status);


return 1;
}


/////////////////////////////////////////////////////////////////////////////
// CGetAllInfoDlg dialog

CGetAllInfoDlg::CGetAllInfoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGetAllInfoDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CGetAllInfoDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	status=0;
}

void CGetAllInfoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGetAllInfoDlg)
	DDX_Control(pDX, IDC_BgetAll, m_BgetAll);
	DDX_Control(pDX, IDC_LIST1, m_list);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CGetAllInfoDlg, CDialog)
	//{{AFX_MSG_MAP(CGetAllInfoDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BgetAll, OnBgetAll)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGetAllInfoDlg message handlers

BOOL CGetAllInfoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
    TotalFileNum=0;
	fp.Open("info.txt",CFile::modeCreate|CFile::modeWrite);
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	aProcesses= new DWORD [1024];
	pagain= new DWORD[1024];
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CGetAllInfoDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CGetAllInfoDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CGetAllInfoDlg::OnBgetAll() 
{
if(!status){
		status=1;
        AfxBeginThread(&Thread,this,THREAD_PRIORITY_BELOW_NORMAL,0,0);	
        m_BgetAll.SetWindowText("暫停搜尋");
}
else{
     m_BgetAll.SetWindowText("查所有資訊");
     status=0;
}
}


void CGetAllInfoDlg::OnGetProcess()
{
DWORD cbNeeded;
//unsigned int i;
//列舉系統程序ID列表
if(!EnumProcesses( aProcesses, 1024*sizeof(DWORD), &cbNeeded ) )return;
// Calculate how many process identifiers were returned.
//計算程序數量
cProcesses1 = cbNeeded / sizeof(DWORD);
// 輸出每個程序的名稱和ID
//for ( i = 0; i < cProcesses1; i++ )PrintProcessNameAndID( aProcesses[i]);
}

void CGetAllInfoDlg::PrintProcessNameAndID(DWORD processID)
{
char szProcessName[MAX_PATH] = "unknown";

//取得程序的控制代碼
HANDLE hProcess=OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,processID);
//取得程序名稱
if ( hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
  //GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) );
//該函式得到程序檔名
  GetModuleFileNameEx(hProcess,hMod,szProcessName, sizeof(szProcessName));
//AfxMessageBox(szProcessName);
//該函式得到程序全檔名路徑
 //回顯程序名稱和ID
CloseHandle( hProcess );
}
tKillProcess(processID);
CString in;
SYSTEMTIME t;
::GetLocalTime(&t);
in.Format("%d月-%d日-%d時:%d分%d秒)殺死:",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
in+=szProcessName;
m_list.AddString(in);
}

void CGetAllInfoDlg::OnKillProcess(DWORD processID)
{

tKillProcess(processID);
}

BOOL CGetAllInfoDlg::SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;//包含訪問令牌的許可權設定資訊
LUID luid;//區域性唯一ID值
//第一個引數是系統名,為NULL,表示在本地系統查詢;
//第二個引數為要查詢的許可權名,定義在檔案 Winnt.h 中
//如果成功,返回值為非0,其在系統中的 ID 值為第三個引數所指
if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
{
 m_list.AddString("查詢許可權值錯誤"); 
return FALSE; 
}
tp.PrivilegeCount = 1; //許可權列的個數
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //使能許可權
else
tp.Privileges[0].Attributes = 0;
//設定 luid 程序的許可權
AdjustTokenPrivileges(
  hToken, 
  FALSE, 
  &tp, 
  sizeof(TOKEN_PRIVILEGES), 
  (PTOKEN_PRIVILEGES) NULL, 
  (PDWORD) NULL); 
if (GetLastError() != ERROR_SUCCESS) 
{ 
m_list.AddString("調整許可權失敗"); 
return FALSE; 
} 
return TRUE;
}

BOOL CGetAllInfoDlg::tKillProcess(DWORD pid)
{
  CString inf;
HANDLE hProcess=NULL,hProcessToken=NULL;
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize=sizeof(ver);//必須的,否則不正確
if(!GetVersionEx(&ver)){
   m_list.AddString("無法判斷當前作業系統");
   return 0;    }

if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){  //為NT,2000,XP
 //殺死所有程序包括服務,在2000以上需要提升許可權
 //開啟某個程序的訪問令牌,第一個引數為程序控制代碼,第二個引數為訪問許可權,
 //第三個引數為函式輸出的用來調整許可權的控制代碼
  if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
  {
   m_list.AddString("開啟本程序訪問令牌失敗!");
  return 0;
  }
//SE_DEBUG_NAME 為要求除錯程序的許可權
  if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
  {
    m_list.AddString("設定許可權錯誤!");
   return 0;
}

  if((hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,pid))==NULL)
  {
  m_list.AddString("開啟程序失敗");
  return 0;
  }
  if(!TerminateProcess(hProcess,1))//m_list.AddString("殺死程序成功\n");
  //else 
  m_list.AddString("不能殺死程序\n");
}
  else{//是95,98作業系統
   hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, DWORD(pid));
  if(!TerminateProcess(hProcess,1))  //m_list.AddString("殺死程序成功\n");
  //else 
  m_list.AddString("不能殺死程序\n");
}
     CloseHandle(hProcess);
 
return 1;
}

void CGetAllInfoDlg::ScanProcess()
{
DWORD cbNeeded, cProcesses2;
//列舉系統程序ID列表
if(!EnumProcesses( pagain, 1024*sizeof(DWORD), &cbNeeded ) )return;
// Calculate how many process identifiers were returned.
//計算程序數量

cProcesses2 = cbNeeded / sizeof(DWORD);
//for ( int i1 = 0; i1 < cProcesses2; i1++ )PrintProcessNameAndID(pagain[i1]);


for(DWORD i=0;i<cProcesses2;i++){
   if(!IsHave(pagain[i]))PrintProcessNameAndID(pagain[i]);
	}
}

int CGetAllInfoDlg::IsHave(DWORD id)
{
int flag=0;
for(DWORD i=0;i<cProcesses1;i++)
if(aProcesses[i]==id)
{
  flag=1;
  break;
};
return  flag;
}