Гость tent1s Опубликовано 22 мая, 2020 Поделиться Опубликовано 22 мая, 2020 Здравствуйте! Пишу аналог CE (не с полным его функционалом кнш)В QT creater на c++ Столкнулся с такой проблемой: В старых играх поиск адресов по значению проходит отлично(в некоторых новых тоже все как по маслу, например, в kenshi) , запись и считывание по адресу тоже.Но в новых находит очень мало адресов, либо ничего не находит, а так же не читает и не записывает по адресу. А , например, в cossacks 3 находит нужный адрес, но не читает его и не записывает. Не понимаю в чем проблема...Возможно ReadProcessMemory и WriteProcessMemory просто блочатся, если так, могли бы подсказать, что делать? Спойлер void MainWindow::setTableAdr(int row, int column) { if (column==0) { ui->tableWidget_2->setItem(row,column, new QTableWidgetItem(AA));//изменение самого адреса в таблице(если пользователь ввел именно адрес) } if (column==1) { DWORD pid= getPID(); QTableWidgetItem *item2 = ui->tableWidget_2->item(row,0);//берет из таблицы адрес int value = item2->text().toInt(nullptr,16);//из стринга в инт int newValue = AA.toInt(); //значение, на которое пользователь хочет заменить DWORD protection = PAGE_EXECUTE_READWRITE; VirtualProtect( (LPVOID)value, sizeof(newValue), PAGE_EXECUTE_READWRITE, &protection ); HANDLE pHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pid); WriteProcessMemory(pHandle, (LPVOID)value, &newValue, sizeof(newValue), 0); VirtualProtect( (LPVOID)value, sizeof(newValue), protection, &protection ); } } Спойлер template <typename T> std::vector<uintptr_t> scanner(T valor, HANDLE phandle, DWORD pid, int x, TypeV TheValue, int tp_s) { std::vector<uintptr_t> Addres; Addres.clear(); HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); for (auto&catchorra : mapp) { auto bf = reinterpret_cast<uint8_t*>(LocalAlloc(NULL, catchorra.RegionSize)); auto ret = ReadProcessMemory(phandle, catchorra.BaseAddress, bf, catchorra.RegionSize, NULL); if (!ret) { continue; } for (int i = 0; i < catchorra.RegionSize; ++i) { auto allocadPoint = uintptr_t(&bf[i]); auto vVal = *reinterpret_cast<T*>(allocadPoint); if (tp_s == 3){ if (vVal == valor || vVal <= (valor + 1) && vVal >= (valor - 1)) { Addres.push_back((uintptr_t)catchorra.BaseAddress + i); i += TheValue; } } else { if (vVal == valor) { Addres.push_back((uintptr_t)catchorra.BaseAddress + i); i += TheValue; } } } LocalFree(bf); } CloseHandle(hModuleSnap); return Addres; } Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 После RPM/WPM вызовов делай вызов GetLastError, чтобы получить код ошибки. И по коду ошибки уже можно будет более определенное что-то сказать. Ссылка на комментарий Поделиться на другие сайты Поделиться
Hack Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 Новые игры это 64bit? 1. Скомпилированный exe, должен быть 64bit. 2. Все переменные где хранится адрес, должны иметь размер 8 байт, а не 4. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость tent1s Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 8 часов назад, Xipho сказал: После RPM/WPM вызовов делай вызов GetLastError, чтобы получить код ошибки. И по коду ошибки уже можно будет более определенное что-то сказать. При чтении ошибка 299 Only part of a RPM or WPM request was comleted При записи ошибка 998 Invalid access to memory location Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость tent1s Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 (изменено) 8 часов назад, Hack сказал: Новые игры это 64bit? 1. Скомпилированный exe, должен быть 64bit. 2. Все переменные где хранится адрес, должны иметь размер 8 байт, а не 4. Благодарю, возможно в этом и проблема, при компиляции в 64бит exe выдает ошибки . Хотя kenshi вроде как онли 64x ,там все работает отлично А так же не понимаю , почему в козаках 3 все нормально ищется , а так же читает большинство адресов , кроме тех, которые именно отвечают за количество ресурсов Изменено 23 мая, 2020 пользователем tent1s Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 41 минуту назад, tent1s сказал: При чтении ошибка 299 Покажи кусок кода, в котором читаешь, и инициализацию связанных переменных (которые используются в вызове RPM) 41 минуту назад, tent1s сказал: При записи ошибка 998 Invalid access to memory location Перед тем, как записать, на целевой регион памяти установи права на запись. Ссылка на комментарий Поделиться на другие сайты Поделиться
Hack Опубликовано 23 мая, 2020 Поделиться Опубликовано 23 мая, 2020 40 минут назад, tent1s сказал: Благодарю, возможно в этом и проблема, при компиляции в 64бит exe выдает ошибки . Хотя kenshi вроде как онли 64x ,там все работает отлично А так же не понимаю , почему в козаках 3 все нормально ищется , а так же читает большинство адресов , кроме тех, которые именно отвечают за количество ресурсов Смотря какой адрес, если не больше 7FFFFFFF то будет всё отлично. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость tent1s Опубликовано 28 мая, 2020 Поделиться Опубликовано 28 мая, 2020 В 23.05.2020 в 18:52, Xipho сказал: Покажи кусок кода, в котором читаешь, и инициализацию связанных переменных (которые используются в вызове RPM) Перед тем, как записать, на целевой регион памяти установи права на запись. Благодаря подсказке пользователя Hack(большое ему спасибо), я починил сканер памяти.Теперь находит все отлично в 64 битных играх Но проблема с казаками 3 осталась, возможно она может быть и не только в казаках.Не читает и не записывает именно по адресу, который содержит информацию о игровых ресурсах Фрагмент кода, где я записываю по адресу, в первом сообщении, открываю процесс с правами на чтение и снимаю защиту через VirtualProtect Ниже метод, который в отдельном потоке обновляет значение по адресу в таблице std::vector<uintptr_t> adr(ui->tableWidget_2->rowCount());// инцилизация масссива адресов из тааблицы, у которых нужно обнавлять значение и отправка сигнала с инфой в класс отдельного потока for (int i=0;i<ui->tableWidget_2->rowCount();i++ ) { QTableWidgetItem *item = ui->tableWidget_2->item(i,0); adr[i] = item->text().toInt(nullptr,16); } connect(this, SIGNAL(sendTableInfo(int,DWORD, std::vector<uintptr_t>)), thread, SLOT(receiveTableInfo(int,DWORD, std::vector<uintptr_t>))); void Thread::run() { HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid); int i=1; while(true) { for (int j=0;j<TableNumber;j++) { ReadProcessMemory(phandle, (LPVOID)adr[j], &i, sizeof(i), 0); if(ReadProcessMemory(phandle, (LPVOID)adr[j], &i, sizeof(i), 0)==0){i=0;} qDebug() << "infa = " << i; emit send(i,j); } Sleep(1000); } } Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 29 мая, 2020 Поделиться Опубликовано 29 мая, 2020 15 часов назад, tent1s сказал: ReadProcessMemory(phandle, (LPVOID)adr[j], &i, sizeof(i), 0); if(ReadProcessMemory(phandle, (LPVOID)adr[j], &i, sizeof(i), 0)==0){i=0;} Это зачем такой бред придумал? Вот так надо делать, а не два раза считывать память. HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid); int i=1; int bytesRead = 0; while(true) { for (int j=0;j<TableNumber;j++) { ReadProcessMemory(phandle, (LPVOID)adr[j], &i, sizeof(i), &bytesRead); if(!bytesRead) int err = GetLastError() // и дальше вывод инфы пользователю об ошибке qDebug() << "infa = " << i; emit send(i,j); } Sleep(1000); } Ссылка на комментарий Поделиться на другие сайты Поделиться
Hack Опубликовано 29 мая, 2020 Поделиться Опубликовано 29 мая, 2020 item->text().toLongLong(nullptr, 16); Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения