0

There are other questions about the same message, but I specifically seem to run into this when I try to execute a string of machine code that invokes certain functions. In my case I make a call to exit(0) which works fine when called as typical in C in the same program. If, however, as an exercise I set the EIP to the address of some machine code (you might call it "shellcode"), e.g.

const char code[] = 
"\x6A\x00"      // push        0"
"\xFF\x15\x00\x00\x00\x00"  //system call, 'read access violation':   call dword ptr [__imp__exit]
"\x5D"  //pop ebp    
"\xC3"; //ret

I will get the message "Access violation reading location 0x00000000.". The "\x6A\x00" instruction will run, but the call to exit(0) will throw this exception.

This is C compiled in VS2010 with /GS-, and also running the "shellcode" with execute rights, but is there still some sort of nonexecutable memory or stack protection going on? Why is this instruction causing an error?

    int main() 
{ 

    void *exec = VirtualAlloc(0, sizeof(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, code, sizeof(code));
//EIP = exec in debug->immediate
    exit(0);

}
Community
  • 1
  • 1
T. Webster
  • 9,605
  • 6
  • 67
  • 94
  • 1
    There are obviously plenty of zeros in your byte values. This is not magically going to be relocated to __imp_exit by the loader, it has no clue that your char[] is supposed to be code. You will have to do so yourself. – Hans Passant Dec 11 '12 at 02:47

1 Answers1

1

If you disassemble your shellcode, you'll get something like this (AT&T syntax):

00000000 <_code>:
   0:   6a 00                   push   $0x0
   2:   ff 15 00 00 00 00       call   *0x0
   8:   5d                      pop    %ebp
   9:   c3                      ret

The call instruction is doing a memory-indirect jump through address 0: it's loading the target from memory address 0 and jumping to that location. Since memory address 0 is invalid (in rare exceptions it can be valid, but this is no exception), an access violation results.

Ordinarily, when you compile C code, the jumps to external functions get replaced by placeholders, and those placeholders get filled in by the linker at link time. When you're generating shellcode at runtime, you don't have the assistance of the linker, so you have to do it yourself. You need to figure out what your desired target address is and fill that in directly in the shellcode, possibly using some position-independent tricks if you don't know exactly what address the shellcode is going to execute at.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589