2017-01-09 12 views
0

Недавно я начал новый консольный проект C++ win32. Он в основном перезаписывает значение данного адреса в памяти.Как получить (физический) baseaddress .DLL, используемый в процессе?

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

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

приятный день.

+0

'CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, PID) -> _wcsicmp (MODULEENTRY32.szModule, L "MyName") -> MODULEENTRY32.modBaseAddr' – RbMm

ответ

1

Чтобы получить базовый адрес модуля (DLL или EXE) в памяти, вы можете перечислить загруженные модули с помощью функции Windows API ToolHelp32Snapshot. Корпорация Майкрософт предоставляет документированный исходный код для поиска модуля. В основном вам нужны две функции, одна для захвата 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"); 

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

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; 
}