如何使用导出的函数交叉编译DLL

n00*_*00b 11 c++ linux mingw cross-compiling mingw32

我正在进行DLL劫持练习,并编写了一个DLL,在Visual Studio中编译时可以正常工作.本质上,当加载DLL时,它会执行shell命令并将合法功能(在此示例中为CheckEvenOddPrintAMessage函数)传递给最初预期的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;
}
Run Code Online (Sandbox Code Playgroud)

虽然它在Visual Studio(Windows)中编译时可以正常工作,但我想在Linux中生成DLL(用于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
Run Code Online (Sandbox Code Playgroud)

这会成功创建DLL.但是,当我的"受害者应用程序"(在Windows上运行)加载DLL时,虽然"ExecuteCmd"函数被执行,但导出的函数(来自"pragma comment"行)不可用.也就是说,加载此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;
} 
Run Code Online (Sandbox Code Playgroud)

这告诉我,当我在Linux中生成DLL时,"pragma comment"行没有按预期工作.

从一些阅读中我理解这些"pragma命令"是编译器特定的.是否有一些标志我可以给"i686-w64-mingw32-g ++"(或者我可以做一些代码更改),以便在Linux中编译DLL时导出的函数可用?

Dex*_* CD 6

Pragma特定于每个编译器,您的pragma将在Visual C++中工作,但在MingW中不起作用.相反,您可以使用Visual C++和MinGW支持的.def文件.

以下是您的情况下inject.def的样子:

EXPORTS
    CheckEvenOdd = GetEvenOdd.dll.original.CheckEvenOdd
    PrintAMessage = GetEvenOdd.dll.original.PrintAMessage
Run Code Online (Sandbox Code Playgroud)

编译命令:

$ i686-w64-mingw32-g++ -o GetEvenOdd.dll --shared injector.cpp injector.def
Run Code Online (Sandbox Code Playgroud)