From 5dcd1d1714663fcc7db6fb4dab48ac16e6c0c5d5 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 22 Oct 2024 09:05:04 +0300 Subject: [PATCH] [UCRT:VCRUNTIME] Implement __security_init_cookie and __security_check_cookie --- sdk/lib/ucrt/CMakeLists.txt | 2 + .../ucrt/vcruntime/__security_init_cookie.c | 87 +++++++++++++++++++ .../vcruntime/amd64/__security_check_cookie.s | 27 ++++++ .../vcruntime/i386/__security_check_cookie.s | 27 ++++++ sdk/lib/ucrt/vcruntime/vcruntime.cmake | 14 +++ 5 files changed, 157 insertions(+) create mode 100644 sdk/lib/ucrt/vcruntime/__security_init_cookie.c create mode 100644 sdk/lib/ucrt/vcruntime/amd64/__security_check_cookie.s create mode 100644 sdk/lib/ucrt/vcruntime/i386/__security_check_cookie.s create mode 100644 sdk/lib/ucrt/vcruntime/vcruntime.cmake diff --git a/sdk/lib/ucrt/CMakeLists.txt b/sdk/lib/ucrt/CMakeLists.txt index deeb3c7b27e..a5106b5037c 100644 --- a/sdk/lib/ucrt/CMakeLists.txt +++ b/sdk/lib/ucrt/CMakeLists.txt @@ -101,6 +101,7 @@ include(stdio/stdio.cmake) include(stdlib/stdlib.cmake) include(string/string.cmake) include(time/time.cmake) +include(vcruntime/vcruntime.cmake) add_library(ucrt OBJECT ${UCRT_CONIO_SOURCES} @@ -122,6 +123,7 @@ add_library(ucrt OBJECT ${UCRT_STDLIB_SOURCES} ${UCRT_STRING_SOURCES} ${UCRT_TIME_SOURCES} + ${UCRT_VCRUNTIME_SOURCES} ) #target_link_libraries(ucrt pseh) diff --git a/sdk/lib/ucrt/vcruntime/__security_init_cookie.c b/sdk/lib/ucrt/vcruntime/__security_init_cookie.c new file mode 100644 index 00000000000..7488aec954d --- /dev/null +++ b/sdk/lib/ucrt/vcruntime/__security_init_cookie.c @@ -0,0 +1,87 @@ +// +// __security_init_cookie.c +// +// Copyright (c) 2024 Timo Kreuzer +// +// Implementation of __security_init_cookie. +// +// SPDX-License-Identifier: MIT +// + +#include +#include +#include + +#ifdef _WIN64 +#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ull +#define _rotlptr _rotl64 +#else +#define DEFAULT_SECURITY_COOKIE 0xBB40E64E +#define _rotlptr _rotl +#endif + +uintptr_t __security_cookie = DEFAULT_SECURITY_COOKIE; +uintptr_t __security_cookie_complement = ~DEFAULT_SECURITY_COOKIE; + +void __security_init_cookie(void) +{ + LARGE_INTEGER performanceCounter; + FILETIME fileTime; + uintptr_t randomValue = (uintptr_t)0x27E30B2C16B07297ull; + +#if defined(_M_IX86) || defined(_M_X64) + if (IsProcessorFeaturePresent(PF_RDRAND_INSTRUCTION_AVAILABLE)) + { +#ifdef _M_X64 + while (!_rdrand64_step(&randomValue)) + _mm_pause(); +#else + while (!_rdrand32_step(&randomValue)) + _mm_pause(); +#endif + } + + if (IsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE)) + { + randomValue += __rdtsc(); + } +#endif + + randomValue += (uintptr_t)&randomValue; + randomValue ^= GetTickCount(); + + QueryPerformanceCounter(&performanceCounter); +#ifdef _WIN64 + randomValue ^= performanceCounter.QuadPart; +#else + randomValue ^= performanceCounter.LowPart; + randomValue ^= performanceCounter.HighPart; +#endif + + randomValue += GetCurrentThreadId(); + randomValue = _rotlptr(randomValue, GetCurrentThreadId() >> 2); + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + GetSystemTimePreciseAsFileTime(&fileTime); +#else + GetSystemTimeAsFileTime(&fileTime); +#endif + randomValue += fileTime.dwLowDateTime; + randomValue += fileTime.dwHighDateTime; + + randomValue += GetCurrentProcessId(); + randomValue = _rotlptr(randomValue, GetCurrentProcessId() >> 2); + + if (randomValue == DEFAULT_SECURITY_COOKIE) + { + randomValue++; + } + +#ifdef _WIN64 + /* Zero out highest 16 bits */ + randomValue &= 0x0000FFFFFFFFFFFFull; +#endif + + __security_cookie = randomValue; + __security_cookie_complement = ~randomValue; +} diff --git a/sdk/lib/ucrt/vcruntime/amd64/__security_check_cookie.s b/sdk/lib/ucrt/vcruntime/amd64/__security_check_cookie.s new file mode 100644 index 00000000000..621426521f4 --- /dev/null +++ b/sdk/lib/ucrt/vcruntime/amd64/__security_check_cookie.s @@ -0,0 +1,27 @@ +// +// __security_check_cookie.asm +// +// Copyright (c) 2024 Timo Kreuzer +// +// Implementation of __security_check_cookie for x64. +// +// SPDX-License-Identifier: MIT +// + +#include + +EXTERN __security_cookie:QWORD +EXTERN __report_gsfailure:PROC + +.code64 + +// This function must not clobber any registers! +PUBLIC __security_check_cookie +__security_check_cookie: + cmp rcx, qword ptr __security_cookie[rip] + jne __security_check_cookie_fail + ret +__security_check_cookie_fail: + jmp __report_gsfailure + +END diff --git a/sdk/lib/ucrt/vcruntime/i386/__security_check_cookie.s b/sdk/lib/ucrt/vcruntime/i386/__security_check_cookie.s new file mode 100644 index 00000000000..276025efae3 --- /dev/null +++ b/sdk/lib/ucrt/vcruntime/i386/__security_check_cookie.s @@ -0,0 +1,27 @@ +// +// __security_check_cookie.asm +// +// Copyright (c) 2024 Timo Kreuzer +// +// Implementation of __security_check_cookie for x86. +// +// SPDX-License-Identifier: MIT +// + +#include + +EXTERN ___security_cookie:QWORD +EXTERN ___report_gsfailure:PROC + +.code + +// This function must not clobber any registers! +PUBLIC ___security_check_cookie +___security_check_cookie: + cmp ecx, dword ptr [___security_cookie] + jne ___security_check_cookie_fail + ret +___security_check_cookie_fail: + jmp ___report_gsfailure + +END diff --git a/sdk/lib/ucrt/vcruntime/vcruntime.cmake b/sdk/lib/ucrt/vcruntime/vcruntime.cmake new file mode 100644 index 00000000000..e4857cfe95c --- /dev/null +++ b/sdk/lib/ucrt/vcruntime/vcruntime.cmake @@ -0,0 +1,14 @@ + +list(APPEND UCRT_VCRUNTIME_SOURCES + vcruntime/__security_init_cookie.c +) + +if(${ARCH} STREQUAL "i386") + list(APPEND UCRT_VCRUNTIME_SOURCES + vcruntime/i386/__security_check_cookie.s + ) +elseif(${ARCH} STREQUAL "amd64") + list(APPEND UCRT_VCRUNTIME_SOURCES + vcruntime/amd64/__security_check_cookie.s + ) +endif()