7.6 实现进程挂起与恢复
挂起与恢复进程是指暂停或恢复进程的工作状态,以达到一定的控制和管理效果。在 Windows 操作系统中,可以使用系统提供的函数实现进程的挂起和恢复,以达到对进程的控制和调度。需要注意,过度使用进程挂起/恢复操作可能会造成系统性能的降低,导致死锁等问题,因此在使用时应该谨慎而慎重。同时,通过和其他进程之间协同工作,也可以通过更加灵活的方式,实现进程的协调、交互等相应的功能,从而实现更加高效和可靠的进程管理。要实现挂起进程,首先我们需要实现挂起线程,因为挂起进程的实现原理是通过调用SuspendThread函数循环将进程内的所有线程全部挂起后实现的,而要实现挂起线程则我们需要先确定指定进程内的线程信息,要实现枚举进程内的线程信息则可以通过以下几个步骤实现。
首先通过CreateToolhelp32Snapshot得到当前系统下所有的进程快照,并通过遍历进程的方式寻找是否符合我们所需要枚举的进程名,如果是则调用CreateToolhelp32Snapshot并通过传入TH32CS_SNAPTHREAD代表枚举线程,通过循环的方式遍历进程内的线程,每次通过调用OpenThread打开线程,并调用ZwQueryInformationThread查询该线程的入口信息以及线程所在的模块信息,最后以此输出即可得到当前进程内的所有线程信息。
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
using namespace std;
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
}THREADINFOCLASS;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION
{
LONG ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
LONG AffinityMask;
LONG Priority;
LONG BasePriority;
}THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
extern "C" LONG(__stdcall * ZwQueryInformationThread)
(
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
) = NULL;
// 枚举进程内的线程
BOOL EnumThread(char *ProcessName)
{
// 进程快照句柄
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 process = { sizeof(PROCESSENTRY32) };
// 遍历进程
while (Process32Next(hProcessSnap, &process))
{
// char* 转 string
string s_szExeFile = process.szExeFile;
if (s_szExeFile == ProcessName)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// 创建线程快照
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
// 为快照分配内存空间
te32.dwSize = sizeof(THREADENTRY32);
// 获取第一个线程的信息
if (!Thread32First(hThreadSnap, &te32))
{
return FALSE;
}
// 遍历线程
while (Thread32Next(hThreadSnap, &te32))
{
// 判断线程是否属于本进程
if (te32.th32OwnerProcessID == process.th32ProcessID)
{
// 打开线程
HANDLE hThread = OpenThread(
THREAD_ALL_ACCESS, // 访问权限
FALSE, // 由此线程创建的进程不继承线程的句柄
te32.th32ThreadID // 线程 ID
);
if (hThread == NULL)
{
return FALSE;
}
// 将区域设置设置为从操作系统获取的ANSI代码页
setlocale(LC_ALL, ".ACP");
// 获取 ntdll.dll 的模块句柄
HINSTANCE hNTDLL = ::GetModuleHandle("ntdll");
// 从 ntdll.dll 中取出 ZwQueryInformationThread
(FARPROC&)ZwQueryInformationThread = GetProcAddress(hNTDLL, "ZwQueryInformationThread");
// 获取线程入口地址
PVOID startaddr; // 用来接收线程入口地址
ZwQueryInformationThread(
hThread, // 线程句柄
ThreadQuerySetWin32StartAddress, // 线程信息类型 ThreadQuerySetWin32StartAddress 线程入口地址
&startaddr, // 指向缓冲区的指针
sizeof(startaddr), // 缓冲区的大小
NULL
);
// 获取线程所在模块
THREAD_BASIC_INFORMATION tbi; // _THREAD_BASIC_INFORMATION 结构体对象
TCHAR modname; // 用来接收模块全路径
ZwQueryInformationThread(
hThread, // 线程句柄
ThreadBasicInformation, // 线程信息类型,ThreadBasicInformation :线程基本信息
&tbi, // 指向缓冲区的指针
sizeof(tbi), // 缓冲区的大小
NULL
);
// 检查入口地址是否位于某模块中
GetMappedFileName(
OpenProcess( // 进程句柄
PROCESS_ALL_ACCESS, // 访问权限
FALSE, // 由此线程创建的进程不继承线程的句柄
(DWORD)tbi.ClientId.UniqueProcess // 唯一进程 ID
),
startaddr, // 要检查的地址
modname, // 用来接收模块名的指针
MAX_PATH // 缓冲区大小
);
std::cout << "线程ID: " << te32.th32ThreadID << " 线程入口: " << startaddr << " 所在模块: " << modname << std::endl;
}
}
}
}
}
int main(int argc, char* argv[])
{
EnumThread("lyshark.exe");
system("pause");
return 0;
}读者可自行编译并运行上述代码,通过调用SuspendProcess函数并以此传入需要挂起的进程PID以及一个状态,当该状态为TRUE时则代表挂起进程,而当状态值为FALSE时则代表为恢复一个进程,当一个进程被挂起后其会出现卡死的现象,当恢复后一切都会变得正常。
本文作者: 王瑞
本文链接: https://www.lyshark.com/post/5fbc3082.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]