Выполнить шеллкод, приведя к указателю на функцию в Visual C ++ - PullRequest
6 голосов
/ 07 марта 2012

В 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

Кто-нибудь знает, почему это так?

Ответы [ 2 ]

12 голосов
/ 07 марта 2012

Правильный отладчик скажет вам, что происходит не так. Я могу только догадываться, что ваш код вызывает нарушение прав доступа, поскольку буфер, к которому вы хотите перейти, не является исполняемым.

Вероятно, вы работаете в системе, включенной по умолчанию - DEP , например, Vista или 7, поэтому вы должны убедиться, что ваш шелл-код является исполняемым. Для этого сначала используйте VirtualAlloc, чтобы выделить новый исполняемый буфер и скопировать в него свой шелл-код, а затем выполнить его:

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

Кстати, вам не нужно завершать шеллкод нулем (C ++ автоматически завершит строковый литерал, но это не обязательно). Вам также не нужно указывать размер:

unsigned char b[] = "\xcc";
0 голосов
/ 07 марта 2012

Типичный способ переосмысления данных как другого типа - копирование двоичного представления:

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

Это позволяет избежать неопределенного поведения, вызванного нарушениями псевдонимов и выравнивания.

...