mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-10-30 21:35:06 +00:00
55 lines
2.9 KiB
C
55 lines
2.9 KiB
C
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <winternl.h>
|
|
|
|
// FoldStringW's mappings and the volume of an open file through NtQueryVolumeInformationFile, as setup programs call them.
|
|
|
|
typedef struct {
|
|
ULONG FileSystemAttributes;
|
|
LONG MaximumComponentNameLength;
|
|
ULONG FileSystemNameLength;
|
|
WCHAR FileSystemName[1];
|
|
} ATTRIBUTE_INFORMATION;
|
|
|
|
typedef struct {
|
|
LARGE_INTEGER TotalAllocationUnits;
|
|
LARGE_INTEGER AvailableAllocationUnits;
|
|
ULONG SectorsPerAllocationUnit;
|
|
ULONG BytesPerSector;
|
|
} SIZE_INFORMATION;
|
|
|
|
static int same(const WCHAR *left, const WCHAR *right, int count)
|
|
{
|
|
for (int index = 0; index < count; ++index)
|
|
if (left[index] != right[index]) return 0;
|
|
return 1;
|
|
}
|
|
|
|
int raven_entry(void)
|
|
{
|
|
WCHAR folded[16];
|
|
// Fullwidth letters and Arabic-Indic digits fold to ASCII; the terminator is counted when the source length is -1.
|
|
if (FoldStringW(MAP_FOLDCZONE | MAP_FOLDDIGITS, L"\xff21\xff42\x0661\x0662", -1, folded, 16) != 5 || !same(folded, L"Ab12", 5)) return 1;
|
|
if (FoldStringW(MAP_EXPAND_LIGATURES, L"\x00e6\xfb01", 2, folded, 16) != 4 || !same(folded, L"aefi", 4)) return 2;
|
|
if (FoldStringW(MAP_COMPOSITE, L"\x00e9", 1, folded, 16) != 2 || !same(folded, L"e\x0301", 2)) return 3;
|
|
if (FoldStringW(MAP_PRECOMPOSED, L"e\x0301x", 3, folded, 16) != 2 || !same(folded, L"\x00e9x", 2)) return 4;
|
|
if (FoldStringW(MAP_FOLDDIGITS, L"\x0663", 1, NULL, 0) != 1) return 5;
|
|
if (FoldStringW(MAP_FOLDDIGITS, L"\x0663\x0664", 2, folded, 1) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return 6;
|
|
if (FoldStringW(MAP_PRECOMPOSED | MAP_COMPOSITE, L"a", 1, folded, 16) || GetLastError() != ERROR_INVALID_FLAGS) return 7;
|
|
|
|
HANDLE file = CreateFileW(L"C:\\Windows", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
if (file == INVALID_HANDLE_VALUE) return 10;
|
|
IO_STATUS_BLOCK status;
|
|
union { ATTRIBUTE_INFORMATION attributes; SIZE_INFORMATION sizes; BYTE bytes[64]; } buffer;
|
|
if (NtQueryVolumeInformationFile(file, &status, &buffer, sizeof(buffer), (FS_INFORMATION_CLASS)5) || status.Information != 20 ||
|
|
buffer.attributes.FileSystemNameLength != 8 || !same(buffer.attributes.FileSystemName, L"NTFS", 4)) return 11;
|
|
// A name cut by the buffer is reported as an overflow with the part that fit.
|
|
if (NtQueryVolumeInformationFile(file, &status, &buffer, 14, (FS_INFORMATION_CLASS)5) != (NTSTATUS)0x80000005 || status.Information != 14) return 12;
|
|
if (NtQueryVolumeInformationFile(file, &status, &buffer, 8, (FS_INFORMATION_CLASS)5) != (NTSTATUS)0xc0000004) return 13;
|
|
if (NtQueryVolumeInformationFile(file, &status, &buffer, sizeof(buffer), (FS_INFORMATION_CLASS)3) || status.Information != 24 ||
|
|
buffer.sizes.BytesPerSector != 512 || !buffer.sizes.TotalAllocationUnits.QuadPart) return 14;
|
|
if (NtQueryVolumeInformationFile(file, &status, &buffer, sizeof(buffer), (FS_INFORMATION_CLASS)99) != (NTSTATUS)0xc0000003) return 15;
|
|
CloseHandle(file);
|
|
return 0;
|
|
}
|