刚开始接触注射DLL工具时,发现很多工具没有提供调用函数的输入框,查找了许多实例中没有程序的入口。实在是让我等小白迷糊了。为了弄明白 ,特别写了一个测试程序测试。
在写DLL文件时,查到微软给出了DLL的入口点:
BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved );,链接:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
而一般的实验只给出了导出函数表,其在函数的前加"__declspec(dllexport)"标识。所以测试的dll程序testdll.c如下:
#include "windows.h"
#include "stdio.h"
#include "stdlib.h"
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
printf("hModule.%p lpReserved.%p \n", hModule,lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf("Process attach. \n");
break;
case DLL_PROCESS_DETACH:
printf("Process detach. \n");
break;
case DLL_THREAD_ATTACH:
printf("Thread attach. \n");
break;
case DLL_THREAD_DETACH:
printf("Thread detach. \n");
break;
}
return (TRUE);
}
__declspec(dllexport) testdll()
{
printf("declspec testdll entry point %p\n",testdll);
}
调用程序calldll.c如下:
#include "windows.h"
#include "stdio.h"
void main()
{
HMODULE h_dll;
FARPROC dllfunc;
printf("loadlibaray dll\n");
h_dll=LoadLibrary("testdll.dll");
if(h_dll==NULL)
{
printf("loadlibrary testdll.dll fairue!\n");
return;
}
printf("calldll dllmain entry point %p\n",h_dll);
dllfunc=GetProcAddress(h_dll,"testdll");
printf("calldll dllfunc entry point %p\n",dllfunc);
dllfunc();
system("pause");
if(FreeLibrary(h_dll)==0)
{
printf("Freelibrary testdll.dll fairue!\n");
}
system("pause");
return;
}
运行calldll.exe.输出如下:
请按任意键继续. . .
hModule.10000000 lpReserved.00000000
Process attach.
declspec testdll entry point 10001084
hModule.10000000 lpReserved.00000000
Process detach.
请按任意键继续. . .
loadlibaray dll
calldll dllmain entry point 10000000
calldll dllfunc entry point 10001084
分析:
在调用LoadLibrary和FreeLibrary函数时,程序会自动进入dll文件的dllmain函数中。这就使用我迷糊了,有些dll程序没有dllmain函数怎么办呢?注释掉dllmain函数后编译,再执行calldll.exe.输出如下:
请按任意键继续. . .
declspec testdll entry point 10001000
请按任意键继续. . .
loadlibaray dll
calldll dllmain entry point 10000000
calldll dllfunc entry point 10001000
说明dll程序中没有dllmain函数时,系统使用默认的dllmain函数;而没有dllmain程序入口的dll文件,其导出函数不是入口函数。所以:dll注射工具中没有给出调用输入框的程序,只能载入dllmain自定义的dll文件,不然无法执行所需要的程序。而在给出的函数调用框的注射工具,应该是计算出了所需的程序的入口点(相对入口的偏移量),然后使用远程创建进程函数:CreatRemoteThread执行所需的程序。