gpt4 book ai didi

windows - 检测 "suspended"Windows 8/10 进程

转载 作者:可可西里 更新时间:2023-11-01 11:44:13 26 4
gpt4 key购买 nike

Windows 8/10 中的 UWP(或“Metro”)应用程序不在前台时可以暂停。处于此状态的应用程序继续存在但不再消耗 CPU 时间。引入此更改似乎是为了提高平板电脑和手机等低功耗/存储设备的性能。

检测处于这种状态的进程的最优雅、最简单的方法是什么?

目前我可以看到 2 种可能的解决方案:

  1. 调用 NtQuerySystemInformation() 并枚举每个进程和每个线程。如果所有线程都处于挂起状态,则进程被“挂起”。这种方法将需要大量代码,而且关键的是 NtQuerySystemInformation() 只是半文档化的,可能会在未来的操作系统中被删除。 NtQueryInformationProcess() 也可能针对相同的问题提供类似的解决方案。

  2. 调用 GetProcessTimes() 并记录每个进程的计数器。等待一些较长的时间(分钟)并再次检查。如果进程计数器未更改,则假定进程已挂起。我承认这是一个 hack,但如果时间足够长,可能会奏效。

有没有更优雅的方式?

最佳答案

为此存在PROCESS_EXTENDED_BASIC_INFORMATION - 本answer中描述的标志的含义.你需要 IsFrozen 标志。因此您需要具有 PROCESS_QUERY_LIMITED_INFORMATION 访问权限的开放进程(要对所有进程执行此操作,您需要在 token 中启用 SE_DEBUG_PRIVILEGE)。并使用 ProcessBasicInformationPROCESS_EXTENDED_BASIC_INFORMATION 调用 NtQuerySystemInformation作为输入。为了枚举所有进程,我们可以使用 NtQuerySystemInformationSystemProcessInformation。当然可以并使用 CreateToolhelp32Snapshot + Process32First + Process32Next 但是这个 api 效率很低,比较直接调用 NtQuerySystemInformation

也可以枚举进程中的所有线程并检查它的状态,如果状态等待 - 等待原因。这非常简单,因为所有这些信息都已经通过使用 SystemProcessInformation 调用 NtQuerySystemInformation 返回了。有了这个,我们就不需要开放流程了。通常这两种方式都会给出相同的结果(对于暂停/卡住)进程,但是使用 IsFrozen 是最正确的解决方案。

void PrintSuspended()
{
BOOLEAN b;
RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &b);

ULONG cb = 0x1000;
NTSTATUS status;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;

if (PBYTE buf = new BYTE[cb])
{
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb)))
{
union {
PBYTE pb;
SYSTEM_PROCESS_INFORMATION* spi;
};

pb = buf;

ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;

if (!spi->UniqueProcessId)
{
continue;
}

if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
(ULONG)(ULONG_PTR)spi->UniqueProcessId))
{
PROCESS_EXTENDED_BASIC_INFORMATION pebi;
if (0 <= NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pebi, sizeof(pebi), 0) &&
pebi.Size >= sizeof(pebi))
{
if (pebi.IsFrozen)
{
DbgPrint("f:%x %wZ\n", spi->UniqueProcessId, spi->ImageName);
}
}
CloseHandle(hProcess);
}

if (ULONG NumberOfThreads = spi->NumberOfThreads)
{
SYSTEM_THREAD_INFORMATION* TH = spi->TH;
do
{
if (TH->ThreadState != StateWait || TH->WaitReason != Suspended)
{
break;
}
} while (TH++, --NumberOfThreads);

if (!NumberOfThreads)
{
DbgPrint("s:%x %wZ\n", spi->UniqueProcessId, spi->ImageName);
}
}

} while (NextEntryOffset = spi->NextEntryOffset);
}
delete [] buf;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
}

关于windows - 检测 "suspended"Windows 8/10 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50172564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com