我想编写一个简单的程序,根据md5哈希值(如notepad.exe ...)阻止执行某些.exe文件。
我搜索了这个问题,我发现我需要注册一个回调,这个方法是开始PsSetCreateProcessNotifyRoutineEx,这里是一个示例回调:
VOID PsCreateProcessNotifyEx_CB(HANDLE ParentProcessId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)
{
if (CreateInfo) // if the info is available
{
DbgPrint("Created Process info \r\n");
DbgPrint("\tIs Sub-System Process: %wZ\r\n", CreateInfo->IsSubsystemProcess);
if (!CreateInfo->IsSubsystemProcess) {
DbgPrint("\tParent ProcessId: %d", CreateInfo->ParentProcessId);
DbgPrint("\tFile name: %wZ \r\n", CreateInfo->FileObject->FileName);
DbgPrint("\tImageFileName: %wZ \r\n", CreateInfo->ImageFileName);
DbgPrint("\tCommandLine: %wZ \r\n", CreateInfo->CommandLine);
DbgPrint("\tCreationStatus: %x \r\n", CreateInfo->CreationStatus);
CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
}
}
}
正如您所看到的,我将CreationStatus
设置为阻止每个进程执行的STATUS_ACCESS_DENIED
:),如何有条件地阻止某些进程的执行?如果在SqLite数据库中有一个不允许的.exe文件列表怎么办?如何将此回调连接到一些服务,该服务告诉应该运行哪个文件以及哪个文件不应该?
我也看到微软的this推荐说:
这种回调警告并限制我们,所以我的问题是如何实现我的目标? (根据存储在SqlLite数据库中的哈希值限制执行某些.exe文件?)
非常感谢任何帮助。
答案 0 :(得分:1)
首先,PsCreateProcessNotifyEx_CB
的签名不正确 - 第一个参数必须是PEPROCESS Process
(指向ne进程对象的指针),而不是HANDLE ParentProcessId
。你从msdn页面复制粘贴,但这里有错误。
关于解决方案 - 因为PsCreateProcessNotifyEx_CB
在禁用normal kernel APCs的关键区域执行 - 我们在这里非常有限。但是我们可以将normal kernel APC排队到当前线程。它将在我们离开关键区域时执行。在这里,在Normal例程中我们已经可以从文件中释放读取数据,等待,查询用户模式。对于终止流程,我们只需拨打ZwTerminateProcess
void* __cdecl operator new(size_t size, POOL_TYPE PoolType)
{
return ExAllocatePool(PoolType, size);
}
void __cdecl operator delete(PVOID pv)
{
ExFreePool(pv);
}
// asm routines: call corresponding *Routine and jmp ObfDereferenceObject for g_DriverObject
VOID CALLBACK RundownRoutine(PKAPC );
VOID CALLBACK KernelRoutine(PKAPC , PKNORMAL_ROUTINE *, PVOID * , PVOID * ,PVOID * );
VOID CALLBACK NormalRoutine(PVOID , PVOID ,PVOID );
VOID CALLBACK _NormalRoutine (
PVOID ,
PEPROCESS Process,
PFILE_OBJECT FileObject
)
{
__pragma(message("extern " __FUNCDNAME__ " : PROC ; " __FUNCSIG__))
DbgPrint("NormalRoutine(%p, %p %s)\n", Process, FileObject, PsGetProcessImageFileName(Process));
if (NeedTerminate(Process, FileObject))
{
HANDLE hProcess;
if (0 <= ObOpenObjectByPointer(Process, 0, 0, PROCESS_TERMINATE, *PsProcessType, KernelMode, &hProcess))
{
status = ZwTerminateProcess(hProcess, STATUS_ACCESS_DENIED);
ZwClose(hProcess);
}
}
ObfDereferenceObject(FileObject);
ObfDereferenceObject(Process);
}
VOID CALLBACK _RundownRoutine(PKAPC Apc);
{
__pragma(message("extern " __FUNCDNAME__ " : PROC ; " __FUNCSIG__))
DbgPrint("--Apc<%p>\n", Apc);
delete Apc;
}
VOID CALLBACK _KernelRoutine(
PKAPC Apc,
PKNORMAL_ROUTINE * /*NormalRoutine*/,
PVOID * /*NormalContext*/,
PVOID * /*SystemArgument1*/,
PVOID * /*SystemArgument2*/
)
{
__pragma(message("extern " __FUNCDNAME__ " : PROC ; " __FUNCSIG__))
DbgPrint("KernelRoutine<%p>\n", Apc);
ObfReferenceObject(g_DriverObject);//NormalRoutine will be called
_RundownRoutine(Apc);
}
void CreateProcessNotifyRoutineEx(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)
{
PFILE_OBJECT FileObject;
if (CreateInfo && !CreateInfo->IsSubsystemProcess && (PFILE_OBJECT FileObject = CreateInfo->FileObject))
{
// for do main job out of critical region
if (PKAPC Apc = new(NonPagedPool) KAPC)
{
KeInitializeApc(Apc, KeGetCurrentThread(), OriginalApcEnvironment, KernelRoutine, RundownRoutine, NormalRoutine, KernelMode, 0);
DbgPrint("++Apc<%p> \n", Apc);
ObfReferenceObject(g_DriverObject);
ObfReferenceObject(Process);
ObfReferenceObject(FileObject);
if (!KeInsertQueueApc(Apc, Process, FileObject, IO_NO_INCREMENT))
{
ObfDereferenceObject(FileObject);
ObfDereferenceObject(Process);
ObfDereferenceObject(g_DriverObject);
delete Apc;
}
}
}
}