From f5525670ad6c5cb9f6e33b28c85589d4df97c4da Mon Sep 17 00:00:00 2001 From: Etienne Bergeron Date: Mon, 11 Jul 2016 23:02:18 +0000 Subject: [PATCH] [compiler-rt] Refactor the interception code on windows. Summary: This is a cleanup and refactoring of the interception code on windows Enhancement: * Adding the support for 64-bits code * Adding several hooking technique: * Detour * JumpRedirect * HotPatch * Trampoline * Adding a trampoline memory pool (64-bits) and release the allocated memory in unittests Cleanup: * Adding unittests for 64-bits hooking techniques * Enhancing the RoundUpInstruction by sharing common decoder Reviewers: rnk Subscribers: llvm-commits, wang0109, chrisha Differential Revision: http://reviews.llvm.org/D22111 llvm-svn: 275123 --- .../lib/interception/interception_win.cc | 905 ++++++++++++------ .../lib/interception/interception_win.h | 17 + .../tests/interception_win_test.cc | 497 ++++++++-- 3 files changed, 1079 insertions(+), 340 deletions(-) diff --git a/compiler-rt/lib/interception/interception_win.cc b/compiler-rt/lib/interception/interception_win.cc index a7d71a86e341e..5d7b6536c3815 100644 --- a/compiler-rt/lib/interception/interception_win.cc +++ b/compiler-rt/lib/interception/interception_win.cc @@ -10,16 +10,160 @@ // 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 these 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