Почему в моей программе не может быть найдена точка входа dll? PE файл - PullRequest
0 голосов
/ 01 августа 2020

Я пытаюсь создать загрузчик модов для игры 18-летней давности, чтобы помочь мне стать лучше в C ++. Прямо сейчас я просто пытаюсь внедрить dll в тот же процесс, что и загрузчик модов. Образец dll просто выводит текст в командное окно, но этого не делает. Я думаю, что код, который у меня загружает точку входа dll, не работает, потому что все работает до тех пор, пока я не вызову функцию точки входа моего образца dll в моем ModLoader.exe, а Visual Studio просто вызовет нарушение доступа. Я просмотрел средство просмотра памяти в режиме отладки в Visual Studio, чтобы попытаться увидеть, где, по мнению моей программы ModLoader, точка входа dll находится внутри dll, но адрес просто указывает на кучу нулей. Я недавно изучил формат файла PE и попытался понять весь код, который я написал, когда следил за учебником на Youtube о том, как это сделать, так что простите меня за мою неопытность, которую я просто пытаюсь изучить. Другой код, который я не показываю, - это поиск и нахождение целевого процесса, чтение двоичного файла dll, получение заголовков из библиотеки dll, выделение места в целевом процессе для библиотеки dll и, наконец, запись всех данных заголовка раздела. в целевой процесс. Я могу предоставить любой другой код, который вы все хотели бы видеть!

Injector.h

using ModLoader_LoadLibrary = HINSTANCE(WINAPI*)(const char* filename); 
using ModLoader_GetProcAddress = UINT_PTR(WINAPI*)(HINSTANCE module, const char* procName);
using ModLoader_DllEntry = BOOL(WINAPI*)(HINSTANCE dll, DWORD reason, LPVOID reserved);

struct ModLoader_ManualMapping_Data
{
    ModLoader_LoadLibrary ML_LoadLibrary;       //Function pointer to the windows load library function
    ModLoader_GetProcAddress ML_ProcAddress;    //Function pointer to a function to be called 
    HINSTANCE ML_Module;                            //dll instance
};

Injector. cpp: функция Shellcode, которая будет работать вместе с целевым исполняемым файлом

    void __stdcall Shellcode(ModLoader_ManualMapping_Data* data)
{
    if (!data)
        return;
BYTE* pData = reinterpret_cast<BYTE*>(data);

IMAGE_OPTIONAL_HEADER& optHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(pData + reinterpret_cast<IMAGE_DOS_HEADER*>(pData)->e_lfanew)->OptionalHeader;

auto loadLibrary = data->ML_LoadLibrary;
auto procAddress = data->ML_ProcAddress;
auto dllLoad = reinterpret_cast<ModLoader_DllEntry>(pData + optHeader.AddressOfEntryPoint); //Loads entry point func from dll
BYTE* locationDelta = pData - optHeader.ImageBase; //pData = the new address | ImageBase = preferred address -> Get the difference between the two to add to every address in the relocation table
if (locationDelta) //THIS DOES NOT GET RAN
{
    //Adds the delta value to all addresses within the base relocation table 
}

//Import table
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
{
    IMAGE_IMPORT_DESCRIPTOR* imgImport = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(pData
        + optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    while (imgImport->Name) //THIS DOES NOT GET RAN B\C imgImport is all zeros.
    {
        //Loops through import table
    }
}
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) //THIS DOES NOT GET RAN
{
    //Calls the callback functions within dll
}
dllLoad(reinterpret_cast<HINSTANCE>(pData), DLL_PROCESS_ATTACH, nullptr); //PROBLEM: ACCESS VIOLATION
}

Injector. cpp: bool ManualMapping (процесс HANDLE, const char * dllFilepath) - эта функция вызывается в main. cpp. Переменная srcData - это просто двоичное содержимое dll

ModLoader_ManualMapping_Data loadData = { 0 };
loadData.ML_LoadLibrary =  LoadLibraryA;
loadData.ML_ProcAddress = reinterpret_cast<ModLoader_GetProcAddress>(GetProcAddress);

memcpy(srcData, &loadData, sizeof(loadData));
WriteProcessMemory(process, locOfDll, srcData, 0x1000, nullptr);
void* shellCodeBase = VirtualAllocEx(process, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //Allocates 0x1000 bytes in the process memory for the shellcode
WriteProcessMemory(process, shellCodeBase, Shellcode, 0x1000, nullptr); //Injects the Shellcode function into the process
HANDLE thread = nullptr;
thread = CreateRemoteThread(process, nullptr, 0, reinterpret_cast<PTHREAD_START_ROUTINE>(shellCodeBase), locOfDll, 0, nullptr); //Runs 

Наконец, образец кода dll

#include <Windows.h>

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD reason_for_call, LPVOID lpReserved)
{
    switch (reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            OutputDebugStringA("Injected!");
            break;
    }
    return TRUE;
}

EDIT После переписывания всего кода и просмотра его весь день я наконец понял это вне. Мне просто нужно было убедиться, что параметры верны, когда я вызвал dllLoad!

...