Перейти к содержанию

Проблема с использование ReadProcessMemory и WriteProcessMemory в new играх


Рекомендуемые сообщения

 

Здравствуйте!

Пишу аналог 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;
}

 

 

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, Xipho сказал:

После RPM/WPM вызовов делай вызов GetLastError, чтобы получить код ошибки. И по коду ошибки уже можно будет более определенное что-то сказать.

При чтении ошибка 299

Only part of a RPM or WPM request was comleted

При записи ошибка 998

Invalid access to memory location

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, Hack сказал:

Новые игры это 64bit?

1. Скомпилированный exe, должен быть 64bit.

2. Все переменные где хранится адрес, должны иметь размер 8 байт,  а не 4.

Благодарю, возможно в этом и проблема, при компиляции в 64бит exe выдает ошибки .

Хотя kenshi вроде как онли 64x ,там все работает отлично

А так же не понимаю , почему в козаках 3 все нормально ищется , а так же читает большинство адресов , кроме тех, которые именно отвечают за количество ресурсов 

Изменено пользователем tent1s
Ссылка на комментарий
Поделиться на другие сайты

 

41 минуту назад, tent1s сказал:

При чтении ошибка 299

Покажи кусок кода, в котором читаешь, и инициализацию связанных переменных (которые используются в вызове RPM)

 

41 минуту назад, tent1s сказал:

При записи ошибка 998

Invalid access to memory location

Перед тем, как записать, на целевой регион памяти установи права на запись.

Ссылка на комментарий
Поделиться на другие сайты

40 минут назад, tent1s сказал:

Благодарю, возможно в этом и проблема, при компиляции в 64бит exe выдает ошибки .

Хотя kenshi вроде как онли 64x ,там все работает отлично

А так же не понимаю , почему в козаках 3 все нормально ищется , а так же читает большинство адресов , кроме тех, которые именно отвечают за количество ресурсов 

Смотря какой адрес, если не больше 7FFFFFFF то будет всё отлично.

Ссылка на комментарий
Поделиться на другие сайты

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

 

Ссылка на комментарий
Поделиться на другие сайты

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


 

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.