[compiler-rt] [compiler-rt] Intercept MinGW x86-64 import thunks (PR #222710)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 09:51:01 PDT 2026


https://github.com/oltolm created https://github.com/llvm/llvm-project/pull/222710

MinGW GCC emits RIP-relative indirect jumps through the import address table. Teach redirect-jump interception to recognize that form and replace its target pointer.

>From a63fbb67419c6558985f00b4e297fadba4545346 Mon Sep 17 00:00:00 2001
From: Oleg Tolmatcev <oleg.tolmatcev at gmail.com>
Date: Thu, 10 Sep 2026 17:53:59 +0200
Subject: [PATCH] [compiler-rt] Intercept MinGW x86-64 import thunks

MinGW GCC emits RIP-relative indirect jumps through the import address
table. Teach redirect-jump interception to recognize that form and
replace its target pointer.

Co-authored-by: Hannes Domani <ssbssa at yahoo.de>
---
 .../lib/interception/interception_win.cpp     | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index b43776418f621..59ff2a985b915 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -1122,6 +1122,33 @@ bool OverrideFunctionWithDetour(
 
 bool OverrideFunctionWithRedirectJump(
     uptr old_func, uptr new_func, uptr *orig_old_func) {
+#  if SANITIZER_WINDOWS64 && defined(__GNUC__) && !defined(__clang__)
+  u8* old_u8 = (u8*)old_func;
+
+  // Relative indirect jump.
+  if (old_u8[0] == 0xff && old_u8[1] == 0x25) {
+    sptr relative_offset = *(s32*)(old_func + 2);
+    uptr* absolute_target_ptr = (uptr*)(old_func + 6 + relative_offset);
+    if (orig_old_func)
+      *orig_old_func = *absolute_target_ptr;
+
+    // Change memory protection to writable.
+    DWORD protection = 0;
+    if (!ChangeMemoryProtection((uptr)absolute_target_ptr, sizeof(uptr),
+                                &protection))
+      return false;
+
+    *absolute_target_ptr = new_func;
+
+    // Restore previous memory protection.
+    if (!RestoreMemoryProtection((uptr)absolute_target_ptr, sizeof(uptr),
+                                 protection))
+      return false;
+
+    return true;
+  }
+#  endif
+
   // Check whether the first instruction is a relative jump.
   if (*(u8*)old_func != 0xE9)
     return false;



More information about the llvm-commits mailing list