У меня задача - разобраться с указателями в плюсах и наконец взломать ведьмака CE - Cheat Engine; Для этого нужно было найти многоуровневый указатель, с чем я справился Не совсем понял на счет "witcher3.exe"+029807C0 - первая часть выражения это базовый статический адрес процесса, вторая это нечто статическое, похожее на оффсет. Так мне сказал CE, пометив это дело зеленым цветом. Здесь поправьте. uintptr_t BaseAddress = 0x7FF68E6E0000; С эти адресом мне помог CE Так вот, как мне сложить все это дело, чтобы в переменную MoneyPointer int MoneyPointer; нужный мне адрес Если снять с меня костюм, то без него я Новичек, Перепрыгнул с c# на c++, с десктопной на кул хацкера. #include <Windows.h> #include <TlHelp32.h> #include <iostream> #include <tchar.h> using namespace std; DWORD pID; DWORD offsets[] = { 0xDD4, 0x140, 0x10 , 0x1B0 , 0x40 , 0x148 , 0x68, 0x029807C0 }; uintptr_t BaseAddress = 0x7FF68E6E0000; uintptr_t find_addr(uintptr_t addrs, DWORD offests[], HANDLE handle){ uintptr_t addr = addrs; for (int i = 7; i >= 0; i--) { if (ReadProcessMemory(handle, (LPCVOID)(addr + offests[i]), &addr, sizeof(addr), NULL)) { cout << "OH ES"; } else { cout << "OH NO"; } } return addr; } int main() { uintptr_t MoneyPointer = find_addr(BaseAddress, offsets); int WriteToMemory; cin >> WriteToMemory; HWND hWindow = FindWindow(0, L"The Witcher 3"); if (hWindow == 0) { cout << "wnd not found"; } else { GetWindowThreadProcessId(hWindow, &pID); HANDLE hGameHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); if (hGameHandle == INVALID_HANDLE_VALUE || hGameHandle == NULL) { std::cout << "Failed to open process" << std::endl; return 0; } bool ProcIsWriten = WriteProcessMemory ( hGameHandle, (LPVOID)MoneyPointer, &WriteToMemory, (DWORD)sizeof(WriteToMemory), 0 ); CloseHandle(hGameHandle); cout << ProcIsWriten << "\t"; cin >> pID; } } Code #include <Windows.h> #include <TlHelp32.h> #include <iostream> #include <tchar.h> using namespace std; DWORD pID; DWORD offsets[] = { 0xDD4, 0x140, 0x10 , 0x1B0 , 0x40 , 0x148 , 0x68, 0x029807C0 }; uintptr_t BaseAddress = 0x7FF68E6E0000; uintptr_t find_addr(uintptr_t addrs, DWORD offests[], HANDLE handle){ uintptr_t addr = addrs; for (int i = 7; i >= 0; i--) { if (ReadProcessMemory(handle, (LPCVOID)(addr + offests[i]), &addr, sizeof(addr), NULL)) { cout << "OH ES"; } else { cout << "OH NO"; } } return addr; } int main() { uintptr_t MoneyPointer = find_addr(BaseAddress, offsets); int WriteToMemory; cin >> WriteToMemory; HWND hWindow = FindWindow(0, L"The Witcher 3"); if (hWindow == 0) { cout << "wnd not found"; } else { GetWindowThreadProcessId(hWindow, &pID); HANDLE hGameHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); if (hGameHandle == INVALID_HANDLE_VALUE || hGameHandle == NULL) { std::cout << "Failed to open process" << std::endl; return 0; } bool ProcIsWriten = WriteProcessMemory ( hGameHandle, (LPVOID)MoneyPointer, &WriteToMemory, (DWORD)sizeof(WriteToMemory), 0 ); CloseHandle(hGameHandle); cout << ProcIsWriten << "\t"; cin >> pID; } }
Там создал, но шанс, что тебе кто-то поможет ночью, тем более со сложным языком - крайне мал The post was merged to previous Jan 12, 2022 Попроси в услугах программирования людям с серым ником, которые на плюсах и си пишут помочь, кто-нибудь да согласится, только предупреди, что не платишь The post was merged to previous Jan 12, 2022 Или другим людям из этого раздела напиши
Первым является VA (Virtual Address), а вторым соответственно RVA (Relative Virtual Address). Отличие в том, что VA существует относительно физического адреса процесса (это зависит от ОС), а RVA считается (чаще всего, но не всегда) от начала бинарного файла приложения (т.е от VA (RVA зависит от линкера и загрузчика)) до нужной переменной (ее адреса). Для большей подробности придется читать спецификацию по VA и RVA. Ну, адрес переменной будет считаться как VA + RVA . Суммируешь, получаешь значение переменной, затем перезаписываешь значение переменной по найденному адресу. P.S: я не читмейкер, так что думаю, что тут более знающие люди подтянутся и разъяснят все получше.
Replacer, у меня получается арифметическое переполнение, делал (VA)DWORD + (RVA)DWORD + ... + (смещение)int-ное
Решение найдено. После бессонных ночей #include <Windows.h> #include <iostream> #include <vector> #include "mem.h" using namespace std; int valueToWrite; std::vector<long long> offset = {0x0, 0x1a8, 0x340, 0x50, 0xf0, 0x108, 0x140, 0xDD4 }; long long BaseAddr; int main() { memory mem; cout << "witcher money pointer value changer" << endl; cout << "Enter value: "; cin >> valueToWrite; while (!mem.Attach("witcher3.exe")) { cout << "Searching witcher3.exe ..." << endl; }cout << "Process found!" << endl; BaseAddr = mem.GetModule("NvCameraSDK64.dll").longBase +0x50A0; cout<<"Base address 0x" << hex << BaseAddr << endl; for (size_t i = 0; i < offset.size()-1; i++) { cout << "reading address 0x" << hex << BaseAddr << " + 0x" << offset[i]; BaseAddr = mem.Read<long long>(BaseAddr+offset[i]); cout << " -> 0x" << hex << BaseAddr << endl; }cout << "Money pointer is 0x" << hex << BaseAddr << " + last offset 0x" << offset[7] << endl; BaseAddr += offset[7]; valueToWrite = WriteProcessMemory(mem._process, (LPVOID)BaseAddr, &valueToWrite, sizeof(valueToWrite), NULL); cout << "Write to 0x" << hex << BaseAddr << " IS 0x"<< valueToWrite << endl; } C #include <Windows.h> #include <iostream> #include <vector> #include "mem.h" using namespace std; int valueToWrite; std::vector<long long> offset = {0x0, 0x1a8, 0x340, 0x50, 0xf0, 0x108, 0x140, 0xDD4 }; long long BaseAddr; int main() { memory mem; cout << "witcher money pointer value changer" << endl; cout << "Enter value: "; cin >> valueToWrite; while (!mem.Attach("witcher3.exe")) { cout << "Searching witcher3.exe ..." << endl; }cout << "Process found!" << endl; BaseAddr = mem.GetModule("NvCameraSDK64.dll").longBase +0x50A0; cout<<"Base address 0x" << hex << BaseAddr << endl; for (size_t i = 0; i < offset.size()-1; i++) { cout << "reading address 0x" << hex << BaseAddr << " + 0x" << offset[i]; BaseAddr = mem.Read<long long>(BaseAddr+offset[i]); cout << " -> 0x" << hex << BaseAddr << endl; }cout << "Money pointer is 0x" << hex << BaseAddr << " + last offset 0x" << offset[7] << endl; BaseAddr += offset[7]; valueToWrite = WriteProcessMemory(mem._process, (LPVOID)BaseAddr, &valueToWrite, sizeof(valueToWrite), NULL); cout << "Write to 0x" << hex << BaseAddr << " IS 0x"<< valueToWrite << endl; } Проблема была в том, что поинтеры были 8 байтные, в этом случае DWORD не подходило, его можно заменить на long long. Так же многоуровневый указатель как я показывал сверху был не верен, данные не читались корректно. Нашел через Cheat Engine модуль "NvCameraSDK64.dll" Пример работы: Было интересно