PVOID pIoCreateFileSpecifyDeviceObjectHint = 0 ;
extern POBJECT_TYPE *IoDeviceObjectType;
ULONG SystemVolumeIndex = 0xffffffff;
NTSTATUS MyIoCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG Disposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options
)
{
NTSTATUS stat ;
LPWSTR pPathVolume;
ULONG volumeindex ;
WCHAR VolumePath[13] = L"\\GLOBAL??\\A:";
HANDLE LinkHandle ;
OBJECT_ATTRIBUTES oba ;
PDEVICE_OBJECT DeviceObject ;
if (pIoCreateFileSpecifyDeviceObjectHint == NULL || UserInit)
{
goto NormalCreateFile;
}
pPathVolume = ObjectAttributes->ObjectName->Buffer + 4;
if (*pPathVolume >= L'A' && *pPathVolume <= L'Z')
{
volumeindex = *pPathVolume - L'A';
}
else if(*pPathVolume >= L'a' && *pPathVolume <= L'z')
{
volumeindex = *pPathVolume - L'a';
}
else
{
goto NormalCreateFile;
}
if (pPathVolume[1] != L':' || pPathVolume[2] != L'\\')
{
goto NormalCreateFile;
}
if (volumeindex == SystemVolumeIndex )
{
goto NormalCreateFile;
}
if (VolumeBaseDevObjCache[volumeindex] == 0 )
{
UNICODE_STRING uniname ;
HANDLE KeyHandle ;
UNICODE_STRING DevUniName;
PVOID pKeyInfo ;
ULONG btr ;
LPWSTR pDeviceName ;
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo ;
PFILE_OBJECT FileObject ;
VolumePath[10] = VolumePath[10] + volumeindex ;
RtlInitUnicodeString(&uniname , L"\\Registry\\Machine\\SYSTEM\\Setup");
InitializeObjectAttributes(&oba , &uniname , OBJ_CASE_INSENSITIVE , 0 , 0);
stat = ZwOpenKey(&KeyHandle , KEY_ALL_ACCESS , &oba);
if (!NT_SUCCESS(stat))
{
goto NormalCreateFile;
}
pKeyInfo = ExAllocatePool(NonPagedPool , sizeof(KEY_VALUE_PARTIAL_INFORMATION)+ MAX_PATH * sizeof(WCHAR));
if (!pKeyInfo)
{
ZwClose(KeyHandle);
goto NormalCreateFile;
}
RtlInitUnicodeString(&uniname , L"SystemPartition");
stat = ZwQueryValueKey(KeyHandle ,
&uniname ,
KeyValuePartialInformation ,
pKeyInfo ,
sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH * sizeof(WCHAR) ,
&btr );
ZwClose(KeyHandle);
if (!NT_SUCCESS(stat))
{
ExFreePool(pKeyInfo);
goto NormalCreateFile;
}
RtlInitUnicodeString(&uniname, VolumePath);
InitializeObjectAttributes(&oba , &uniname , OBJ_CASE_INSENSITIVE , 0 , 0 );
stat = ZwOpenSymbolicLinkObject(&LinkHandle , SYMBOLIC_LINK_QUERY , &oba );
if (!NT_SUCCESS(stat))
{
ExFreePool(pKeyInfo);
goto NormalCreateFile;
}
pDeviceName = ExAllocatePool(NonPagedPool , MAX_PATH*sizeof(WCHAR));
if (!pDeviceName)
{
ExFreePool(pKeyInfo);
ZwClose(LinkHandle);
goto NormalCreateFile;
}
RtlInitUnicodeString(&DevUniName , pDeviceName);
DevUniName.MaximumLength = MAX_PATH * sizeof(WCHAR);
stat = ZwQuerySymbolicLinkObject(LinkHandle , &DevUniName , NULL);
ZwClose(LinkHandle);
if (!NT_SUCCESS(stat))
{
ExFreePool(pKeyInfo);
ExFreePool(pDeviceName);
}
KeyValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)pKeyInfo ;
if (_wcsnicmp(pDeviceName , &KeyValueInfo->Data , DevUniName.Length / sizeof(WCHAR)) == 0)
{
SystemVolumeIndex = volumeindex ;
ExFreePool(pKeyInfo);
ExFreePool(pDeviceName);
goto NormalCreateFile;
}
ExFreePool(pKeyInfo);
stat = IoGetDeviceObjectPointer(&DevUniName ,
FILE_READ_ATTRIBUTES ,
&FileObject ,
&DeviceObject );
ExFreePool(pDeviceName);
if (!NT_SUCCESS(stat))
{
goto NormalCreateFile ;
}
DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
if (DeviceObject == FileObject->DeviceObject)
{
//DbgPrint("device object not mounted! %08x\n" , DeviceObject);
stat = IoVerifyVolume(DeviceObject , FALSE);
if (!NT_SUCCESS(stat))
{
//DbgPrint("try mounte volume failed %08x\n", stat);
ObDereferenceObject(FileObject);
goto NormalCreateFile ;
}
//DbgPrint("mount volume OK\n");
if (DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject)
{
DeviceObject = DeviceObject->Vpb->DeviceObject ;
}
}
ObDereferenceObject(FileObject);
if (!DeviceObject)
{
goto NormalCreateFile;
}
VolumeBaseDevObjCache[volumeindex] = DeviceObject ;
}
else
{
DeviceObject = VolumeBaseDevObjCache[volumeindex];
}
goto BypassCreateFile;
NormalCreateFile:
return IoCreateFile(FileHandle , DesiredAccess ,
ObjectAttributes , IoStatusBlock , AllocationSize ,
FileAttributes , ShareAccess , Disposition , CreateOptions , EaBuffer ,
EaLength , CreateFileType , ExtraCreateParameters , Options);
BypassCreateFile:
__asm
{
push DeviceObject
push Options
push ExtraCreateParameters
push CreateFileType
push EaLength
push EaBuffer
push CreateOptions
push Disposition
push ShareAccess
push FileAttributes
push AllocationSize
push IoStatusBlock
push ObjectAttributes
push DesiredAccess
push FileHandle
call pIoCreateFileSpecifyDeviceObjectHint
mov stat ,eax
}
return stat ;
}