in Silhouette/Filter_Main.cpp [67:177]
NTSTATUS FindPagefile()
{
const ULONG systemProcessId = HandleToULong(PsGetProcessId(PsInitialSystemProcess)); // Always 4, but you never know?
DECLARE_CONST_UNICODE_STRING(pagefile_sys, L"\\pagefile.sys");
NTSTATUS ntStatus = STATUS_SUCCESS;
PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
ULONG handleInfoMem = 0;
ULONG returnLength = 0;
PFILE_OBJECT pFile = NULL;
PFILE_NAME_INFORMATION pNameInfo = NULL;
for (ULONG tries = 0; tries < 5; tries++)
{
ntStatus = ZwQuerySystemInformation(SystemHandleInformation, pHandleInfo, handleInfoMem, &returnLength);
if (STATUS_INFO_LENGTH_MISMATCH != ntStatus)
{
break;
}
HandleDelete(pHandleInfo);
handleInfoMem = returnLength * 2;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)ExAllocatePoolWithTag(PagedPool, handleInfoMem, POOL_TAG);
if (!pHandleInfo)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
RtlZeroMemory(pHandleInfo, handleInfoMem);
}
if (!NT_SUCCESS(ntStatus))
{
goto Cleanup;
}
for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++)
{
UNICODE_STRING nameInfoUni = { 0, };
if (systemProcessId != pHandleInfo->Handles[i].UniqueProcessId)
{
continue;
}
ReferenceDelete(pFile);
PoolDeleteWithTag(pNameInfo, POOL_TAG);
// I'm not fond of temporarily referencing other handles in the System process, but the point here is to prove the concept
ntStatus = ObReferenceObjectByHandle(
MAKE_KERNEL_HANDLE(ULongToHandle(pHandleInfo->Handles[i].HandleValue)), FILE_READ_DATA|FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID*)&pFile, NULL);
if (!NT_SUCCESS(ntStatus))
{
continue;
}
// pagefile.sys is opened without buffering
if (!FlagOn(pFile->Flags, FO_NO_INTERMEDIATE_BUFFERING))
{
continue;
}
// pagefile.sys is opened for RW- with -W- sharing
if (!pFile->ReadAccess || !pFile->WriteAccess || pFile->DeleteAccess || pFile->SharedRead || pFile->SharedDelete)
{
continue;
}
pNameInfo = (PFILE_NAME_INFORMATION)ExAllocatePoolWithTag(PagedPool, 4096, POOL_TAG);
if (!pNameInfo)
{
continue;
}
RtlZeroMemory(pNameInfo, 4096);
pNameInfo->FileNameLength = 4096 - sizeof(*pNameInfo); // Leave room for a NULL
ntStatus = FsRtlQueryInformationFile(pFile, pNameInfo, 4096, FileNameInformation, &returnLength);
if (!NT_SUCCESS(ntStatus) || (pNameInfo->FileNameLength > MAXUSHORT))
{
continue;
}
nameInfoUni.Buffer = pNameInfo->FileName;
nameInfoUni.Length = (USHORT)pNameInfo->FileNameLength;
nameInfoUni.MaximumLength = nameInfoUni.Length;
if (!RtlEqualUnicodeString(&nameInfoUni, &pagefile_sys, FALSE))
{
continue;
}
ntStatus = FsRtlQueryInformationFile(pFile, &gProtectedFiles[0], sizeof(gProtectedFiles[0]), FileIdInformation, &returnLength);
if (NT_SUCCESS(ntStatus) && (sizeof(gProtectedFiles[0]) == returnLength))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"Silhouette: Pagefile: %wZ\n",
&nameInfoUni);
goto Cleanup;
}
}
ntStatus = STATUS_PAGEFILE_NOT_SUPPORTED;
Cleanup:
PoolDeleteWithTag(pHandleInfo, POOL_TAG);
PoolDeleteWithTag(pNameInfo, POOL_TAG);
ReferenceDelete(pFile);
return ntStatus;
}