Выполнение shellcode путем приведения к указателю функции в Visual C++
в gcc это работает нормально. Код звучит примерно так:
unsigned char b[50] = "xdaxd1 ... 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
кто-нибудь знает, почему это так?
2 ответов
правильный отладчик скажет вам, что происходит неправильно. Я могу только догадываться, что ваш код вызывает нарушение доступа, потому что буфер, к которому вы хотите перейти, не является исполняемым.
Вероятно, вы находитесь по умолчанию -DEP-включена система, такая как Vista или 7, поэтому вы должны убедиться, что ваш shellcode является исполняемым. Для этого сначала используйте VirtualAlloc
чтобы выделить новый исполняемый буфер и скопировать в него шеллкод, выполните его:
void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, b, sizeof b);
((void(*)())exec)();
кстати, вам не нужно null-terminate shellcode (C++ автоматически завершит строковый литерал для вас, но это не обязательно). Вам также не нужно указывать размер:
unsigned char b[] = "\xcc";
типичный способ переинтерпретировать данные как другой тип-скопировать двоичное представление:
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
это позволяет избежать неопределенного поведения, вызванного нарушениями сглаживания и выравнивания.