Как я могу получить (физический) базовый адрес .DLL, используемого в процессе?

Недавно я запустил новый консольный проект на C ++ win32.
Это в основном переписывает значение данного адреса в памяти.

Дело в том, что я хочу использовать карту указателей со смещениями, чтобы пересчитать адрес, который он должен использовать.
Вот изображение карты указателя в Cheat Engine

Как я уже сказал, мне удалось переписать значение (в данном случае 1147) вручную, если я просто наберу адрес, но я хочу, чтобы оно было автоматическим!
Надеюсь, вы понимаете мою проблему

хорошего дня.

0

Решение

Чтобы получить базовый адрес модуля (DLL или EXE) в памяти, вы можете перечислить загруженные модули, используя ToolHelp32Snapshot Функция Windows API. Microsoft предоставляет документированный исходный код для поиска модуля. В основном вам нужны 2 функции, одна для захвата ProcessId и одна для получения базового адреса.

bool GetPid(const wchar_t* targetProcess, DWORD* procID)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!wcscmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
*procID = pe.th32ProcessID;
return true;
}
} while (Process32Next(snap, &pe));
}
}
return false;
}

char* GetModuleBase(const wchar_t* ModuleName, DWORD procID)
{
MODULEENTRY32 ModuleEntry = { 0 };
HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procID);

if (!SnapShot) return NULL;

ModuleEntry.dwSize = sizeof(ModuleEntry);

if (!Module32First(SnapShot, &ModuleEntry)) return NULL;

do
{
if (!wcscmp(ModuleEntry.szModule, ModuleName))
{
CloseHandle(SnapShot);
return (char*)ModuleEntry.modBaseAddr;
}
} while (Module32Next(SnapShot, &ModuleEntry));

CloseHandle(SnapShot);
return NULL;
}

Тогда вы делаете:

DWORD ProcId;
GetPid(L"ac_client.exe", &ProcId);
char* ExeBaseAddress = GetModuleBase(L"ac_client.exe", ProcId);

Если вы внедрили этот процесс во внутренний хак, вы можете использовать GetModuleHandle потому что на момент публикации возвращаемый дескриптор является просто адресом модуля:

 DWORD BaseAddress = (DWORD)GetModuleHandle(L"ac_client.exe");

Чтобы вычислить динамический адрес, на который указывает многоуровневый указатель, вы можете использовать эту функцию, она в основном отменяет указатель на внешнюю ссылку для вас, используя ReadProcessMemory ():

uintptr_t FindDmaAddy(int PointerLevel, HANDLE hProcHandle, uintptr_t Offsets[], uintptr_t BaseAddress)
{
uintptr_t pointer = BaseAddress;
uintptr_t pTemp;

uintptr_t pointerAddr;
for(int i = 0; i < PointerLevel; i++)
{
if(i == 0)
{
ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
}
pointerAddr = pTemp + Offsets[i];

ReadProcessMemory(hProcHandle, (LPCVOID)pointerAddr, &pTemp, sizeof(pTemp), NULL);
}
return pointerAddr;
}
1

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

Других решений пока нет …