title: C++ jump to other method execution
body: <p>In my C++ JNI-Agent project i am implementing a function which would be given a variable number of parameters and would pass the execution to the other function:</p>
  
  <pre><code>// address of theOriginalFunction
  public static void* originalfunc;
  
  void* interceptor(JNIEnv *env, jclass clazz, ...){
  
      // add 4 to the function address to skip "push ebp / mov ebp esp"
      asm volatile("jmp *%0;"::"r" (originalfunc+4));
  
      // will not get here anyway
      return NULL;
  }
  </code></pre>
  
  <p>The function above needs to just jump to the:</p>
  
  <pre><code>JNIEXPORT void JNICALL Java_main_Main_theOriginalFunction(JNIEnv *env, jclass clazz, jboolean p1, jbyte p2, jshort p3, jint p4, jlong p5, jfloat p6, jdouble p7, jintArray p8, jbyteArray p9){
      // Do something
  }
  </code></pre>
  
  <p>The code above works perfectly, the original function can read all the parameters correctly (tested with 9 parameters of different types including arrays).</p>
  
  <p>However, before jumping into original function from the interceptor i need to do some computations. However, here i observe interesting behavior.</p>
  
  <pre><code>void* interceptor(JNIEnv *env, jclass clazz, ...){
      int x = 10;
      int y = 20;
      int summ = x + y;
  
      // NEED TO RESTORE ESP TO EBP SO THAT ORIGINAL FUNCTION READS PARAMETERS CORRECTLY
      asm (
          "movl %ebp, %esp;"
          "mov %rbp, %rsp"
      );
  
      // add 4 to the function address to skip "push ebp / mov ebp esp"
      asm volatile("jmp *%0;"::"r" (originalfunc+4));
  
      // will not get here anyway
      return NULL;
  }
  </code></pre>
  
  <p>This still works fine, i am able to do some basic computations , then reset the stack pointer and jump to my original function, the original function also reads the parameters from the var_args correctly. However: if i replace the basic int operations with <code>malloc</code> or <code>printf("any string");</code> , then, somehow, if jump into my original function, then my parameters get messed up and the original function ends reading wrong values...</p>
  
  <p>I have tried to debug this behavior and i inspected the memory regions to see what is goin wrong... Right before the jump, everything looks fine there, ebp is being followed by function parameters. </p>
  
  <p>If i <strong>jump without complicated computations, everything works fine, memory region behind ebp doesnt get changed. original function reads correct values</strong>... </p>
  
  <p>Now if i <strong>jump after doing printf (for example), the parameters read by the original method get corrupted</strong>...</p>
  
  <p>What is causing this strange behavior? printf doesnt even store any lokal variables in my method... Ok it does store some literals in registers but why my stack <strong>gets corrupted only after the jump</strong> and not already before it?</p>
  
  <p>For this project I use g++ version 4.9.1 compiler running on a windows machine.</p>
  
  <p>And yes I am concerned of std::forward and templates options but they just do not work in my case... Aaand yes I know that jumping into other methods is a bit hacky but thats my only idea of how to bring JNI-interceptor to work...</p>
  
  <p>******************** EDIT ********************</p>
  
  <p>As discussed i am adding the generated assembler code with the source functions.</p>
  
  <p>Function without printf (which works fine):</p>
  
  <pre><code>void* interceptor(JNIEnv *env, jclass clazz, ...){
  
      //just an example
      int x=8;
  
      // restoring stack pointers
      asm (
          "movl %ebp, %esp;"
          "mov %rbp, %rsp"
      );
  
      // add 4 to the function address to skip "push ebp / mov ebp esp"
      asm volatile("jmp *%0;"::"r" (originalfunc+4));
  
      // will not get here anyway
      return NULL;
  }
  
  void* interceptor(JNIEnv *env, jclass clazz, ...){
      // first when interceptor is called, probably some parameter restoring...
      push %rbp
      mov %rsp %rbp
      sub $0x30, %rsp
      mov %rcx, 0x10(%rbp)
      mov %r8, 0x20(%rbp)
      mov %r9, 0x28(%rbp)
      mov %rdx, 0x18(%rbp)
  
      // int x = 8;
      movl $0x8, -0x4(%rbp)
  
      // my inline asm restoring stack pointers
      mov %ebp, %esp
      mov %rbp, %rsp
  
      // asm volatile("jmp *%0;"::"r" (originalfunc+4))
      mov 0xa698b(%rip),%rax      // store originalfunc in rax
      add %0x4, %rax
      jmpq *%rax
  
      // return NULL;
      mov $0x0, %eax
  }
  </code></pre>
  
  <p>Now asm output for printf variant...</p>
  
  <pre><code>void* interceptor(JNIEnv *env, jclass clazz, ...){
  
      //just an example
      int x=8;
  
      printf("hey");
  
      // restoring stack pointers
      asm (
          "movl %ebp, %esp;"
          "mov %rbp, %rsp"
      );
  
      // add 4 to the function address to skip "push ebp / mov ebp esp"
      asm volatile("jmp *%0;"::"r" (originalfunc+4));
  
      // will not get here anyway
      return NULL;
  }
  
  void* interceptor(JNIEnv *env, jclass clazz, ...){
      // first when interceptor is called, probably some parameter restoring...
      push %rbp
      mov %rsp %rbp
      sub $0x30, %rsp
      mov %rcx, 0x10(%rbp)
      mov %r8, 0x20(%rbp)
      mov %r9, 0x28(%rbp)
      mov %rdx, 0x18(%rbp)
  
      // int x = 8;
      movl $0x8, -0x4(%rbp)
  
      // printf("hey");
      lea 0x86970(%rip), %rcx   // stores "hey" in rcx???
      callq 0x6b701450          // calls the print function, i guess
  
      // my inline asm restoring stack pointers
      mov %ebp, %esp
      mov %rbp, %rsp
  
      // asm volatile("jmp *%0;"::"r" (originalfunc+4))
      mov 0xa698b(%rip),%rax      // store originalfunc in rax
      add %0x4, %rax
      jmpq *%rax
  
      // return NULL;
      mov $0x0, %eax
  }
  </code></pre>
  
  <p>And here is the asm code for the printf function:</p>
  
  <pre><code>printf(char const*, ...)
      push %rbp
      push %rbx
      sub $0x38, %rsp
      lea 0x80(%rsp), %rbp
      mov %rdx, -0x28(%rbp)
      mov $r8, -0x20(%rbp)
      mov $r9, -0x18(%rbp)
      mov $rcx, -0x30(%rbp)
      lea -0x28(%rbp), %rax
      mov %rax, -0x58(%rbp)
      mov -0x58(%rbp), %rax
      mov %rax, %rdx
      mov -0x30(%rbp), %rcx
      callq 0x6b70ff60 // (__mingw_vprintf)
      mov %eax, %ebx
      mov %ebx, %eax 
      add $0x38, %rsp
      pop %rbx
      pop %rbp
      retq
  </code></pre>
  
  <p>It looks like printf does many operations on rbp , but i cannot see anything wrong with it...</p>
  
  <p>And here is the asm code of the intercepted function.</p>
  
  <pre><code>push %rbp              // 1 byte
  push %rsp, %rbp        // 3 bytes , need to skip them
  sub $0x50, %rsp
  mov %rcx, 0x10(%rbp)
  mov %rdx, 0x18(%rbp)
  mov %r8d, %ecx
  mov %r9d, %edx
  mov 0x30(%rbp), %eax
  mov %cl, 0x20(%rbp)
  mov %dl, 0x28(%rbp)
  mov %ax, -0x24(%rbp)
  </code></pre>
  
  <p>************* EDIT 2 **************</p>
  
  <p>I thought it would be useful to see how memory changes at the run-time:</p>
  
  <p>The first picture shows the memory layout right after entering the interceptor function:</p>
  
  <p><a href="https://i.stack.imgur.com/zPtR7.png" rel="noreferrer"><img src="https://i.stack.imgur.com/zPtR7.png" alt="Memory Layout when entering the interceptor"></a></p>
  
  <p>The second images shows the same memory region after problematic code (like printf and so)</p>
  
  <p><a href="https://i.stack.imgur.com/ohLFq.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ohLFq.png" alt="enter image description here"></a></p>
  
  <p>The third picture shows the memory layout right after jumping to original function.</p>
  
  <p><a href="https://i.stack.imgur.com/2narR.png" rel="noreferrer"><img src="https://i.stack.imgur.com/2narR.png" alt="enter image description here"></a></p>
  
  <p>As you can see, right after calling printf , stack looks fine, however when i jump into the original function, it messes up... </p>
  
  <p>Looking at the screenshots, I am pretty sure that all the parameters lie on the stack in the memory, and parameter are not passed by registers. </p>