1//===-- asan_win_dll_thunk.cc ---------------------------------------------===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// This file is a part of AddressSanitizer, an address sanity checker. 9// 10// This file defines a family of thunks that should be statically linked into 11// the DLLs that have ASan instrumentation in order to delegate the calls to the 12// shared runtime that lives in the main binary. 13// See https://github.com/google/sanitizers/issues/209 for the details. 14//===----------------------------------------------------------------------===// 15 16#ifdef SANITIZER_DLL_THUNK 17#include "asan_init_version.h" 18#include "interception/interception.h" 19#include "sanitizer_common/sanitizer_win_defs.h" 20#include "sanitizer_common/sanitizer_win_dll_thunk.h" 21#include "sanitizer_common/sanitizer_platform_interceptors.h" 22 23// ASan own interface functions. 24#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name) 25#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) 26#include "asan_interface.inc" 27 28// Memory allocation functions. 29INTERCEPT_WRAP_V_W(free) 30INTERCEPT_WRAP_V_W(_free_base) 31INTERCEPT_WRAP_V_WW(_free_dbg) 32 33INTERCEPT_WRAP_W_W(malloc) 34INTERCEPT_WRAP_W_W(_malloc_base) 35INTERCEPT_WRAP_W_WWWW(_malloc_dbg) 36 37INTERCEPT_WRAP_W_WW(calloc) 38INTERCEPT_WRAP_W_WW(_calloc_base) 39INTERCEPT_WRAP_W_WWWWW(_calloc_dbg) 40INTERCEPT_WRAP_W_WWW(_calloc_impl) 41 42INTERCEPT_WRAP_W_WW(realloc) 43INTERCEPT_WRAP_W_WW(_realloc_base) 44INTERCEPT_WRAP_W_WWW(_realloc_dbg) 45INTERCEPT_WRAP_W_WWW(_recalloc) 46INTERCEPT_WRAP_W_WWW(_recalloc_base) 47 48INTERCEPT_WRAP_W_W(_msize) 49INTERCEPT_WRAP_W_W(_expand) 50INTERCEPT_WRAP_W_W(_expand_dbg) 51 52// TODO(timurrrr): Might want to add support for _aligned_* allocation 53// functions to detect a bit more bugs. Those functions seem to wrap malloc(). 54 55// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). 56 57INTERCEPT_LIBRARY_FUNCTION(atoi); 58INTERCEPT_LIBRARY_FUNCTION(atol); 59INTERCEPT_LIBRARY_FUNCTION(frexp); 60INTERCEPT_LIBRARY_FUNCTION(longjmp); 61#if SANITIZER_INTERCEPT_MEMCHR 62INTERCEPT_LIBRARY_FUNCTION(memchr); 63#endif 64INTERCEPT_LIBRARY_FUNCTION(memcmp); 65INTERCEPT_LIBRARY_FUNCTION(memcpy); 66INTERCEPT_LIBRARY_FUNCTION(memmove); 67INTERCEPT_LIBRARY_FUNCTION(memset); 68INTERCEPT_LIBRARY_FUNCTION(strcat); // NOLINT 69INTERCEPT_LIBRARY_FUNCTION(strchr); 70INTERCEPT_LIBRARY_FUNCTION(strcmp); 71INTERCEPT_LIBRARY_FUNCTION(strcpy); // NOLINT 72INTERCEPT_LIBRARY_FUNCTION(strcspn); 73INTERCEPT_LIBRARY_FUNCTION(strdup); 74INTERCEPT_LIBRARY_FUNCTION(strlen); 75INTERCEPT_LIBRARY_FUNCTION(strncat); 76INTERCEPT_LIBRARY_FUNCTION(strncmp); 77INTERCEPT_LIBRARY_FUNCTION(strncpy); 78INTERCEPT_LIBRARY_FUNCTION(strnlen); 79INTERCEPT_LIBRARY_FUNCTION(strpbrk); 80INTERCEPT_LIBRARY_FUNCTION(strrchr); 81INTERCEPT_LIBRARY_FUNCTION(strspn); 82INTERCEPT_LIBRARY_FUNCTION(strstr); 83INTERCEPT_LIBRARY_FUNCTION(strtok); 84INTERCEPT_LIBRARY_FUNCTION(strtol); 85INTERCEPT_LIBRARY_FUNCTION(wcslen); 86INTERCEPT_LIBRARY_FUNCTION(wcsnlen); 87 88#ifdef _WIN64 89INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler); 90#else 91INTERCEPT_LIBRARY_FUNCTION(_except_handler3); 92// _except_handler4 checks -GS cookie which is different for each module, so we 93// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4). 94INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) { 95 __asan_handle_no_return(); 96 return REAL(_except_handler4)(a, b, c, d); 97} 98#endif 99 100// Windows specific functions not included in asan_interface.inc. 101INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return) 102INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address) 103INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter) 104 105using namespace __sanitizer; 106 107extern "C" { 108int __asan_option_detect_stack_use_after_return; 109uptr __asan_shadow_memory_dynamic_address; 110} // extern "C" 111 112static int asan_dll_thunk_init() { 113 typedef void (*fntype)(); 114 static fntype fn = 0; 115 // asan_dll_thunk_init is expected to be called by only one thread. 116 if (fn) return 0; 117 118 // Ensure all interception was executed. 119 __dll_thunk_init(); 120 121 fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init"); 122 fn(); 123 __asan_option_detect_stack_use_after_return = 124 (__asan_should_detect_stack_use_after_return() != 0); 125 __asan_shadow_memory_dynamic_address = 126 (uptr)__asan_get_shadow_memory_dynamic_address(); 127 128#ifndef _WIN64 129 INTERCEPT_FUNCTION(_except_handler4); 130#endif 131 // In DLLs, the callbacks are expected to return 0, 132 // otherwise CRT initialization fails. 133 return 0; 134} 135 136#pragma section(".CRT$XIB", long, read) // NOLINT 137__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init; 138 139static void WINAPI asan_thread_init(void *mod, unsigned long reason, 140 void *reserved) { 141 if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init(); 142} 143 144#pragma section(".CRT$XLAB", long, read) // NOLINT 145__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *, 146 unsigned long, void *) = asan_thread_init; 147 148WIN_FORCE_LINK(__asan_dso_reg_hook) 149 150#endif // SANITIZER_DLL_THUNK 151