守护进程

守护进程

WaitForMultipleObjects 可以等待进程、线程、事件、信号、mutex等,可以用它实现进程保护,在需要保护的进程被结束时,重新启动保护进程,可以达到普通用户无法正常结束进程的目的,如保护进程和被保护进程互相保护,那就更难结束了。

代码:
stdafx.h

#define WM_PROCESSEND WM_USER+1
typedef struct PROCESS_STRUCT
{
    DWORD PID;
    HANDLE hProcess;
    TCHAR name[64];
    TCHAR path[MAX_PATH];
}PROCESS_STRUCT,*PPROCESS_STRUCT;

SelectProcess.cpp

BEGIN_MESSAGE_MAP(SelectProcess, CDialogEx)
    ON_BN_CLICKED(IDC_SELECT, &SelectProcess::OnBnClickedSelect)
END_MESSAGE_MAP()

// SelectProcess 消息处理程序
BOOL SelectProcess::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    CRect rect;
    m_list.GetWindowRect(&rect);
    m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
    m_list.InsertColumn(0, _T("ID"), LVCFMT_LEFT, rect.Width() / 15, 0);
    m_list.InsertColumn(1, _T("句柄"), LVCFMT_LEFT, 2*rect.Width() / 15, 1);
    m_list.InsertColumn(2, _T("进程名"), LVCFMT_LEFT, 3*rect.Width() / 15, 2);
    m_list.InsertColumn(3, _T("路径"), LVCFMT_LEFT, 8*rect.Width() / 15, 3);
    PROCESSENTRY32 pe;
    auto handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(handle, &pe))
        return FALSE;
    while (TRUE)
    {
        pe.dwSize = sizeof(PROCESSENTRY32);
        if (!Process32Next(handle, &pe))
            break;
        PPROCESS_STRUCT pProcess = new PROCESS_STRUCT;
        pProcess->PID = pe.th32ProcessID;
        pProcess->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
        if (INVALID_HANDLE_VALUE == pProcess->hProcess)
        {
            delete pProcess;
            continue;
        }
        if (!GetModuleFileNameEx(pProcess->hProcess, NULL, pProcess->path, sizeof(pProcess->path)))
        {
            delete pProcess;
            continue;
        }
        memcpy_s(pProcess->name, sizeof(pProcess->name), pe.szExeFile, sizeof(pProcess->name));
        m_vec.push_back(pProcess);
    }
    CloseHandle(handle);
    CString s;
    for (size_t i = 0;i < m_vec.size();++i)
    {
        s.Format(_T("%u"), m_vec[i]->PID);
        m_list.InsertItem(i, s);
        s.Format(_T("%p"), m_vec[i]->hProcess);
        m_list.SetItemText(i, 1, s);
        m_list.SetItemText(i, 2, m_vec[i]->name);
        m_list.SetItemText(i, 3, m_vec[i]->path);
    }

    return TRUE;  
}

void SelectProcess::OnBnClickedSelect()
{
    auto pos = m_list.GetFirstSelectedItemPosition();
    if (pos)
        m_select = m_list.GetNextSelectedItem(pos);
    if (m_select >= m_vec.size())
        m_select = -1;
    CDialogEx::OnOK();
}

ProcessProtectDlg.cpp

BEGIN_MESSAGE_MAP(CProcessProtectDlg, CDialogEx)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_ADD, &CProcessProtectDlg::OnBnClickedAdd)
    ON_BN_CLICKED(IDC_EXIT, &CProcessProtectDlg::OnBnClickedExit)
    ON_MESSAGE(WM_PROCESSEND, &CProcessProtectDlg::OnProcessend)
END_MESSAGE_MAP()

// CProcessProtectDlg 消息处理程序
BOOL CProcessProtectDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);         // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    CRect rect;
    m_list.GetWindowRect(&rect);
    m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    m_list.InsertColumn(0, _T("ID"), LVCFMT_LEFT, rect.Width() / 15, 0);
    m_list.InsertColumn(1, _T("句柄"), LVCFMT_LEFT, 2 * rect.Width() / 15, 1);
    m_list.InsertColumn(2, _T("进程名"), LVCFMT_LEFT, 3 * rect.Width() / 15, 2);
    m_list.InsertColumn(3, _T("路径"), LVCFMT_LEFT, 8 * rect.Width() / 15, 3);
    AfxBeginThread(CheckProc, this);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

UINT CProcessProtectDlg::CheckProc(LPVOID param)
{
    CProcessProtectDlg * pParent = (CProcessProtectDlg *)param;
    HANDLE handles[20] = { 0 };
    handles[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
    handles[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
    pParent->m_processList[0].hProcess = handles[0];
    pParent->m_processList[1].hProcess = handles[1];
    pParent->m_hExit = handles[0];
    pParent->m_hAdd = handles[1];
    pParent->m_listUse = 2;
    int count = pParent->m_listUse;
    CString s;
    while (TRUE)
    {
        DWORD ret = WaitForMultipleObjects(count, handles, FALSE, INFINITE);
        ret -= WAIT_OBJECT_0;
        if(ret == 0)//结束
            break;
        else if (ret == 1)//添加进程
        {
            ResetEvent(handles[ret]);
            ++pParent->m_listUse;
            count = pParent->m_listUse;
            handles[count - 1] = pParent->m_processList[pParent->m_listUse - 1].hProcess;
        }
        else if (ret > 1 && ret < 20)//进程结束
        {
            SHELLEXECUTEINFO sei;
            ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
            sei.cbSize = sizeof(SHELLEXECUTEINFO);
            sei.lpFile = pParent->m_processList[pParent->m_listUse - 1].path;
            sei.nShow = SW_SHOWDEFAULT;
            sei.fMask = SEE_MASK_NOCLOSEPROCESS;
            sei.lpVerb = _T("open");
            CloseHandle(handles[count - 1]);
            if (ShellExecuteEx(&sei))
            {
                pParent->m_processList[pParent->m_listUse - 1].hProcess = sei.hProcess;
                pParent->m_processList[pParent->m_listUse - 1].PID = GetProcessId(sei.hProcess);
                handles[count - 1] = sei.hProcess;
            }
            else
            {
                --pParent->m_listUse;
                count = pParent->m_listUse;
            }
            pParent->PostMessage(WM_PROCESSEND, 0, 0);
        }
    }
    CloseHandle(pParent->m_processList[0].hProcess);
    CloseHandle(pParent->m_processList[1].hProcess);
    return 0;
}

void CProcessProtectDlg::OnBnClickedAdd()
{
    SelectProcess dlg;
    dlg.DoModal();
    if (dlg.m_select != -1)
    {
        m_processList[m_listUse].hProcess = dlg.m_vec[dlg.m_select]->hProcess;
        m_processList[m_listUse].PID = dlg.m_vec[dlg.m_select]->PID;
        memcpy_s(m_processList[m_listUse].name, sizeof(m_processList[m_listUse].name), dlg.m_vec[dlg.m_select]->name, sizeof(dlg.m_vec[dlg.m_select]->name));
        memcpy_s(m_processList[m_listUse].path, sizeof(m_processList[m_listUse].path), dlg.m_vec[dlg.m_select]->path, sizeof(dlg.m_vec[dlg.m_select]->path));
        int pos = m_list.GetItemCount();
        if (pos > -1)
        {
            CString s;
            s.Format(_T("%u"), m_processList[m_listUse].PID);
            m_list.InsertItem(pos, s);
            s.Format(_T("%p"), m_processList[m_listUse].hProcess);
            m_list.SetItemText(pos, 1, s);
            m_list.SetItemText(pos, 2, m_processList[m_listUse].name);
            m_list.SetItemText(pos, 3, m_processList[m_listUse].path);
        }
        SetEvent(m_hAdd);
    }
}

void CProcessProtectDlg::OnBnClickedExit()
{
    SetEvent(m_hExit);
    CDialogEx::OnOK();
}

afx_msg LRESULT CProcessProtectDlg::OnProcessend(WPARAM wParam, LPARAM lParam)
{
    m_list.DeleteAllItems();
    CString s;
    for (int i = 2;i < m_listUse;++i)
    {
        s.Format(_T("%u"), m_processList[i].PID);
        m_list.InsertItem(i - 2, s);
        s.Format(_T("%p"), m_processList[i].hProcess);
        m_list.SetItemText(i - 2, 1, s);
        m_list.SetItemText(i - 2, 2, m_processList[i].name);
        m_list.SetItemText(i - 2, 3, m_processList[i].path);
    }
    return 0;
}

效果:
选择要保护的进程:
这里写图片描述
保护中的进程:
这里写图片描述
结束进程后:
这里写图片描述
代码链接:
VS2015工程:http://download.csdn.net/detail/yangyang031213/9893804
https://github.com/yangyang0312/cpp/tree/master/windows/ProcessProtect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值