about summary refs log tree commit diff stats
path: root/src/tools/callback.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-03-25 19:10:34 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-03-25 19:10:34 +0100
commitb17d80247656f5679a24bf5b43920eca524a7089 (patch)
treed615925b4f5feab7763f1f2d476fe2f0839668cf /src/tools/callback.c
parent9ebdf642984d5f617ac35e5183c1802b37be6d86 (diff)
downloadbox64-b17d80247656f5679a24bf5b43920eca524a7089.tar.gz
box64-b17d80247656f5679a24bf5b43920eca524a7089.zip
Fixed RunFunction and DynaCall/EmuCall with stack arguments
Diffstat (limited to 'src/tools/callback.c')
-rwxr-xr-xsrc/tools/callback.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/tools/callback.c b/src/tools/callback.c
index 8cdc117c..0d9b0c5d 100755
--- a/src/tools/callback.c
+++ b/src/tools/callback.c
@@ -19,9 +19,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
     (void)context;
 
     x64emu_t *emu = thread_get_emu();
+    int align = (nargs>6)?(((nargs-6)&1)):0;
+    int stackn = align + ((nargs>6)?(nargs-6):0);
 
-    if(nargs>6)
-        R_ESP -= (nargs-6)*sizeof(void*);   // need to push in reverse order
+    Push64(emu, R_RBP); // push rbp
+    R_RBP = R_RSP;      // mov rbp, rsp
+
+    R_RSP -= stackn*sizeof(void*);   // need to push in reverse order
 
     uint64_t *p = (uint64_t*)R_RSP;
 
@@ -38,9 +42,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
     }
     va_end (va);
 
+    uintptr_t oldip = R_RIP;
     DynaCall(emu, fnc);
-    if(nargs>6)
-        R_ESP+=((nargs-6)*sizeof(void*));
+
+    if(oldip==R_RIP) {
+        R_RSP = R_RBP;          // mov rsp, rbp
+        R_RBP = Pop64(emu);     // pop rbp
+    }
 
     uint64_t ret = R_RAX;
 
@@ -50,8 +58,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
 EXPORTDYN
 uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...)
 {
-    if(nargs>6)
-        R_ESP -= (nargs-6)*sizeof(void*);   // need to push in reverse order
+    int align = (nargs>6)?(((nargs-6)&1)):0;
+    int stackn = align + ((nargs>6)?(nargs-6):0);
+
+    Push64(emu, R_RBP); // push rbp
+    R_RBP = R_RSP;      // mov rbp, rsp
+
+    R_RSP -= stackn*sizeof(void*);   // need to push in reverse order
 
     uint64_t *p = (uint64_t*)R_RSP;
 
@@ -77,8 +90,10 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in
 
     DynaCall(emu, fnc);
 
-    if(oldip==R_RIP && nargs>6)
-        R_ESP+=((nargs-6)*sizeof(void*));   // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
+    if(oldip==R_RIP) {
+        R_RSP = R_RBP;      // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
+        R_RBP = Pop64(emu); //Pop EBP
+    }
 
     emu->quit = old_quit;
     emu->quitonlongjmp = oldlong;