根据 md5 哈希阻止执行特定的 .exe 文件

Block executing specific .exe files based on their md5 hash

我想编写一个简单的程序,根据它们的 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 Microsoft 的推荐,它说:

在这个回调中有点警告和限制我们,所以我的问题是如何实现我的目标? (根据存储在 SqlLite 数据库中的哈希值限制某些 .exe 文件的执行?)

非常感谢任何帮助。

首先,您对 PsCreateProcessNotifyEx_CB 的签名不正确 - 第一个参数必须是 PEPROCESS Process(指向 ne 进程对象的指针)而不是 HANDLE ParentProcessId。您从 msdn 页面复制粘贴此内容,但此处出错。

关于解决方案 - 因为 PsCreateProcessNotifyEx_CB 在临界区执行 normal kernel APCs disabled - we very restricted todo something here. but we can queue normal kernel APC to current thread. it will be executed just we leave critical region. and here, in Normal routine we already can free read data from file, wait, query user mode. for terminate process we can simply call 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;
            }
        }
    }
}