153 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- asan_win_dll_thunk.cc ---------------------------------------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// This file is a part of AddressSanitizer, an address sanity checker.
 | 
						|
//
 | 
						|
// This file defines a family of thunks that should be statically linked into
 | 
						|
// the DLLs that have ASan instrumentation in order to delegate the calls to the
 | 
						|
// shared runtime that lives in the main binary.
 | 
						|
// See https://github.com/google/sanitizers/issues/209 for the details.
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#ifdef SANITIZER_DLL_THUNK
 | 
						|
#include "asan_init_version.h"
 | 
						|
#include "interception/interception.h"
 | 
						|
#include "sanitizer_common/sanitizer_win_defs.h"
 | 
						|
#include "sanitizer_common/sanitizer_win_dll_thunk.h"
 | 
						|
#include "sanitizer_common/sanitizer_platform_interceptors.h"
 | 
						|
 | 
						|
// ASan own interface functions.
 | 
						|
#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
 | 
						|
#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
 | 
						|
#include "asan_interface.inc"
 | 
						|
 | 
						|
// Memory allocation functions.
 | 
						|
INTERCEPT_WRAP_V_W(free)
 | 
						|
INTERCEPT_WRAP_V_W(_free_base)
 | 
						|
INTERCEPT_WRAP_V_WW(_free_dbg)
 | 
						|
 | 
						|
INTERCEPT_WRAP_W_W(malloc)
 | 
						|
INTERCEPT_WRAP_W_W(_malloc_base)
 | 
						|
INTERCEPT_WRAP_W_WWWW(_malloc_dbg)
 | 
						|
 | 
						|
INTERCEPT_WRAP_W_WW(calloc)
 | 
						|
INTERCEPT_WRAP_W_WW(_calloc_base)
 | 
						|
INTERCEPT_WRAP_W_WWWWW(_calloc_dbg)
 | 
						|
INTERCEPT_WRAP_W_WWW(_calloc_impl)
 | 
						|
 | 
						|
INTERCEPT_WRAP_W_WW(realloc)
 | 
						|
INTERCEPT_WRAP_W_WW(_realloc_base)
 | 
						|
INTERCEPT_WRAP_W_WWW(_realloc_dbg)
 | 
						|
INTERCEPT_WRAP_W_WWW(_recalloc)
 | 
						|
INTERCEPT_WRAP_W_WWW(_recalloc_base)
 | 
						|
 | 
						|
INTERCEPT_WRAP_W_W(_msize)
 | 
						|
INTERCEPT_WRAP_W_W(_msize_base)
 | 
						|
INTERCEPT_WRAP_W_W(_expand)
 | 
						|
INTERCEPT_WRAP_W_W(_expand_dbg)
 | 
						|
 | 
						|
// TODO(timurrrr): Might want to add support for _aligned_* allocation
 | 
						|
// functions to detect a bit more bugs.  Those functions seem to wrap malloc().
 | 
						|
 | 
						|
// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
 | 
						|
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(atoi);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(atol);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(frexp);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(longjmp);
 | 
						|
#if SANITIZER_INTERCEPT_MEMCHR
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(memchr);
 | 
						|
#endif
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(memcmp);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(memcpy);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(memmove);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(memset);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strcat);  // NOLINT
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strchr);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strcmp);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strcpy);  // NOLINT
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strcspn);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strdup);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strlen);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strncat);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strncmp);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strncpy);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strnlen);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strpbrk);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strrchr);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strspn);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strstr);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strtok);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(strtol);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(wcslen);
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(wcsnlen);
 | 
						|
 | 
						|
#ifdef _WIN64
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);
 | 
						|
#else
 | 
						|
INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
 | 
						|
// _except_handler4 checks -GS cookie which is different for each module, so we
 | 
						|
// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
 | 
						|
INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
 | 
						|
  __asan_handle_no_return();
 | 
						|
  return REAL(_except_handler4)(a, b, c, d);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
// Windows specific functions not included in asan_interface.inc.
 | 
						|
INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
 | 
						|
INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
 | 
						|
INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
 | 
						|
 | 
						|
using namespace __sanitizer;
 | 
						|
 | 
						|
extern "C" {
 | 
						|
int __asan_option_detect_stack_use_after_return;
 | 
						|
uptr __asan_shadow_memory_dynamic_address;
 | 
						|
} // extern "C"
 | 
						|
 | 
						|
static int asan_dll_thunk_init() {
 | 
						|
  typedef void (*fntype)();
 | 
						|
  static fntype fn = 0;
 | 
						|
  // asan_dll_thunk_init is expected to be called by only one thread.
 | 
						|
  if (fn) return 0;
 | 
						|
 | 
						|
  // Ensure all interception was executed.
 | 
						|
  __dll_thunk_init();
 | 
						|
 | 
						|
  fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");
 | 
						|
  fn();
 | 
						|
  __asan_option_detect_stack_use_after_return =
 | 
						|
      (__asan_should_detect_stack_use_after_return() != 0);
 | 
						|
  __asan_shadow_memory_dynamic_address =
 | 
						|
      (uptr)__asan_get_shadow_memory_dynamic_address();
 | 
						|
 | 
						|
#ifndef _WIN64
 | 
						|
  INTERCEPT_FUNCTION(_except_handler4);
 | 
						|
#endif
 | 
						|
  // In DLLs, the callbacks are expected to return 0,
 | 
						|
  // otherwise CRT initialization fails.
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
#pragma section(".CRT$XIB", long, read)  // NOLINT
 | 
						|
__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;
 | 
						|
 | 
						|
static void WINAPI asan_thread_init(void *mod, unsigned long reason,
 | 
						|
                                    void *reserved) {
 | 
						|
  if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
 | 
						|
}
 | 
						|
 | 
						|
#pragma section(".CRT$XLAB", long, read)  // NOLINT
 | 
						|
__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
 | 
						|
    unsigned long, void *) = asan_thread_init;
 | 
						|
 | 
						|
WIN_FORCE_LINK(__asan_dso_reg_hook)
 | 
						|
 | 
						|
#endif // SANITIZER_DLL_THUNK
 |