1 //===-- asan_win_dll_thunk.cc ---------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of AddressSanitizer, an address sanity checker.
12 // This file defines a family of thunks that should be statically linked into
13 // the DLLs that have ASan instrumentation in order to delegate the calls to the
14 // shared runtime that lives in the main binary.
15 // See https://code.google.com/p/address-sanitizer/issues/detail?id=209 for the
17 //===----------------------------------------------------------------------===//
19 // Only compile this code when buidling asan_dll_thunk.lib
20 // Using #ifdef rather than relying on Makefiles etc.
21 // simplifies the build procedure.
23 #include "asan_init_version.h"
24 #include "interception/interception.h"
26 // ---------- Function interception helper functions and macros ----------- {{{1
28 void *__stdcall GetModuleHandleA(const char *module_name);
29 void *__stdcall GetProcAddress(void *module, const char *proc_name);
33 static void *getRealProcAddressOrDie(const char *name) {
34 void *ret = GetProcAddress(GetModuleHandleA(0), name);
40 // We need to intercept some functions (e.g. ASan interface, memory allocator --
41 // let's call them "hooks") exported by the DLL thunk and forward the hooks to
42 // the runtime in the main module.
43 // However, we don't want to keep two lists of these hooks.
44 // To avoid that, the list of hooks should be defined using the
45 // INTERCEPT_WHEN_POSSIBLE macro. Then, all these hooks can be intercepted
46 // at once by calling INTERCEPT_HOOKS().
48 // Use macro+template magic to automatically generate the list of hooks.
49 // Each hook at line LINE defines a template class with a static
50 // FunctionInterceptor<LINE>::Execute() method intercepting the hook.
51 // The default implementation of FunctionInterceptor<LINE> is to call
52 // the Execute() method corresponding to the previous line.
54 struct FunctionInterceptor {
55 static void Execute() { FunctionInterceptor<LINE-1>::Execute(); }
58 // There shouldn't be any hooks with negative definition line number.
60 struct FunctionInterceptor<0> {
61 static void Execute() {}
64 #define INTERCEPT_WHEN_POSSIBLE(main_function, dll_function) \
65 template<> struct FunctionInterceptor<__LINE__> { \
66 static void Execute() { \
67 void *wrapper = getRealProcAddressOrDie(main_function); \
68 if (!__interception::OverrideFunction((uptr)dll_function, \
71 FunctionInterceptor<__LINE__-1>::Execute(); \
75 // Special case of hooks -- ASan own interface functions. Those are only called
76 // after __asan_init, thus an empty implementation is sufficient.
77 #define INTERFACE_FUNCTION(name) \
78 extern "C" __declspec(noinline) void name() { \
79 volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf; \
82 INTERCEPT_WHEN_POSSIBLE(#name, name)
84 // INTERCEPT_HOOKS must be used after the last INTERCEPT_WHEN_POSSIBLE.
85 #define INTERCEPT_HOOKS FunctionInterceptor<__LINE__>::Execute
87 // We can't define our own version of strlen etc. because that would lead to
88 // link-time or even type mismatch errors. Instead, we can declare a function
89 // just to be able to get its address. Me may miss the first few calls to the
90 // functions since it can be called before __asan_init, but that would lead to
91 // false negatives in the startup code before user's global initializers, which
93 #define INTERCEPT_LIBRARY_FUNCTION(name) \
94 extern "C" void name(); \
95 INTERCEPT_WHEN_POSSIBLE(WRAPPER_NAME(name), name)
97 // Disable compiler warnings that show up if we declare our own version
98 // of a compiler intrinsic (e.g. strlen).
99 #pragma warning(disable: 4391)
100 #pragma warning(disable: 4392)
102 static void InterceptHooks();
105 // ---------- Function wrapping helpers ----------------------------------- {{{1
106 #define WRAP_V_V(name) \
107 extern "C" void name() { \
108 typedef void (*fntype)(); \
109 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
112 INTERCEPT_WHEN_POSSIBLE(#name, name);
114 #define WRAP_V_W(name) \
115 extern "C" void name(void *arg) { \
116 typedef void (*fntype)(void *arg); \
117 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
120 INTERCEPT_WHEN_POSSIBLE(#name, name);
122 #define WRAP_V_WW(name) \
123 extern "C" void name(void *arg1, void *arg2) { \
124 typedef void (*fntype)(void *, void *); \
125 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
128 INTERCEPT_WHEN_POSSIBLE(#name, name);
130 #define WRAP_V_WWW(name) \
131 extern "C" void name(void *arg1, void *arg2, void *arg3) { \
132 typedef void *(*fntype)(void *, void *, void *); \
133 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
134 fn(arg1, arg2, arg3); \
136 INTERCEPT_WHEN_POSSIBLE(#name, name);
138 #define WRAP_W_V(name) \
139 extern "C" void *name() { \
140 typedef void *(*fntype)(); \
141 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
144 INTERCEPT_WHEN_POSSIBLE(#name, name);
146 #define WRAP_W_W(name) \
147 extern "C" void *name(void *arg) { \
148 typedef void *(*fntype)(void *arg); \
149 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
152 INTERCEPT_WHEN_POSSIBLE(#name, name);
154 #define WRAP_W_WW(name) \
155 extern "C" void *name(void *arg1, void *arg2) { \
156 typedef void *(*fntype)(void *, void *); \
157 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
158 return fn(arg1, arg2); \
160 INTERCEPT_WHEN_POSSIBLE(#name, name);
162 #define WRAP_W_WWW(name) \
163 extern "C" void *name(void *arg1, void *arg2, void *arg3) { \
164 typedef void *(*fntype)(void *, void *, void *); \
165 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
166 return fn(arg1, arg2, arg3); \
168 INTERCEPT_WHEN_POSSIBLE(#name, name);
170 #define WRAP_W_WWWW(name) \
171 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4) { \
172 typedef void *(*fntype)(void *, void *, void *, void *); \
173 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
174 return fn(arg1, arg2, arg3, arg4); \
176 INTERCEPT_WHEN_POSSIBLE(#name, name);
178 #define WRAP_W_WWWWW(name) \
179 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \
181 typedef void *(*fntype)(void *, void *, void *, void *, void *); \
182 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
183 return fn(arg1, arg2, arg3, arg4, arg5); \
185 INTERCEPT_WHEN_POSSIBLE(#name, name);
187 #define WRAP_W_WWWWWW(name) \
188 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \
189 void *arg5, void *arg6) { \
190 typedef void *(*fntype)(void *, void *, void *, void *, void *, void *); \
191 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
192 return fn(arg1, arg2, arg3, arg4, arg5, arg6); \
194 INTERCEPT_WHEN_POSSIBLE(#name, name);
197 // ----------------- ASan own interface functions --------------------
198 // Don't use the INTERFACE_FUNCTION machinery for this function as we actually
199 // want to call it in the __asan_init interceptor.
200 WRAP_W_V(__asan_should_detect_stack_use_after_return)
203 int __asan_option_detect_stack_use_after_return;
205 // Manually wrap __asan_init as we need to initialize
206 // __asan_option_detect_stack_use_after_return afterwards.
208 typedef void (*fntype)();
209 static fntype fn = 0;
210 // __asan_init is expected to be called by only one thread.
213 fn = (fntype)getRealProcAddressOrDie(__asan_init_name);
215 __asan_option_detect_stack_use_after_return =
216 (__asan_should_detect_stack_use_after_return() != 0);
222 INTERFACE_FUNCTION(__asan_handle_no_return)
224 INTERFACE_FUNCTION(__asan_report_store1)
225 INTERFACE_FUNCTION(__asan_report_store2)
226 INTERFACE_FUNCTION(__asan_report_store4)
227 INTERFACE_FUNCTION(__asan_report_store8)
228 INTERFACE_FUNCTION(__asan_report_store16)
229 INTERFACE_FUNCTION(__asan_report_store_n)
231 INTERFACE_FUNCTION(__asan_report_load1)
232 INTERFACE_FUNCTION(__asan_report_load2)
233 INTERFACE_FUNCTION(__asan_report_load4)
234 INTERFACE_FUNCTION(__asan_report_load8)
235 INTERFACE_FUNCTION(__asan_report_load16)
236 INTERFACE_FUNCTION(__asan_report_load_n)
238 INTERFACE_FUNCTION(__asan_store1)
239 INTERFACE_FUNCTION(__asan_store2)
240 INTERFACE_FUNCTION(__asan_store4)
241 INTERFACE_FUNCTION(__asan_store8)
242 INTERFACE_FUNCTION(__asan_store16)
243 INTERFACE_FUNCTION(__asan_storeN)
245 INTERFACE_FUNCTION(__asan_load1)
246 INTERFACE_FUNCTION(__asan_load2)
247 INTERFACE_FUNCTION(__asan_load4)
248 INTERFACE_FUNCTION(__asan_load8)
249 INTERFACE_FUNCTION(__asan_load16)
250 INTERFACE_FUNCTION(__asan_loadN)
252 INTERFACE_FUNCTION(__asan_memcpy);
253 INTERFACE_FUNCTION(__asan_memset);
254 INTERFACE_FUNCTION(__asan_memmove);
256 INTERFACE_FUNCTION(__asan_register_globals)
257 INTERFACE_FUNCTION(__asan_unregister_globals)
259 INTERFACE_FUNCTION(__asan_before_dynamic_init)
260 INTERFACE_FUNCTION(__asan_after_dynamic_init)
262 INTERFACE_FUNCTION(__asan_poison_stack_memory)
263 INTERFACE_FUNCTION(__asan_unpoison_stack_memory)
265 INTERFACE_FUNCTION(__asan_poison_memory_region)
266 INTERFACE_FUNCTION(__asan_unpoison_memory_region)
268 INTERFACE_FUNCTION(__asan_address_is_poisoned)
269 INTERFACE_FUNCTION(__asan_region_is_poisoned)
271 INTERFACE_FUNCTION(__asan_get_current_fake_stack)
272 INTERFACE_FUNCTION(__asan_addr_is_in_fake_stack)
274 INTERFACE_FUNCTION(__asan_stack_malloc_0)
275 INTERFACE_FUNCTION(__asan_stack_malloc_1)
276 INTERFACE_FUNCTION(__asan_stack_malloc_2)
277 INTERFACE_FUNCTION(__asan_stack_malloc_3)
278 INTERFACE_FUNCTION(__asan_stack_malloc_4)
279 INTERFACE_FUNCTION(__asan_stack_malloc_5)
280 INTERFACE_FUNCTION(__asan_stack_malloc_6)
281 INTERFACE_FUNCTION(__asan_stack_malloc_7)
282 INTERFACE_FUNCTION(__asan_stack_malloc_8)
283 INTERFACE_FUNCTION(__asan_stack_malloc_9)
284 INTERFACE_FUNCTION(__asan_stack_malloc_10)
286 INTERFACE_FUNCTION(__asan_stack_free_0)
287 INTERFACE_FUNCTION(__asan_stack_free_1)
288 INTERFACE_FUNCTION(__asan_stack_free_2)
289 INTERFACE_FUNCTION(__asan_stack_free_4)
290 INTERFACE_FUNCTION(__asan_stack_free_5)
291 INTERFACE_FUNCTION(__asan_stack_free_6)
292 INTERFACE_FUNCTION(__asan_stack_free_7)
293 INTERFACE_FUNCTION(__asan_stack_free_8)
294 INTERFACE_FUNCTION(__asan_stack_free_9)
295 INTERFACE_FUNCTION(__asan_stack_free_10)
297 // FIXME: we might want to have a sanitizer_win_dll_thunk?
298 INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
299 INTERFACE_FUNCTION(__sanitizer_cov)
300 INTERFACE_FUNCTION(__sanitizer_cov_dump)
301 INTERFACE_FUNCTION(__sanitizer_cov_indir_call16)
302 INTERFACE_FUNCTION(__sanitizer_cov_init)
303 INTERFACE_FUNCTION(__sanitizer_cov_module_init)
304 INTERFACE_FUNCTION(__sanitizer_cov_trace_basic_block)
305 INTERFACE_FUNCTION(__sanitizer_cov_trace_func_enter)
306 INTERFACE_FUNCTION(__sanitizer_cov_with_check)
307 INTERFACE_FUNCTION(__sanitizer_free_hook)
308 INTERFACE_FUNCTION(__sanitizer_get_allocated_size)
309 INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
310 INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
311 INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
312 INTERFACE_FUNCTION(__sanitizer_get_free_bytes)
313 INTERFACE_FUNCTION(__sanitizer_get_heap_size)
314 INTERFACE_FUNCTION(__sanitizer_get_ownership)
315 INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)
316 INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)
317 INTERFACE_FUNCTION(__sanitizer_malloc_hook)
318 INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)
319 INTERFACE_FUNCTION(__sanitizer_print_stack_trace)
320 INTERFACE_FUNCTION(__sanitizer_ptr_cmp)
321 INTERFACE_FUNCTION(__sanitizer_ptr_sub)
322 INTERFACE_FUNCTION(__sanitizer_report_error_summary)
323 INTERFACE_FUNCTION(__sanitizer_reset_coverage)
324 INTERFACE_FUNCTION(__sanitizer_sandbox_on_notify)
325 INTERFACE_FUNCTION(__sanitizer_set_death_callback)
326 INTERFACE_FUNCTION(__sanitizer_set_report_path)
327 INTERFACE_FUNCTION(__sanitizer_unaligned_load16)
328 INTERFACE_FUNCTION(__sanitizer_unaligned_load32)
329 INTERFACE_FUNCTION(__sanitizer_unaligned_load64)
330 INTERFACE_FUNCTION(__sanitizer_unaligned_store16)
331 INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
332 INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
333 INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
335 // TODO(timurrrr): Add more interface functions on the as-needed basis.
337 // ----------------- Memory allocation functions ---------------------
342 WRAP_W_WWWW(_malloc_dbg)
345 WRAP_W_WWWWW(_calloc_dbg)
346 WRAP_W_WWW(_calloc_impl)
349 WRAP_W_WWW(_realloc_dbg)
350 WRAP_W_WWW(_recalloc)
354 WRAP_W_W(_expand_dbg)
356 // TODO(timurrrr): Might want to add support for _aligned_* allocation
357 // functions to detect a bit more bugs. Those functions seem to wrap malloc().
359 // TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
361 INTERCEPT_LIBRARY_FUNCTION(atoi);
362 INTERCEPT_LIBRARY_FUNCTION(atol);
363 INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
365 // _except_handler4 checks -GS cookie which is different for each module, so we
366 // can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
367 INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
368 __asan_handle_no_return();
369 return REAL(_except_handler4)(a, b, c, d);
372 INTERCEPT_LIBRARY_FUNCTION(frexp);
373 INTERCEPT_LIBRARY_FUNCTION(longjmp);
374 INTERCEPT_LIBRARY_FUNCTION(memchr);
375 INTERCEPT_LIBRARY_FUNCTION(memcmp);
376 INTERCEPT_LIBRARY_FUNCTION(memcpy);
377 INTERCEPT_LIBRARY_FUNCTION(memmove);
378 INTERCEPT_LIBRARY_FUNCTION(memset);
379 INTERCEPT_LIBRARY_FUNCTION(strcat); // NOLINT
380 INTERCEPT_LIBRARY_FUNCTION(strchr);
381 INTERCEPT_LIBRARY_FUNCTION(strcmp);
382 INTERCEPT_LIBRARY_FUNCTION(strcpy); // NOLINT
383 INTERCEPT_LIBRARY_FUNCTION(strlen);
384 INTERCEPT_LIBRARY_FUNCTION(strncat);
385 INTERCEPT_LIBRARY_FUNCTION(strncmp);
386 INTERCEPT_LIBRARY_FUNCTION(strncpy);
387 INTERCEPT_LIBRARY_FUNCTION(strnlen);
388 INTERCEPT_LIBRARY_FUNCTION(strtol);
389 INTERCEPT_LIBRARY_FUNCTION(wcslen);
391 // Must be after all the interceptor declarations due to the way INTERCEPT_HOOKS
393 void InterceptHooks() {
395 INTERCEPT_FUNCTION(_except_handler4);
398 // We want to call __asan_init before C/C++ initializers/constructors are
399 // executed, otherwise functions like memset might be invoked.
400 // For some strange reason, merely linking in asan_preinit.cc doesn't work
401 // as the callback is never called... Is link.exe doing something too smart?
403 // In DLLs, the callbacks are expected to return 0,
404 // otherwise CRT initialization fails.
405 static int call_asan_init() {
409 #pragma section(".CRT$XIB", long, read) // NOLINT
410 __declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init;
412 #endif // ASAN_DLL_THUNK