Execute shellcode by casting to function pointer in Visual C++

jcai picture jcai · Mar 6, 2012 · Viewed 11k times · Source

In gcc this works fine. The code goes something like:

unsigned char b[50] = "\xda\xd1 ... \x0"; //some shellcode with terminating \x0
( (void(*)())b )(); //cast b to function pointer from void to void, then run it

But when this is put in Visual C++, it spits out this error message:

1>..\test.cpp(132): error C2440: 'type cast' : cannot convert from 'unsigned char [50]' to 'void (__cdecl *)(void)'
1>          There is no context in which this conversion is possible

Anyone know why this is so?

Answer

Niklas B. picture Niklas B. · Mar 7, 2012

A proper debugger will tell you what's going wrong. I can only guess that your code is causing an access violation because the buffer you want to jump to is not executable.

Probably you're on a default-DEP-enabled system like Vista or 7, so you have to make sure that your shellcode is executable. To do that, first use VirtualAlloc to allocate a new, executable buffer and copy your shellcode into it, then execute it:

void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, b, sizeof b);
((void(*)())exec)();

By the way, you don't need to null-terminate the shellcode (C++ will terminate the string literal automatically for you, but this is not necessary). You also don't need to specify a size:

unsigned char b[] = "\xcc";