Страницы

Поиск по вопросам

среда, 9 января 2019 г.

Как вызвать произвольный участок памяти в качестве указателя на функцию

Подскажите, можно ли как-то передать управление программы на C/C++ в произвольный доступный участок памяти?
Сделал тестовый пример (mingw, Windows), но не работает, программа аварийно завершается при вызове pw3(5)
#include using namespace std;
void work1(int value){ cout << "work1 " <void work2(int value){ cout << "work2 " <void (*pw1)(int) = work1; void (*pw2)(int) = work2; unsigned char data[100]={}; unsigned char *funcData = (unsigned char *)pw1;
int main() { cout << "start test programm" << endl;
work1(1); work2(2);
pw1(3); pw2(4);
cout <<(void*)pw1 << endl; cout <<(void*)pw2 << endl;
void (*pw3)(int) = (void (*)(int))data;
for(int i=0;i<100;i++){ data[i] = funcData[i];
} pw3(5);
cout <<"end work"<< endl;
return 0; }


Ответ

Можно или нельзя это сделать зависит не только от "правильности" конвертации указателей, но и от свойств подлежащей платформы. Ни одна современная [интерактивная] ОС не позволит вам просто так передавать управление в область данных. Это один из столпов обеспечения безопасности системы. Защита подобного рода (Data Execution Prevention) реализована как на уровне ОС, так и на уровне процессора.
Возможно, ваша ОС предоставляет средства для отключения этой защиты. Без отключения этой защиты вам необходимо ОС-зависимыми средствами пометить ваши данные, как выполняемый код, и только после этого передавать туда управление. Но для доступа к соответствующему API ваша программа должна обладать необходимыми (весьма высокими) привилегиями.
Отдельно стоит заметить, что вам никто не обещал, что код функции располагается в памяти неким компактным непрерывным образом. Т.е. ваше верование в то, что ваш цикл for копирует в массив funcData именно код функции, ничем не обосновано.
Также нет гарантии, что код функции является позиционно-независимым. Если вы специально не обеспечили генерации позиционно-независимого кода, то может получится, что даже в случае успешного копирования кода функции в массив funcData, это код на новом месте все равно не будет вести себя так, как вы ожидаете.

Комментариев нет:

Отправить комментарий