C++ 读取进程内存多级指针(DLL注入)
我已成功地将.dll注入.exe,需要通过多级指针访问值 这是一个获得正确值的工作示例:C++ 读取进程内存多级指针(DLL注入),c++,pointers,dll-injection,readprocessmemory,cheat-engine,C++,Pointers,Dll Injection,Readprocessmemory,Cheat Engine,我已成功地将.dll注入.exe,需要通过多级指针访问值 这是一个获得正确值的工作示例: #include <Windows.h> #include <iostream> #include <vector> #include <TlHelp32.h> #include <tchar.h> using namespace std; DWORD dwGetModuleBaseAddress(TCHAR *lpszModuleName, D
#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();
}
我通过以下操作直接从静态地址访问值:
int* exampleValue = *(int*)0x12345678;
但是,我们不知道如何对指针和偏移量执行相同的操作。是的,您可以使用GetModuleHandleNULL;获取main.exe模块的句柄或用与DLL名称匹配的字符串替换NULL 您可以使用此函数循环偏移、取消引用和添加每个级别的偏移: uintpttr_t FindDMAAddyuintptr_t ptr,标准::矢量偏移 { uintpttr_t addr=ptr; 对于无符号整数i=0;i
但这比它的价值更让人困惑和恼火。这对我有用,可以像另一个答案一样循环:
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;
这对我不起作用,但我找到了答案。无论如何,谢谢。@snzm在我的代码dynamicPtrBaseAddr中是指向对象的指针,而不是对象的地址。在代码中,您可以:*DWORD*clientBase+0x0031D0CC,它首先反引用指针。如果在我的代码中使用对象的地址代替dynamicPtrBaseAddr,它将无法工作,因为它不是正确的参数。如果改用指针clientBase+0x0031D0CC,它应该可以正常工作。这就是你有问题的原因吗?让我知道,这样我可以更新我的答案,使之更好。最好使用uintptr\t或类似工具,这样就不必更新x64的代码,只需更改构建即可
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;