/*
* Do nothing if the global cookie has already been initialized.
*/
if (security_cookie && security_cookie != DEFAULT_SECURITY_COOKIE)
return;
/*
* Initialize the global cookie with an unpredictable value which is
* different for each module in a process. Combine a number of sources
* of randomness.
*/
GetSystemTimeAsFileTime(&systime.ft_struct);
#if !defined (_WIN64)
cookie = systime.ft_struct.dwLowDateTime;
cookie ^= systime.ft_struct.dwHighDateTime;
#else /* !defined (_WIN64) */
cookie = systime.ft_scalar;
#endif /* !defined (_WIN64) */
cookie ^= GetCurrentProcessId();
cookie ^= GetCurrentThreadId();
cookie ^= GetTickCount();
QueryPerformanceCounter(&perfctr);
#if !defined (_WIN64)
cookie ^= perfctr.LowPart;
cookie ^= perfctr.HighPart;
#else /* !defined (_WIN64) */
cookie ^= perfctr.QuadPart;
#endif /* !defined (_WIN64) */
/*
* Make sure the global cookie is never initialized to zero, since in
* that case an overrun which sets the local cookie and return address
* to the same value would go undetected.
*/
__security_cookie = cookie? cookie : DEFAULT_SECURITY_COOKIE;
}
Listing 7.1 (continued)
Unsurprisingly, stack checking is not impossible to defeat [Bulba, Koziol].
Exactly how that’s done is beyond the scope of this book, but suffice it to say that
in some functions the attacker still has a window of opportunity for writing into
a local memory address (which almost guarantees that he or she will be able to
Auditing Program Binaries 253