PsSuspendProcess 阻塞/等待/卡住 - Windows 内核编程
PsSuspendProcess blocking / waiting / stuck - Windows Kernel Programming
我带着 Windows 内核中的一个非常低级的问题来到这里。
我在微过滤器驱动程序的回调函数中。
驱动程序的目标是暂停任何进程 尝试打开我标记为受保护的文件。
我正在使用从此函数获得的 PsSuspendProcess :
(pPsSuspendProcess)ReturnSystemRoutineAddress(L"PsSuspendProcess");
但是当我用上面的代码调用它时,我的程序卡在了 Suspend 调用处。
在任务管理器上,进程挂起很好,但驱动程序永远不会结束这个功能。
只有当我手动取消暂停进程或从 taskmgr 中将其终止时,它才会继续。
我完全被阻止了,因为 PsSuspendProcess 是一个未记录的函数...
这是我的代码:
FLT_PREOP_CALLBACK_STATUS
DfPreCreateCallback(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Outptr_result_maybenull_ PVOID* CompletionContext
)
{
PAGED_CODE();
NTSTATUS status;
ULONG options = Data->Iopb->Parameters.Create.Options;
UCHAR disposition = (options >> 24) & 0xff;
ULONG createOptions = (options << 8) >> 8;
if ((createOptions & FILE_NON_DIRECTORY_FILE) && (disposition == FILE_OPEN || disposition == FILE_OPEN_IF
|| disposition == FILE_OVERWRITE || disposition == FILE_OVERWRITE_IF))
{
HANDLE processId = (HANDLE)FltGetRequestorProcessId(Data);
PEPROCESS p = FltGetRequestorProcess(Data);
if (p == NULL)
goto callback_end;
LPSTR processName = PsGetProcessImageFileName(p);
if (processName == NULL)
goto callback_end;
for (int i = 0; i < (sizeof(ExcludedProcess) / sizeof(LPCWSTR)); i++)
{
if (strcmp(processName, ExcludedProcess[i]) == 0)
goto callback_end;
}
PFLT_FILE_NAME_INFORMATION FileInfo;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &FileInfo);
if (NT_ERROR(status))
goto callback_end;
if (!IsProtected(&FileInfo->Name))
goto callback_end;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG PROTECTED %wZ", FileInfo->Name);
PsSuspendProcess(p);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG SUSPENDED")
}
callback_end:
CompletionContext = NULL;
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
你按事实打电话
PsSuspendProcess(FltGetRequestorProcess(Data));
但对于文件操作,预回调几乎总是在请求给定 I/O 操作的线程上下文中调用。所以几乎总是
FltGetRequestorProcess(Data) == IoGetCurrentProcess();
因此您暂停 current 进程和 current 线程。结果下一行
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG SUSPENDED");
当然不会执行,直到线程不会恢复
我带着 Windows 内核中的一个非常低级的问题来到这里。 我在微过滤器驱动程序的回调函数中。 驱动程序的目标是暂停任何进程 尝试打开我标记为受保护的文件。 我正在使用从此函数获得的 PsSuspendProcess :
(pPsSuspendProcess)ReturnSystemRoutineAddress(L"PsSuspendProcess");
但是当我用上面的代码调用它时,我的程序卡在了 Suspend 调用处。 在任务管理器上,进程挂起很好,但驱动程序永远不会结束这个功能。
只有当我手动取消暂停进程或从 taskmgr 中将其终止时,它才会继续。
我完全被阻止了,因为 PsSuspendProcess 是一个未记录的函数...
这是我的代码:
FLT_PREOP_CALLBACK_STATUS
DfPreCreateCallback(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Outptr_result_maybenull_ PVOID* CompletionContext
)
{
PAGED_CODE();
NTSTATUS status;
ULONG options = Data->Iopb->Parameters.Create.Options;
UCHAR disposition = (options >> 24) & 0xff;
ULONG createOptions = (options << 8) >> 8;
if ((createOptions & FILE_NON_DIRECTORY_FILE) && (disposition == FILE_OPEN || disposition == FILE_OPEN_IF
|| disposition == FILE_OVERWRITE || disposition == FILE_OVERWRITE_IF))
{
HANDLE processId = (HANDLE)FltGetRequestorProcessId(Data);
PEPROCESS p = FltGetRequestorProcess(Data);
if (p == NULL)
goto callback_end;
LPSTR processName = PsGetProcessImageFileName(p);
if (processName == NULL)
goto callback_end;
for (int i = 0; i < (sizeof(ExcludedProcess) / sizeof(LPCWSTR)); i++)
{
if (strcmp(processName, ExcludedProcess[i]) == 0)
goto callback_end;
}
PFLT_FILE_NAME_INFORMATION FileInfo;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &FileInfo);
if (NT_ERROR(status))
goto callback_end;
if (!IsProtected(&FileInfo->Name))
goto callback_end;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG PROTECTED %wZ", FileInfo->Name);
PsSuspendProcess(p);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG SUSPENDED")
}
callback_end:
CompletionContext = NULL;
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
你按事实打电话
PsSuspendProcess(FltGetRequestorProcess(Data));
但对于文件操作,预回调几乎总是在请求给定 I/O 操作的线程上下文中调用。所以几乎总是
FltGetRequestorProcess(Data) == IoGetCurrentProcess();
因此您暂停 current 进程和 current 线程。结果下一行
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DBG SUSPENDED");
当然不会执行,直到线程不会恢复