我试着在C中编写LoadLibrary函数。 该函数获取DLL文件的路径,该文件通常在加载时弹出消息框(我尝试使用原始的LoadLibrary函数运行该DLL文件并且它可以工作)。
基本上,DLL内容被加载到缓冲区中,解析并从入口点运行。
在VirtualAllocEx
功能中,我使用PAGE_READWRITE
保护模式。然后,当运行第f(nth->OptionalHeader.ImageBase, DLL_PROCESS_ATTACH, NULL)
行时,我收到以下错误消息:Exception thrown at 0x10011032 in PE.exe: 0xC0000005: Access violation executing location 0x10011032.
(0x10011032是入口点地址)。
如果我将模式更改为PAGE_EXECUTE_READWRITE
,则错误消息为:Exception thrown at 0x00019644 in PE.exe: 0xC0000005: Access violation executing location 0x00019644.
(不知道该地址是什么)。
我认为很清楚为什么在PE的所有部门都不允许执行,但我只是出于测试目的而这样做。在最终的代码中,我需要正确编写它。
我的代码已附上。 (顺便说一句,如果你有其他与我的问题无关的建议 - 我很高兴知道)。
#include <Windows.h>
typedef HMODULE func(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
HMODULE LoadLibraryFromMem(char* dllPath)
{
DWORD read;
HANDLE handle;
handle = CreateFileA(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD size = GetFileSize(handle, NULL);
PVOID vDll = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
BOOL r = ReadFile(handle, vDll, size, &read, NULL);
CloseHandle(handle);
PIMAGE_DOS_HEADER dosh = (PIMAGE_DOS_HEADER)vDll;
PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)((PBYTE)vDll + dosh->e_lfanew);
handle = GetCurrentProcess();
PVOID vImg = VirtualAllocEx(
handle,
nth->OptionalHeader.ImageBase,
nth->OptionalHeader.SizeOfImage,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
); // HERE --> PAGE_EXECUTE_READWRITE
WriteProcessMemory(
handle,
vImg,
vDll,
nth->OptionalHeader.SizeOfHeaders,
0
);
PIMAGE_SECTION_HEADER sech = IMAGE_FIRST_SECTION(nth);
for (size_t i = 0; i < nth->FileHeader.NumberOfSections; i++)
WriteProcessMemory(
handle,
(PBYTE)vImg + sech[i].VirtualAddress,
(PBYTE)vDll + sech[i].PointerToRawData,
sech[i].SizeOfRawData,
0
);
PIMAGE_IMPORT_DESCRIPTOR impd = nth->OptionalHeader.ImageBase + nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
HANDLE proc;
while (((PIMAGE_IMPORT_DESCRIPTOR)impd)->Name)
{
LPSTR dllName = (nth->OptionalHeader.ImageBase + ((PIMAGE_IMPORT_DESCRIPTOR)impd)->Name);
HMODULE dllAdr = LoadLibraryA(dllName);
PDWORD iat = nth->OptionalHeader.ImageBase + ((PIMAGE_IMPORT_DESCRIPTOR)impd)->FirstThunk;
while (*iat)
{
LPSTR funcName = ((PIMAGE_IMPORT_BY_NAME)(nth->OptionalHeader.ImageBase + *iat))->Name;
proc = GetProcAddress(dllAdr, funcName);
if (!proc)
return NULL;
impd->FirstThunk = proc;
iat++;
}
impd++;
}
func* f = (func*)(nth->OptionalHeader.ImageBase + nth->OptionalHeader.AddressOfEntryPoint);
f(nth->OptionalHeader.ImageBase, DLL_PROCESS_ATTACH, NULL);
}
int main()
{
LoadLibraryFromMem("mydll.dll");
return 0;
}
提前致谢!