在gcc中这很好用。代码类似于:
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
但是当它放在Visual C ++中时,它会吐出这个错误信息:
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
任何人都知道为什么会这样吗?
答案 0 :(得分:12)
一个合适的调试器会告诉你出了什么问题。我只能猜测你的代码导致访问冲突,因为你要跳转到的缓冲区不可执行。
可能你是一个默认的 - DEP启用的系统,如Vista或7,所以你必须确保你的shellcode是可执行的。为此,首先使用VirtualAlloc
分配一个新的可执行缓冲区并将shellcode复制到其中,然后执行它:
void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, b, sizeof b);
((void(*)())exec)();
顺便说一句,你不需要空终止shellcode(C ++会自动为你终止字符串文字,但这不是必需的)。您也不需要指定大小:
unsigned char b[] = "\xcc";
答案 1 :(得分:0)
将数据重新解释为不同类型的典型方法是复制二进制表示:
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
这可以避免由于别名和对齐违规而导致的未定义行为。