Многоуровневый указатель памяти процесса чтения (DLL-инъекция)

Я успешно ввел .dll в .exe и мне нужно получить доступ к значению через многоуровневые указатели.

Это рабочий пример, который получает правильное значение:

#include <Windows.h>
#include <iostream>
#include <vector>
#include <TlHelp32.h>
#include <tchar.h>
using namespace std;

DWORD dwGetModuleBaseAddress(TCHAR *lpszModuleName, DWORD pID)
{
DWORD dwBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
MODULEENTRY32 moduleEntry32 = { 0 };
moduleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &moduleEntry32))
{
do {
if (_tcscmp(moduleEntry32.szModule, lpszModuleName) == 0)
{
dwBaseAddress = (DWORD)moduleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &moduleEntry32));
}
CloseHandle(hSnapshot);
return dwBaseAddress;
}

int main()
{
DWORD pID;
DWORD off1, off2, off3, off4, off5;
DWORD baseAddress;
DWORD xAddress;
int newX;
int currentX;
char moduleName[] = "TibiaInjected2.exe";
HWND hGameWindow;
HANDLE pHandle;

// Getting handles
hGameWindow = FindWindowA(NULL, "Tibia - 127.0.0.1:7171");
GetWindowThreadProcessId(hGameWindow, &pID);
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);

// Getting base address
DWORD clientBase = dwGetModuleBaseAddress(_T(moduleName), pID);

ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x0031D0CC), &baseAddress, sizeof(baseAddress), NULL);
cout << "Base address: " << hex << baseAddress << endl;

ReadProcessMemory(pHandle, (LPCVOID)(baseAddress + 0x4), &off1, sizeof(off1), NULL);
cout << "Offset 1: " << hex << off1 << endl;

ReadProcessMemory(pHandle, (LPCVOID)(off1 + 0x4), &off2, sizeof(off2), NULL);
cout << "Offset 2: " << hex << off2 << endl;

ReadProcessMemory(pHandle, (LPCVOID)(off2 + 0xA0), &off3, sizeof(off3), NULL);
cout << "Offset 3: " << hex << off3 << endl;

ReadProcessMemory(pHandle, (LPCVOID)(off3 + 0x100), &off4, sizeof(off4), NULL);
cout << "Offset 4: " << hex << off4 << endl;

ReadProcessMemory(pHandle, (LPCVOID)(off4 + 0x14), &off5, sizeof(off5), NULL);
cout << "Offset 5: " << hex << off5 << endl;

cin.get();
}

Я предпочел бы использовать мою статически внедренную DLL, и из того, что я слышал, я могу заменить весь dwGetModuleBaseAddress на GetModuleHandle (NULL), поскольку он находится внутри внедренной DLL. Мне также не нужно открывать какой-либо процесс. Но если я не сделаю все это, чем заменить ReadProcessMemory?

ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x0031D0CC), &baseAddress, sizeof(baseAddress), NULL);
ReadProcessMemory(pHandle, (LPCVOID)(baseAddress + 0x4), &off1, sizeof(off1), NULL);
ReadProcessMemory(pHandle, (LPCVOID)(off1 + 0x4), &off2, sizeof(off2), NULL);
ReadProcessMemory(pHandle, (LPCVOID)(off2 + 0xA0), &off3, sizeof(off3), NULL);
ReadProcessMemory(pHandle, (LPCVOID)(off3 + 0x100), &off4, sizeof(off4), NULL);
ReadProcessMemory(pHandle, (LPCVOID)(off4 + 0x14), &off5, sizeof(off5), NULL);

Мне удалось получить доступ к значению со статических адресов, выполнив:

int* exampleValue = *(int*)0x12345678;

Но не могу понять, как сделать то же самое с указателями и смещением.

0

Решение

Да, вы можете использовать GetModuleHandle (NULL); чтобы получить дескриптор основного модуля .exe или заменить NULL на строку, соответствующую имени DLL.

Вы можете использовать эту функцию, которая перебирает смещения, разыменовывает и добавляет смещения на каждом уровне:

uintptr_t FindDMAAddy(uintptr_t ptr, std::vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size() ; ++i)
{
addr = *(uintptr_t*)addr;
addr += offsets[i];
}
return addr;
}

uintptr_t ammoAddr = FindDMAAddy(dynamicPtrBaseAddr, { 0x374, 0x14, 0x0 });

//or

int * ammoAddr = (int*)FindDMAAddy(dynamicPtrBaseAddr, { 0x374, 0x14, 0x0 });

Вы также можете сделать некоторые сумасшедшие вещи, такие как:

int * ammo = (int*)((*(uintptr_t*)((*(uintptr_t*)(dynamicPtrBaseAddr)) +0x374)) + 0x14);

Но это более запутанно и раздражает, чем стоит.

1

Другие решения

Это сработало для меня (можно поставить в цикле, как и другой ответ):

DWORD base = *(DWORD*)(clientBase + 0x0031D0CC);
DWORD offsets[] = { 0x4, 0x4, 0xA0, 0x100, 0x14 };

DWORD off1 = *(DWORD*)(base + offsets[0]);
DWORD off2 = *(DWORD*)(off1 + offsets[1]);
DWORD off3 = *(DWORD*)(off2 + offsets[2]);
DWORD off4 = *(DWORD*)(off3 + offsets[3]);
DWORD off5 = *(DWORD*)(off4 + offsets[4]);
cout << "Value: " << off5 << endl;
0

По вопросам рекламы [email protected]