从内存

时间:2018-04-02 14:20:36

标签: c parsing portable-executable dynamic-library entry-point

我试着在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;
}

提前致谢!

0 个答案:

没有答案