碧天澈水 发表于 2020-3-24 00:42

【C++】进程遍历工具

本帖最后由 碧天澈水 于 2020-3-24 00:44 编辑

学习WIN32编程的时候,做了一个进程遍历工具,支持dll注入,供大家学习参考下












部分源码:

开启程序是遍历进程信息:
//遍历进程信息,添加到列表控件
void CProcessViewDlg::GetProcessInfo()
{
    //拍进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    //获取快照失败,直接返回
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
      return;
    }

    PROCESSENTRY32 pe32 = { 0 };
    pe32.dwSize = sizeof(PROCESSENTRY32);

    //遍历进程
    if (Process32First(hSnapshot, &pe32))
    {
      int nRow = 0;
      CString strFmt;

      do
      {
            //将进程名加入列表
            m_ListCtrl.InsertItem(nRow, pe32.szExeFile);
            m_ListCtrl.SetItemData(nRow, pe32.th32ProcessID);

            //将进程ID加入列表
            strFmt.Format(_T("%d"), pe32.th32ProcessID);
            m_ListCtrl.SetItemText(nRow, 1, strFmt);

            //将父进程ID加入列表
            strFmt.Format(_T("%d"), pe32.th32ParentProcessID);
            m_ListCtrl.SetItemText(nRow, 2, strFmt);

            //获取路径
            HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);

            if (hProcess != NULL)
            {
                TCHAR szBuff = { 0 };
                DWORD dwSize = MAX_PATH;

                if (::QueryFullProcessImageName(hProcess, 0, szBuff, &dwSize))
                {
                  m_ListCtrl.SetItemText(nRow, 3, szBuff);
                }
            }

            nRow++;
      } while (Process32Next(hSnapshot, &pe32));
    }

    //关闭句柄
    CloseHandle(hSnapshot);
}


查询进程模块
//遍历模块信息,添加到列表
void CMyModuleInfoDlg::GetModuleInfo()
{
    //拍进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_ProcessId);

    //获取快照失败,直接返回
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
      return;
    }

    MODULEENTRY32me32 = { 0 };
    me32.dwSize = sizeof(MODULEENTRY32);

    //遍历进程
    if (Module32First(hSnapshot, &me32))
    {
      int nRow = 0;
      CString strFmt;

      do
      {
            //将模块路径加入列表
            m_ListCtrl.InsertItem(nRow, me32.szExePath);

            //将模块基地址加入列表
            strFmt.Format(_T("0x%016X"), me32.modBaseAddr);
            m_ListCtrl.SetItemText(nRow, 1, strFmt);

            //将模块大小加入列表
            strFmt.Format(_T("0x%016X"), me32.modBaseSize);
            m_ListCtrl.SetItemText(nRow, 2, strFmt);

            nRow++;
      } while (Module32Next(hSnapshot, &me32));
    }

    //关闭句柄
    CloseHandle(hSnapshot);

查询进程线程
/获取线程信息,添加到列表控件
void CMyThreadInfoDlg::GetThreadInfo()
{
    //拍进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

    //获取快照失败,直接返回
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
      return;
    }

    THREADENTRY32te32 = { 0 };
    te32.dwSize = sizeof(THREADENTRY32);

    //遍历进程
    if (Thread32First(hSnapshot, &te32))
    {
      int nRow = 0;
      CString strFmt;

      do
      {
            if (m_ProcessId == te32.th32OwnerProcessID)
            {
                //显示线程ID
                strFmt.Format(_T("%d"), te32.th32ThreadID);
                m_ListCtrl.InsertItem(nRow, strFmt);

                //显示线程优先级
                strFmt.Format(_T("%d"), te32.tpBasePri);
                m_ListCtrl.SetItemText(nRow, 1, strFmt);

                nRow++;
            }
      } while (Thread32Next(hSnapshot, &te32));
    }
    //关闭句柄
    CloseHandle(hSnapshot);
}

查询进程窗口
//枚举窗口回调函数
BOOL CALLBACK CMyWindowInfoDlg::EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    CMyWindowInfoDlg *pThis = (CMyWindowInfoDlg *)lParam;

    CString csFmt;
    DWORD dwProcessId = 0;
    DWORD dwThreadId = 0;

    //获取窗口的进程ID和线程ID
    dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId);

    if (dwProcessId == pThis->m_ProcessId)
    {
      //获取行数
      int nRows = pThis->m_ListCtrl.GetItemCount();

      //显示窗口句柄
      csFmt.Format(_T("0x%08X"), hwnd);
      pThis->m_ListCtrl.InsertItem(nRows, csFmt);

      //显示窗口标题
      TCHAR szWndText = { 0 };
      ::GetWindowText(hwnd, szWndText, MAX_PATH);
      pThis->m_ListCtrl.SetItemText(nRows, 1, szWndText);

      //显示窗口类名
      TCHAR szWndClassName = { 0 };
      ::GetClassName(hwnd, szWndClassName, MAX_PATH);
      pThis->m_ListCtrl.SetItemText(nRows, 2, szWndClassName);

      //显示进程ID
      csFmt.Format(_T("%d"), dwProcessId);
      pThis->m_ListCtrl.SetItemText(nRows, 3, csFmt);

      //显示线程ID
      csFmt.Format(_T("%d"), dwThreadId);
      pThis->m_ListCtrl.SetItemText(nRows, 4, csFmt);
    }

    return TRUE;
}

DLL注入
/响应注入按钮消息
void CMyRemoteDllDlg::OnBnClickedInject()
{
    //先获取注入的dll
    CString strDllPath;
    m_EditBrowse.GetWindowText(strDllPath);

    if (strDllPath.IsEmpty())
    {
      MessageBox(_T("请填入路径"), _T("提示"), MB_OK);
      return;
    }

    //获取需要注入进程的句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_ProcessId);

    //在进程中申请内存,存放dll的路径
    LPVOID pAddr = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (pAddr == NULL)
    {
      MessageBox(_T("进程申请内存失败!"), _T("提示"), MB_OK);
      return;
    }

    //将需要注入dll的路径写入需要注入DLL进程的空间中
    BOOL bRet = WriteProcessMemory(hProcess, pAddr, strDllPath.GetBuffer(), strDllPath.GetLength() * 2, NULL);

    //注入DLL
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, pAddr, 0, NULL);

    if (hThread == NULL)
    {
      MessageBox(_T("注入DLL失败!"), _T("提示"), MB_OK);
      return;
    }

    MessageBox(_T("注入dll成功"), _T("提示"), MB_OK);
}



链接:https://pan.baidu.com/s/190pq9lSosVJlvsfNqgmd9g提取码:e6u8
页: [1]
查看完整版本: 【C++】进程遍历工具