阻止基于md5哈希

时间:2017-11-17 14:01:49

标签: c++ windows security process driver

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

  • 保持通知例程简短。
  • 不要调用用户模式服务来验证进程,线程或映像。
  • 不要进行注册表调用。
  • 不要进行阻塞和/或进程间通信(IPC)函数调用。
  • 不要与其他线程同步,因为它可能导致重入死锁。

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

非常感谢任何帮助。

1 个答案:

答案 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;
            }
        }
    }
}