ZwReadFile()奇怪地无法从LoadImageNotifyRoutine()读取进程模块

时间:2013-02-02 15:32:23

标签: windows kernel

我正在编写一个Windows内核驱动程序,它是一组用于保护关键基础架构的工具的一部分,而且我遇到了一个非常奇怪的问题。我的代码使用LoadImageNotifyRoutine()捕获可执行加载,之后我将文件名处理为完全限定,因此ZwCreateFile可以使用它。转型看起来像这样

Assume PID: 9212
\Windows\System32\mumble.exe
\Device\HarddiskVolume1\Windows\System32\mumble.exe

转换完成后,ZwCreateFile会打开它,我可以通过我的kumbunculator代码运行它,一切都很顺利。这种情况不适用于父进程使用的任何dll。因此,给定上述PID,LoadNotifyRoutine得到:

PID 9212
\Windows\System32\kernel32.dll
\Device\HarddiskVolume1\Windows\System32\kernel32.dll

ZwCreateFile打开它很好,但任何读取它的尝试都会导致同步模式挂起或否则会导致0x102(STATUS_TIMEOUT)。我的困惑来自于父母很好,我可以做我想做的事,但模块不起作用。这是代码的要点:

....

// Need a mutex to manage call overruns.
KeWaitForSingleObject(&getsigRead, Executive, KernelMode, FALSE, NULL);
LogMessage(Information, "Mumble() got mutex");

//---------------------------------------------------------------------------------------------------
// Start with an Initialized object set
//---------------------------------------------------------------------------------------------------

InitializeObjectAttributes(&objAttr, usFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

//-------------------------------------------------------------------------------------------
// Can't work with files if we're  not at passive level, check to be sure
//-------------------------------------------------------------------------------------------

if(KeGetCurrentIrql() != PASSIVE_LEVEL)
{
    LogMessage(Warning, "---- Not executing at passive level\n");
    KeReleaseMutex(&getsigRead, FALSE);
    return FALSE; //STATUS_INVALID_DEVICE_STATE
}


ntstatus = ZwCreateFile(&hFile, 
            GENERIC_READ, 
            &objAttr, 
            &ioStat, 
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            FILE_SHARE_READ, 
            FILE_OPEN, 
            FILE_NON_DIRECTORY_FILE,
            NULL, 0);

if(ntstatus == STATUS_PENDING)
{
    LogMessage(Information, "Mumble() - Status Pending ...");
    ntstatus = ZwWaitForSingleObject(hFile, FALSE, &Timeout);
    LogMessage(Information, "Open Complete ...");
}

if(!NT_SUCCESS(ntstatus))
{
    LogMessage(Error, "-------- Mumble() failed at ZwCreateFile(), NTSTATUS = 0x%0X File: %wZ\n", ntstatus, objAttr.ObjectName);
    KeReleaseMutex(&getsigRead, FALSE);
    return FALSE;
}

ntstatus = ZwQueryInformationFile(hFile, 
                  &ioStat, 
                  &fileStdInfo, 
                          sizeof(fileStdInfo), 
                  FileStandardInformation);

if(ntstatus == STATUS_PENDING)
{
    LogMessage(Information, "ZwQueryInformationFile() - Status Pending ...");
    ntstatus = ZwWaitForSingleObject(hFile, FALSE, &Timeout);
    LogMessage(Information, "Read Complete ...");
}

if(!NT_SUCCESS(ntstatus)) 
{
    LogMessage(Error, "--------Mumble() failed at ZwQueryInformationFile(), NTSTATUS = 0x%0X\n", ntstatus);
    ZwClose(hFile);
    KeReleaseMutex(&getsigRead, FALSE);
    return FALSE;
}


if((fileData = (PUCHAR)ExAllocatePoolWithTag(PagedPool, fileStdInfo.AllocationSize.LowPart, POOLTAG)) == NULL) 
{
    LogMessage(Error,"--------Mumble() failed at ExAllocatePoolWithTag()");
    ZwClose(hFile);
    KeReleaseMutex(&getsigRead, FALSE);
    return FALSE;
}


ntstatus = ZwReadFile(hFile, 
              NULL,
              NULL, 
              NULL, 
              &ioStat, 
              fileData, 
              fileStdInfo.AllocationSize.LowPart,   // Reads multiple of sector size
              &byteOffset, NULL); 

if(ntstatus == STATUS_PENDING)
{
    LogMessage(Information, "ZwReadFile() - Status Pending ...");
    ntstatus = ZwWaitForSingleObject(hFile, FALSE, &Timeout);
    if(STATUS_SUCCESS != ntstatus)
    {
        LogMessage(Error, "--------ZwReadFile() failed reading %wZ - NTSTATUS = 0x%0X", usFile, ntstatus);
        goto cleanup;
    }

    retVal = TRUE;
    LogMessage(Information, "Read Complete ...");
}

if(!NT_SUCCESS(ntstatus) || ioStat.Information != fileStdInfo.EndOfFile.u.LowPart) 
{
    LogMessage(Error, "--------Mumble() failed at ZwReadFile(), NTSTATUS = 0x%0X, Filename = %wZ\n", ntstatus, usFile);
    retVal = FALSE;
    goto cleanup;
}

....

如上所述,文件打开正常,我可以读取属性,但任何读取DLL的尝试都会失败,而尝试读取父进程会成功。

有没有人知道这里发生了什么,也许有些建议?

0 个答案:

没有答案