1 //===-- asan_win_dll_thunk.cc ---------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
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 //===----------------------------------------------------------------------===//
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"
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"
28 // Memory allocation functions.
29 INTERCEPT_WRAP_V_W(free
)
30 INTERCEPT_WRAP_V_W(_free_base
)
31 INTERCEPT_WRAP_V_WW(_free_dbg
)
33 INTERCEPT_WRAP_W_W(malloc
)
34 INTERCEPT_WRAP_W_W(_malloc_base
)
35 INTERCEPT_WRAP_W_WWWW(_malloc_dbg
)
37 INTERCEPT_WRAP_W_WW(calloc
)
38 INTERCEPT_WRAP_W_WW(_calloc_base
)
39 INTERCEPT_WRAP_W_WWWWW(_calloc_dbg
)
40 INTERCEPT_WRAP_W_WWW(_calloc_impl
)
42 INTERCEPT_WRAP_W_WW(realloc
)
43 INTERCEPT_WRAP_W_WW(_realloc_base
)
44 INTERCEPT_WRAP_W_WWW(_realloc_dbg
)
45 INTERCEPT_WRAP_W_WWW(_recalloc
)
46 INTERCEPT_WRAP_W_WWW(_recalloc_base
)
48 INTERCEPT_WRAP_W_W(_msize
)
49 INTERCEPT_WRAP_W_W(_expand
)
50 INTERCEPT_WRAP_W_W(_expand_dbg
)
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().
55 // TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
57 INTERCEPT_LIBRARY_FUNCTION(atoi
);
58 INTERCEPT_LIBRARY_FUNCTION(atol
);
59 INTERCEPT_LIBRARY_FUNCTION(frexp
);
60 INTERCEPT_LIBRARY_FUNCTION(longjmp
);
61 #if SANITIZER_INTERCEPT_MEMCHR
62 INTERCEPT_LIBRARY_FUNCTION(memchr
);
64 INTERCEPT_LIBRARY_FUNCTION(memcmp
);
65 INTERCEPT_LIBRARY_FUNCTION(memcpy
);
66 INTERCEPT_LIBRARY_FUNCTION(memmove
);
67 INTERCEPT_LIBRARY_FUNCTION(memset
);
68 INTERCEPT_LIBRARY_FUNCTION(strcat
); // NOLINT
69 INTERCEPT_LIBRARY_FUNCTION(strchr
);
70 INTERCEPT_LIBRARY_FUNCTION(strcmp
);
71 INTERCEPT_LIBRARY_FUNCTION(strcpy
); // NOLINT
72 INTERCEPT_LIBRARY_FUNCTION(strcspn
);
73 INTERCEPT_LIBRARY_FUNCTION(strdup
);
74 INTERCEPT_LIBRARY_FUNCTION(strlen
);
75 INTERCEPT_LIBRARY_FUNCTION(strncat
);
76 INTERCEPT_LIBRARY_FUNCTION(strncmp
);
77 INTERCEPT_LIBRARY_FUNCTION(strncpy
);
78 INTERCEPT_LIBRARY_FUNCTION(strnlen
);
79 INTERCEPT_LIBRARY_FUNCTION(strpbrk
);
80 INTERCEPT_LIBRARY_FUNCTION(strrchr
);
81 INTERCEPT_LIBRARY_FUNCTION(strspn
);
82 INTERCEPT_LIBRARY_FUNCTION(strstr
);
83 INTERCEPT_LIBRARY_FUNCTION(strtok
);
84 INTERCEPT_LIBRARY_FUNCTION(strtol
);
85 INTERCEPT_LIBRARY_FUNCTION(wcslen
);
86 INTERCEPT_LIBRARY_FUNCTION(wcsnlen
);
89 INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler
);
91 INTERCEPT_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).
94 INTERCEPTOR(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
);
100 // Window specific functions not included in asan_interface.inc.
101 INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return
)
102 INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address
)
103 INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter
)
105 using namespace __sanitizer
;
108 int __asan_option_detect_stack_use_after_return
;
109 uptr __asan_shadow_memory_dynamic_address
;
112 static 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.
118 // Ensure all interception was executed.
121 fn
= (fntype
) dllThunkGetRealAddrOrDie("__asan_init");
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();
129 INTERCEPT_FUNCTION(_except_handler4
);
131 // In DLLs, the callbacks are expected to return 0,
132 // otherwise CRT initialization fails.
136 #pragma section(".CRT$XIB", long, read) // NOLINT
137 __declspec(allocate(".CRT$XIB")) int (*__asan_preinit
)() = asan_dll_thunk_init
;
139 static void WINAPI
asan_thread_init(void *mod
, unsigned long reason
,
141 if (reason
== /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
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
;
148 WIN_FORCE_LINK(__asan_dso_reg_hook
)
150 #endif // SANITIZER_DLL_THUNK