Как откомпилировать функцию в исполняемый код без «связей»?

Возникла хитрая задачка с которой никогда не сталкивался. Допустим есть код:
int test()
{
    HMODULE user32;
    int (*msgbox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

    user32 = LoadLibrary("user32.dll");
    msgbox = (int (__cdecl *)(struct HWND__ *,const char *,const char *,unsigned int )) GetProcAddress(user32, "MessageBoxA");
    msgbox(0, "MSG", "Header", 0);
    FreeLibrary(user32);
    return 0;
}

Как и каким компилятором можно откомпилировать эту функцию в исполняемый код. То есть нужно получить набор байт который скопировав в память и сделав jmp/call по этому адресу будет выполнен данный код. Чем такое можно сделать?
P.S. Адреса импорта LoadLibrary/GetProcAddress/FreeLibrary не известны заранее.
  • Вопрос задан
  • 2568 просмотров
Пригласить эксперта
Ответы на вопрос 5
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
Не до конца понял что вы хотите сделать, но то что вы описываете очень похоже на динамическую библиотеку. Чем вас она не устраивает?
Ответ написан
@AM5800
Вы можете получить вашу функцию в виде набора байтов, зная адрес начала и конца функции. С первым все просто. А вот второй... Никаких "честных" способох его получения я не знаю. Но можно, например, зная адрес начала функции, начать ее читать и попытаться найти ее эпилог. Но тут, как всегда в C++ нужно быть осторожным. Эпилог может зависеть от компилятора, его настроек и платформы. Да и сама функция может инлайниться, вызывать другие функции, которые после "копирования" будут недоступны и прочие прелести.

Также можете посмотреть сюда:
stackoverflow.com/questions/4156585/how-to-get-the...
Ответ написан
icelaba
@icelaba
Знаю и умею всё
Если судя по комментариям у вас стоит задача загружать и выполнять код извне,
то достаточно набрать в гугл - how to write c++ plugin system
вам выдаст и отличные статьи с drdobbs и еще миллион ссылок.
Достаточно просто с кодом тут www.cplusplus.com/articles/48TbqMoL
И вам правильно говорят это dll, и LoadLibrary ваш друг товарищ и партнер.
Статьи про то как лучше сделать систему плагинов лучше почитать - кучу граблей не наступите.
Ответ написан
Комментировать
AxisPod
@AxisPod
Если делать тупо как вы написали, приложение тупо может упасть. Если вы не хотите делать свой компилятор, то не пытайтесь в память пихать свой код и выполнять его. Если же хотите свой скриптовый движок с JIT компилятором, то копайте именно в сторону JIT компиляторов.
Ответ написан
@xandox
То, что ты описал сильно смахивает на модули ядра linux, которые по сути есть обычные объектные файлы, которые при подгрузке в ядро проходят стадию линковки. Можно начать смотреть от туда.
Правда у меня есть опасение, что такое вообще возможно сделать в user space без всяких очень грязных хаков, все таки как ни крути, а исполнение произвольного кода считается дырой в безопасности системы. Но я не настоящий сварщик, по этому могу ошибаться.

Что бы получить объектный файл у gcc и clang есть опция -c. У VS тоже что-то такое точно должно быть, но у меня нет VS по этому посмотреть не могу. Попробуй запустить cc1{что-то-там}.exe с /? - он наверника скажет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы