Как кросс-компилировать DLL с экспортированными функциями - PullRequest
0 голосов
/ 28 сентября 2018

Я выполняю упражнение на угон DLL, и у меня написана DLL, которая работает, как и ожидалось, при компиляции в Visual Studio.По сути, когда DLL загружается, она выполняет команду оболочки и передает допустимые функциональные возможности (в этом примере функции CheckEvenOdd и PrintAMessage ) первоначально предназначенной библиотеке DLL (в этом примере GetEvenOdd.dll ).Рабочий код выглядит следующим образом:

#include "stdafx.h"
#include <windows.h>

#pragma comment(linker, "/export:CheckEvenOdd=GetEvenOdd.dll.original.CheckEvenOdd")
#pragma comment(linker, "/export:PrintAMessage=GetEvenOdd.dll.original.PrintAMessage")

extern "C" __declspec(dllexport)
DWORD WINAPI ExecuteCmd(LPVOID lpParam) {
    WinExec("c:\\Users\\Public\\execute.bat", 0);
    return 0;
}

extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        CreateThread(NULL, NULL, ExecuteCmd, NULL, NULL, NULL);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Хотя при компиляции в Visual Studio (Windows) он работает должным образом, я хотел бы сгенерировать DLL в Linux (для использования в программе Windows).В Linux я могу кросс-компилировать файл CPP (injector.cpp) и создать библиотеку DLL с помощью этих команд:

i686-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL injector.cpp
i686-w64-mingw32-g++ -shared -o GetEvenOdd.dll injector.o -Wl,--out-implib,injector.a

Это успешно создает библиотеку DLL.Однако, когда DLL загружается моим «приложением-жертвой» (работающим в Windows), хотя функция «ExecuteCmd» выполняется, экспортированные функции (из строки «Комментарий к прагме») недоступны.А именно, программа, которая загружает эту DLL, пытается найти экспортированные функции и не может (т.е. выполняется следующая , если ветвь приложения импорта DLL).

FNPTR fn = (FNPTR)GetProcAddress(hInst, "CheckEvenOdd");
if (!fn)
{
    std::cout << "\nCould not locate the function CheckEvenOdd";
    std::cout << "\n\nPress Enter to Continue...";
    getch();
    return EXIT_FAILURE;
} 

Это говорит о том, что строка "Прагма комментарий" не работает должным образом, когда я генерирую DLL в Linux.

Из некоторого прочтения я понимаю, что эти "команды прагмы" зависят от компилятора.Есть ли какие-либо флаги, которые я могу присвоить «i686-w64-mingw32-g ++» (или некоторые изменения кода, которые я могу сделать), чтобы экспортированные функции были доступны при компиляции DLL в Linux?

1 Ответ

0 голосов
/ 04 октября 2018

Прагмы специфичны для каждого компилятора, ваши прагмы будут работать в Visual C ++, но не в MingW.Вместо этого вы можете использовать файл .def, который поддерживается Visual C ++ и MinGW.

Вот как может выглядеть injector.def в вашем случае:

EXPORTS
    CheckEvenOdd = GetEvenOdd.dll.original.CheckEvenOdd
    PrintAMessage = GetEvenOdd.dll.original.PrintAMessage

Команда компиляции:

$ i686-w64-mingw32-g++ -o GetEvenOdd.dll --shared injector.cpp injector.def
...