Итак, я пытался погрузиться в чтение памяти в C ++ и подумал, что классным проектом будет чтение всех адресов, которые использует процесс (аналогично тому, как работает Cheat Engine).
Я начал с чтения
Ссылка 1: Чтение памяти процесса C ++
Ссылка 2: Чтение памяти 64-битного адреса процесса
Link3: http://www.cplusplus.com/forum/general/42132/
И я также посмотрел учебник на YouTube, где он объяснил, как процесс (игра) работал с адресами. Ссылка на видео YouTube: https://www.youtube.com/watch?v=wiX5LmdD5yk
В результате я сделал три разных метода:
DWORD GetProcId(const wchar_t* procName) {
DWORD pid = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnap != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if(Process32First(hSnap, &procEntry)) {
do {
if(!_wcsicmp(procEntry.szExeFile, procName)) {
pid = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return pid;
}
Этот метод предназначен для получения идентификатор процесса, который я также мог бы просто ввести вручную, найдя тот же PID в диспетчере задач (который дал мне тот же базовый адрес позже).
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) {
uintptr_t modBaseAddr = 0;
//I use 0x10 instead of TH32CS_SNAPMODULE32 since it didnt work and according to documentation
// this is the value it should have.
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | 0x10, procId);
if(hSnap != INVALID_HANDLE_VALUE) {
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if(Module32First(hSnap, &modEntry)) {
do {
if(!_wcsicmp(modEntry.szModule, modName)) {
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while(Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
Этот метод (я предполагаю) вернет базовый адрес процесса. К примеру, в моем коде я попытался найти базовый адрес процесса discord.exe. Когда не работал discord.exe, я получил 0, а когда он работал, я получил адрес (который я считаю правильным базовым адресом, исправьте меня, если я ошибаюсь).
И мой метод main
:
int main() {
DWORD procId = GetProcId(L"Discord.exe");
uintptr_t moduleBase = GetModuleBaseAddress(procId, L"Discord.exe");
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);
uintptr_t dynamicPtrBaseAddr = moduleBase;
std::cout << "Dynamic: " << dynamicPtrBaseAddr << std::endl;
int value = 0;
int arr [10000] = {};
for (int i = 0; i < 100000; i++) {
ReadProcessMemory(hProcess, (BYTE*)dynamicPtrBaseAddr, &value, sizeof(value),0);
dynamicPtrBaseAddr += 1;
arr[i] = value;
}
}
Где я пытаюсь поместить все значения всех 100000 адресов в массив.
Итак, мои вопросы:
- Правильно ли я извлек базовый адрес процесса?
- Для чтения других адресов я просто увеличиваю dynamicPtrBaseAddr на 1, Есть ли лучший способ реализовать смещение? Или это правильный путь?
- Теперь я увеличиваю базовый адрес на 100000. Могу ли я вместо этого найти последний адрес процесса?
Я компилирую с g++ main.cpp -o test -lpsapi -DUNICODE
(MinGW ).