Index: lib/interception/interception_win.h =================================================================== --- lib/interception/interception_win.h +++ lib/interception/interception_win.h @@ -42,6 +42,23 @@ const char *function_name, uptr new_function, uptr *orig_old_func); +#if !SANITIZER_WINDOWS64 +// Exposed for unittests +bool OverrideFunctionWithDetour( + uptr old_func, uptr new_func, uptr *orig_old_func); +#endif + +// Exposed for unittests +bool OverrideFunctionWithRedirectJump( + uptr old_func, uptr new_func, uptr *orig_old_func); +bool OverrideFunctionWithHotPatch( + uptr old_func, uptr new_func, uptr *orig_old_func); +bool OverrideFunctionWithTrampoline( + uptr old_func, uptr new_func, uptr *orig_old_func); + +// Exposed for unittests +void TestOnlyReleaseTrampolineRegions(); + } // namespace __interception #if defined(INTERCEPTION_DYNAMIC_CRT) Index: lib/interception/interception_win.cc =================================================================== --- lib/interception/interception_win.cc +++ lib/interception/interception_win.cc @@ -10,16 +10,139 @@ // This file is a part of AddressSanitizer, an address sanity checker. // // Windows-specific interception methods. +// +// This file is implementing several hooking techniques to intercept calls +// to functions. The hooks are dynamically installed by modifying the assembly +// code. +// +// The hooking techniques are making assumptions on the way the code is +// generated and are safe under certain assumptions. +// +// On 64-bit architecture, there is no direct 64-bit jump instruction. To allow +// arbitrary branching on the whole memory space, the notion of trampoline +// region is used. A trampoline region is a memory space withing 2G boundary +// where it is safe to add custom assembly code to build 64-bit jumps. +// +// Hooking techniques +// ================== +// +// 1) Detour +// +// The Detour hooking technique is assuming the presence of an header with +// padding and an overridable 2-bytes nop instruction (mov edi, edi). The +// nop instruction can safely be replaced by a 2-bytes jump without any need +// to save the instruction. A jump to the target is encoded in the function +// header and the nop instruction is replaced by a short jump to the header. +// +// head: 5 x nop head: jmp +// func: mov edi, edi --> func: jmp short +// [...] real: [...] +// +// This technique is only implemented on 32-bit architecture. +// Most of the time, Windows API are hookable with the detour technique. +// +// 2) Redirect Jump +// +// The redirect jump is applicable when the first instruction is a direct +// jump. The instruction is replaced by jump to the hook. +// +// func: jmp