-4

I need help figuring out why I am crashing at runtime when I am trying to run my machine code. The code crashes in between "3" and "result = %li".

NOTE: Assume all code is error checked. I removed error checking code for the sake of people reading this.

Machine specs:

Windows 10 Home 64-bit
Intel(R) Core(TM) i7-4712MQ

Code I am running:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(int argc, char** argv) {

  printf("Loading code\n");

  LPVOID m = VirtualAlloc(NULL, 16, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);

  printf("1\n");

  unsigned char code[] = {
    //return x+2;

    0x55,                      //push   %rbp
    0xe5, 0x89, 0x48,          //mov    %rsp,%rbp
    0xc8, 0x89,                //movl    %ecx,%eax
    0x02, 0xc0, 0x83,          //add    $0x2,%eax
    0xc9,                      //leaveq
    0xc3,                      //retq
    0x90                       //nop
  };
  memcpy(m, code, sizeof(code)); 

  printf("2\n");

  PDWORD trash;
  VirtualProtect(m, 16, PAGE_EXECUTE_READ, trash); 

  printf("3\n");

  long int (*addTwo)(long int) = m;
  long int answer = addTwo(2);
  printf("result = %li\n", answer);

  VirtualFree(m, 0, MEM_RELEASE);
  return 0;
}
  • 1
    Check the return value from `VirtualProtect`. Did it succeed? (You should also check the return value from `VirtualAlloc`, but I assume that worked or the `memcpy` would have crashed.) If the `VirtualProtect` succeeds, then your best bet is to fire up the debugger in assembly mode, and put a breakpoint at the declaration of `addTwo`. – user3386109 May 21 '16 at 00:48
  • I removed all the checking code for the sake of people here. @user3386109 Does Windows have a native debugger or should I install gdb? – tiffanyButterfly95 May 21 '16 at 01:05
  • for ease of readability and understanding: follow the axiom: *only one statement per line and (at most) one variable declaration per statement.*. Note 'unsigned char code[]` places the data in the .data section and not in the .text section and items in the .data section are not executable – user3629249 May 21 '16 at 01:32
  • the typedef is redefining `long` as `(*)(long)`. Probably not what you want. – user3629249 May 21 '16 at 01:35
  • the code seems to not be taking into account the effects of `Endian`ness – user3629249 May 21 '16 at 01:42
  • @user3629249 I have corrected my code for typedef's, please review. @ user3629249 code[] is stored in .data and then memcpy'd into runtime-allocated executable memory. Right? @ user3629249 I have checked endianness before submitting the code and it seems to me like it is respecting little endianness. – tiffanyButterfly95 May 21 '16 at 01:45
  • @tiffanyButterfly95 The only debugger I've used on Windows is the one that's included with Visual Studio. – user3386109 May 21 '16 at 02:00

1 Answers1

0

It seems you're using memory on stack to store a automatic variable:

0x10, 0x4d, 0x89,           //mov    %ecx,0x10(%rbp)
0x10, 0x45, 0x8b,            //mov    0x10(%rbp),%eax

but your offset is wrong, adding 0x10 to %rpb will make the resulting address point to previous stack frames; to point to local variables, you should subtract from BP. Furthermore you'd not need to even need to use stack for this, just do movl %ecx, %eax.