钩SSDT。其他驱动程序使用我的功能

时间:2018-07-06 17:10:51

标签: c++ windows winapi kernel driver

如何获取上下文中的驱动程序名称或驱动程序路径?我的意思是,当我的驱动程序不使用syscall并挂上它时,我需要获取该驱动程序的名称。对于用户进程,没有问题:

PUNICODE_STRING myname;
SeLocateProcessImageName(PsGetCurrentProcess(), &myname);

但是,如果外来驱动程序使用挂钩的系统调用,则其PID为4。我无法获得上述名称... 这是完整的代码:

    NTSTATUS
HookNtTerminateProcess(
    HANDLE hProcess,
    NTSTATUS ExitStatus
    )
{
    NTSTATUS statuscod;
    if (hProcess == NULL || hProcess == (HANDLE)-1 || hProcess<2) {
        return fnNtTerminateProcess(hProcess, ExitStatus);
    }
    if (PsGetCurrentProcessId() == 4)
    {
        ???????????????????????????
    }
    PUNICODE_STRING name;
    getPathByProcessHandle(hProcess, &name);
    PUNICODE_STRING myname;
    SeLocateProcessImageName(PsGetCurrentProcess(), &myname);

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "\n-------------------------------------------\n");
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "KILL TO PROCESS WITH HANDLE %d\n", hProcess);
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "WHO: %S\n", myname->Buffer);
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "TARGET: %S\n", name->Buffer);
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "PID is %d\n", PsGetCurrentProcessId());

    NTSTATUS status;
    if (wcsstr(name->Buffer, L"Windows\\protecteddir\\myapp.exe") == NULL) {
        return fnNtTerminateProcess(hProcess, ExitStatus);
    }
    sendEvent(0, PsGetCurrentProcessId());
    return STATUS_ACCESS_DENIED;
}

1 个答案:

答案 0 :(得分:0)

驱动程序利用系统进程,该进程的进程ID通常为0x04。驱动程序作为命名部分映射到内存中,然后由线程执行。当您无法通过进程信息唯一地标识它们的名称时,就可以看到它们不是单独的进程,因为它们全都只是系统进程的一部分。

这是一些确定呼叫者与我所知道的驱动程序有关的可能性。对于所有情况,如果进程ID是系统进程(0x04)或前一个KPROCESSOR_MODE都不是用户模式:

1)跟踪系统服务例程挂钩中捕获的当前线程的调用堆栈,并查看调用者的地址范围,并确定该范围内的地址所属的内存部分。该部分的对象属性将指定名称,例如“ driver.sys”。这将是调用源的基本驱动程序的名称

2)使用ZwQueryInformationThread并将ThreadQuerySetWin32StartAddress用作ThreadInformationClass的参数,这将告诉您线程开始执行的位置,然后确定基本执行地址所在的命名内存部分。它将存储在内存中。部分的OBJECT_ATTRIBUTES。这还将解析一个调用源于哪个基本驱动程序的名称。

3)如果要确保只有您的线程可以正常执行系统服务例程挂钩,则可以在线程的ETHREAD / KTHREAD结构中更改未使用/保留的字段,以唯一地标识它以及所有其他线程除外。

这些是一些解决方案,但是在系统进程中唯一地定位和标识线程应该起作用。