我正在编写一个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的尝试都会失败,而尝试读取父进程会成功。
有没有人知道这里发生了什么,也许有些建议?