VC++資訊保安程式設計(5)實現程序監視清除多餘程序
阿新 • • 發佈:2019-01-31
建立多程序處理程式的時候,需要對多程序進行監視,例如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; }