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?
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";
The typical way to reinterpret data as a different type is by copying the binary representation:
void (*fp)();
unsigned char buf[50];
char const * p = reinterpret_cast<char const *>(&buf);
std::copy(p, p + sizeof(char const *), reinterpret_cast<char*>(&fp));
// now fp contains the same value as &buf
fp(); // call
This avoids undefined behaviour caused by aliasing and alignment violations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With