While implementing my own C runtime solution for applications for Windows OS, I faced the following problem:
Each execution time __security_cookie
should get a random value with the selectany attribute (using __declspec(selectany)
). But it doesn't... And because of this every time it has the default value of 0x00002B992DDFA232
in a 64-bit version of the application. And it causes an error (Global security check fails).
I use Clang version 14 for compiling my code.
GlobalSecurity.c:
#if defined (_WIN64)
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232
#else
#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
#endif
// Global security cookie
__declspec(selectany) UPtr __security_cookie = (UPtr)DEFAULT_SECURITY_COOKIE;
__declspec(selectany) UPtr __security_cookie_complement = ~((UPtr)DEFAULT_SECURITY_COOKIE);
GlobalSecurity.h
...
// Global security cookie
extern UPtr __security_cookie;
extern UPtr __security_cookie_complement;
typedef union
{
unsigned __int64 ft_scalar;
FILETIME ft_struct;
} FT;
// Initializes global security cookie
void CDECL __security_init_cookie()
{
if (__security_cookie != DEFAULT_SECURITY_COOKIE
#if defined (_M_IX86)
&& (__security_cookie & 0xFFFF0000) != 0
#endif
)
{
__security_cookie_complement = ~__security_cookie;
return;
}
...
Why does not __security_cookie
work as it should? And how this problem can be solved?
P.S.: UPtr is the same as UINT_PTR
selectany
does not give you a random number and even if its purpose was to avoid "using uninitialized variable" warnings, your code is assigning to the variable!
The selectany
attribute allows the same global variable to be declared and initialized in multiple translation units.