当前位置:首页 > c++ > 正文内容

C++如何实现挂起进程、恢复进程

xuwenyan2年前 (2021-02-22)c++739

1:枚举进程的所有线程,使用SuspendThread函数挂起每一个线程,需要恢复时使用ResumeThread函数恢复。因为挂起和恢复的顺序是不可预知的,所以可能会导致一些多线程程序崩溃,单线程程序可能不受影响。

void SuspendProcess(DWORD process_id) { 
  HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);    
  THREADENTRY32 threadEntry; 
  threadEntry.dwSize = sizeof(THREADENTRY32);       
  Thread32First(hThreadSnapshot, &threadEntry);
  do {
    if (threadEntry.th32OwnerProcessID == process_id) {
      HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE,threadEntry.th32ThreadID);
      SuspendThread(hThread);
      CloseHandle(hThread); 
    }
  } while (Thread32Next(hThreadSnapshot, &threadEntry));   
  CloseHandle(hThreadSnapshot); 
}

void ResumeProcess(DWORD process_id) { 
  HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);    
  THREADENTRY32 threadEntry; 
  threadEntry.dwSize = sizeof(THREADENTRY32);       
  Thread32First(hThreadSnapshot, &threadEntry);
  do {
    if (threadEntry.th32OwnerProcessID == process_id) {
      HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE,threadEntry.th32ThreadID);
      ResumeThread(hThread);
      CloseHandle(hThread); 
    }
  } while (Thread32Next(hThreadSnapshot, &threadEntry));   
  CloseHandle(hThreadSnapshot); 
}

2:使用NtSuspendProcess挂起进程,这个方法在xp系统就已经支持,使用NtResumeProcess函数恢复。

typedef LONG (NTAPI *NtSuspendProcess)(IN HANDLE ProcessHandle); 
void SuspendProcess(DWORD process_id) {
  HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id));
  NtSuspendProcess pfnNtSuspendProcess = 
 (NtSuspendProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess");
  pfnNtSuspendProcess(processHandle); 
  CloseHandle(processHandle); 
}

typedef LONG (NTAPI *NtResumeProcess)(IN HANDLE ProcessHandle); 
void ResumeProcess(DWORD process_id) {
  HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id));
  NtResumeProcess pfnNtResumeProcess = 
 (NtResumeProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtResumeProcess");
  pfnNtResumeProcess(processHandle); 
  CloseHandle(processHandle); 
}

3:使用调试器的方式,调用DebugActiveProcess函数挂起,调用DebugActiveProcessStop函数恢复。

void SuspendProcess(DWORD process_id) {
  DebugActiveProcess(process_id); 
}

void ResumeProcess(DWORD process_id) {
  DebugActiveProcessStop(process_id); 
}


    文章作者:xuwenyan
    版权声明:本文为本站原创文章,转载请注明出处,非常感谢,如版权漏申明或您觉得任何有异议的地方欢迎与本站取得联系。

    扫描二维码推送至手机访问。

    版权声明:本文由艺文笔记发布,如需转载请注明出处。

    本文链接:https://www.xuwenyan.com/archives/233

    分享给朋友:

    “C++如何实现挂起进程、恢复进程” 的相关文章

    uafxcwd.lib(afxmem.obj) : error LNK2005:

    uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)"解决办法

    如果在编译MFC程序的时候出现下列及类似的错误: 1˃uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已经在 LIBCMTD.lib(new...

    C++ 获取进程所在目录(进程全路径)

    C++ 获取进程所在目录(进程全路径)

    打开windows任务管理器,会看到很多的进程在运行,随机挑选一个,如何通过c++代码获取某一个进程的所在全路径呢?这也是在windows软件开发中经常遇到的需求。通过进程名获取进程全路径由于可能很多进程叫同一个名字,所以获得的结果也有可能是多个#include <windows.h...

    c++函数模板参数类型限定

    c++函数模板参数类型限定

    函数模板函数模板可以实现对不同数据类型做统一操作,比如比较两个数据的大小:template<typename T> bool compare(T& a,T& b) {   return a...

    static_assert和assert有什么区别?

    static_assert和assert有什么区别?

    static_assert和assert都是断言,都可用于判断一个条件是否成立,并且在条件不成立时及时给出错误提示。那它们用什么不同和需要注意的地方呢? 1:static_assert在编译期执行,而assert在运行期执行。2:static_assert无论在debug模式还是relea...

    c++为什么不能在构造函数里调用虚函数?

    c++为什么不能在构造函数里调用虚函数?

    c++为什么不能在构造函数里调用虚函数? c++的构造顺序先构造父类,然后构造子类,析构顺序相反。 如果在构造函数调用虚函数,例如:ClassB继承于ClassA,如果在ClassA的构造函数里调用虚函数,此时因为ClassB并没有构造,所以ClassB的成员都没有初始化,如果编译执行...

    排序算法-选择排序

    排序算法-选择排序

    选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。时间复杂度O(n²)最坏情况合适发生?数组顺序与需要的顺序正好相反。步骤首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。再...