about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-03 18:42:03 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-03 18:42:03 +0200
commit12467916a4ce5bf8042324f0dbb10a93da41d834 (patch)
treeb617fe857d5aff21c4df1404c19dba1dcb7be452 /src
parent6f0eb5662177f83458a8ad6db29501851f5d66b8 (diff)
downloadbox64-12467916a4ce5bf8042324f0dbb10a93da41d834.tar.gz
box64-12467916a4ce5bf8042324f0dbb10a93da41d834.zip
[DYNAREC] Re-introduce a simple HotPage handling, to speedup heavily obfuscated program loading
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c21
-rw-r--r--src/dynarec/dynablock.c2
-rw-r--r--src/dynarec/dynarec.c11
-rw-r--r--src/include/custommem.h4
-rw-r--r--src/libtools/signals.c1
5 files changed, 36 insertions, 3 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 6a56c641..476a6837 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -1190,6 +1190,27 @@ int isprotectedDB(uintptr_t addr, size_t size)
     return 1;
 }
 
+uintptr_t hotpage = 0;
+int hotpage_cnt = 0;
+#define HOTPAGE_MARK 64
+void SetHotPage(uintptr_t addr)
+{
+    hotpage = addr&~(box64_pagesize-1);
+    hotpage_cnt = HOTPAGE_MARK;
+}
+int isInHotPage(uintptr_t addr)
+{
+    if(!hotpage_cnt)
+        return 0;
+    --hotpage_cnt;
+    return (addr>=hotpage) && (addr<hotpage+box64_pagesize);
+}
+int checkInHotPage(uintptr_t addr)
+{
+    return hotpage_cnt && (addr>=hotpage) && (addr<hotpage+box64_pagesize);
+}
+
+
 #endif
 
 void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index a1792c9c..55f33670 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -261,6 +261,8 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
 
 dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
 {
+    if(isInHotPage(addr))
+        return NULL;
     dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
     if(db && db->done && db->block && getNeedTest(addr)) {
         if(db->always_test)
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index 39dc6153..1a389b94 100644
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -19,6 +19,7 @@
 #include "dynablock_private.h"
 #include "bridge.h"
 #include "dynarec_next.h"
+#include "custommem.h"
 #endif
 #ifdef HAVE_TRACE
 #include "elfloader.h"
@@ -55,9 +56,13 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
     if(!block) {
         #ifdef HAVE_TRACE
         if(LOG_INFO<=box64_dynarec_log) {
-            dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
-            elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
-            dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s), RIP=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)", (void*)*x3);
+            if(checkInHotPage(addr)) {
+                dynarec_log(LOG_INFO, "Not trying to run a block from a Hotpage at %p\n", (void*)addr);
+            } else {
+                dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
+                elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
+                dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s), RIP=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)", (void*)*x3);
+            }
         }
         #endif
         //tableupdate(native_epilog, addr, table);
diff --git a/src/include/custommem.h b/src/include/custommem.h
index 997afe85..dda21053 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -116,6 +116,10 @@ void fini_custommem_helper(box64context_t* ctx);
 // ---- StrongMemoryModel
 void addLockAddress(uintptr_t addr);    // add an address to the list of "LOCK"able
 int isLockAddress(uintptr_t addr);  // return 1 is the address is used as a LOCK, 0 else
+
+void SetHotPage(uintptr_t addr);
+int isInHotPage(uintptr_t addr);
+int checkInHotPage(uintptr_t addr);
 #endif
 
 void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 94946b9e..e9ff125a 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1396,6 +1396,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
         if(repeated_page == ((uintptr_t)addr&~(box64_pagesize-1))) {
             ++repeated_count;   // Access eoor multiple time on same page, disable dynarec on this page a few time...
             dynarec_log(LOG_DEBUG, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count);
+            SetHotPage(repeated_page);
         } else {
             repeated_page = (uintptr_t)addr&~(box64_pagesize-1);
             repeated_count = 0;