#include <windows.h> #include <iostream> #include <tlhelp32.h> #include <Psapi.h>
#pragma comment(lib,"psapi.lib")
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define SystemProcessesAndThreadsInformation 5 typedef DWORD(WINAPI* PQUERYSYSTEM)(UINT, PVOID, DWORD, PDWORD);
typedef enum _THREAD_STATE { StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown }THREAD_STATE;
typedef enum _KWAIT_REASON { Executive, FreePage, PageIn, PoolAllocation, DelayExecution, Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel, MaximumWaitReason }KWAIT_REASON;
typedef LONG NTSTATUS; typedef LONG KPRIORITY;
typedef struct _CLIENT_ID { DWORD UniqueProcess; DWORD UniqueThread; } CLIENT_ID, * PCLIENT_ID;
typedef struct _VM_COUNTERS { SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; } VM_COUNTERS;
typedef struct _SYSTEM_THREAD_INFORMATION { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; LONG State; LONG WaitReason; } SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, * PUNICODE_STRING;
typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; SYSTEM_THREAD_INFORMATION Threads[5]; }SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
int IsThreadSuspend(DWORD dwProcessID, DWORD dwThreadID) { int nRet = 0; NTSTATUS Status = 0;
PQUERYSYSTEM NtQuerySystemInformation = NULL; PSYSTEM_PROCESS_INFORMATION pInfo = { 0 };
NtQuerySystemInformation = (PQUERYSYSTEM) GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySystemInformation");
DWORD dwSize = 0;
Status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation, NULL, 0, &dwSize );
char* pBuff = new char[dwSize]; pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuff; if (pInfo == NULL) return -1;
Status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation, pInfo, dwSize, &dwSize ); if (!NT_SUCCESS(Status)) { delete[] pInfo; return -1; }
while (1) { if (pInfo->NextEntryDelta == 0) break;
if (pInfo->ProcessId == dwProcessID) {
for (DWORD i = 0; i < pInfo->ThreadCount; i++) { if (pInfo->Threads[i].ClientId.UniqueThread == dwThreadID) { if (pInfo->Threads[i].State == StateWait&& pInfo->Threads[i].WaitReason == Suspended) { nRet = 1; break; } } } break; } pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) + pInfo->NextEntryDelta); }
delete[] pBuff; return nRet; }
int SuspendProcess(DWORD dwProcessID, BOOL fSuspend) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
if (hSnapshot != INVALID_HANDLE_VALUE) { THREADENTRY32 te = { sizeof(te) }; BOOL fOk = Thread32First(hSnapshot, &te); for (; fOk; fOk = Thread32Next(hSnapshot, &te)) { if (te.th32OwnerProcessID == dwProcessID) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME,FALSE, te.th32ThreadID); if (hThread != NULL) { if (fSuspend) { if (IsThreadSuspend(dwProcessID, te.th32ThreadID) == 0) { SuspendThread(hThread); } else { return 0; } } else { if (IsThreadSuspend(dwProcessID, te.th32ThreadID) == 1) { ResumeThread(hThread); } else { return 0; } } } CloseHandle(hThread); } }
} CloseHandle(hSnapshot); return 1; }
int main(int argc, char *argv[]) { SuspendProcess(20308, TRUE);
SuspendProcess(20308, FALSE);
return 0; }
|