Я пытаюсь создать загрузчик модов для игры 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!