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

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

смотрел много видео, но не нашел именно по моей проблеме. самый нижний указатель содержит строку, и я не совсем понимаю, как это написать в коде.
c1r7-Dfy-YQw-U.jpg

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

Интересно как на С++ проверяется валидность значения адреса.

HMODULE gameExeModule = GetModuleHandleW(L"ThisGame.exe");
gameExeModule += 0x10E58C; 
gameExeModule = *gameExeModule; //А если по *gameExeModule у нас NILL? Помню даже на форуме видел темы про это, только на СЕ.
//Интересно такое допустимо на C++?
if (*(gameExeModule))

//Этот вопрос конечно же разрешается несколькими тестами. Но пока не до них.

 

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

5 часов назад, Oonatesara сказал:

почему то мне постоянно возвращает 0, но я хотя бы понял, в какую сторону мне идти. спасибо

Покажи свой код. Может что-то связано с защитой памяти. VirtualProtectEx.

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

9 часов назад, Antonshka сказал:
*gameExeModule у нас NILL?

😱
0xc0000005 или мусор какой-нить, очевидно. Если я правильно тебя понял.

 

9 часов назад, Antonshka сказал:
if (*(gameExeModule))

это разыменует указатель и проверит значение на 0.
 

 

9 часов назад, Antonshka сказал:

Интересно как на С++ проверяется валидность значения адреса

никак🙂

7 часов назад, Oonatesara сказал:

почему то мне постоянно возвращает 0, но я хотя бы понял, в какую сторону мне идти. спасибо

дебажить пробовал?🙂

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

1 час назад, youneuoy сказал:

😱
0xc0000005 или мусор какой-нить, очевидно. Если я правильно тебя понял.

Не сам базовый адрес модуля, а его адрес + смещение.

Спойлер

spacer.png

 

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

11 часов назад, Antonshka сказал:

Интересно как на С++ проверяется валидность значения адреса.

Кажется вот рабочий способ. Не знаю насколько это правильно, но работает.

Спойлер
#include <windows.h>
#include <iostream>


int main() {
    DWORD_PTR* processAdress = reinterpret_cast<DWORD_PTR*>(GetModuleHandleW(NULL));
    processAdress += 0x10000;
    BYTE byteData = 0;
    BOOL accessResult = ReadProcessMemory(GetCurrentProcess(), processAdress, &byteData, sizeof(BYTE), NULL);
    
    if (accessResult) {
        int d = *processAdress;
    }
    return 0;
}

 

Каждый раз перед проверкой доступа вызывать ReadProcessMemory.

Спойлер

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.

 

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

2 часа назад, Antonshka сказал:

Кажется вот рабочий способ

вот только по адресу все равно может мусор оказаться.

 

3 часа назад, Antonshka сказал:

Кажется вот рабочий способ

ага, мусор будет или ошибка чтения. Как в cheat engine когда структуру смотришь - оно указателями всё подряд считает и даже развернуть их можно. 

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

14 часов назад, Antonshka сказал:

Интересно как на С++ проверяется валидность значения адреса.

 

Через WinAPI проверять доступные регионы памяти

Спойлер

image.png

 

Подробно в справочнике по win api. Или Рихтер. "Глава 13. Архитектура памяти в Windows"

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

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

Через WinAPI проверять доступные регионы памяти

А ведь логично. Должна же API предоставлять какой-то механизм исследования участка памяти.

Рихтера читал недавно, но видимо не запечатлелось. Из MSDN собрал такое

Спойлер
#include <windows.h>
#include <iostream>


BOOL isAddressAccesable(LPVOID address) {
    BOOL isAddressAccesable = FALSE;
    MEMORY_BASIC_INFORMATION memoryInfo{ 0 };
    SIZE_T result = VirtualQueryEx(GetCurrentProcess(), address, &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION));
    if (result && memoryInfo.State == MEM_COMMIT) {
        isAddressAccesable = TRUE;
    }
    return isAddressAccesable;
}

int main() {
    DWORD_PTR* processAddress = reinterpret_cast<DWORD_PTR*>(GetModuleHandleW(NULL));
    processAddress += 0x10000;

    if (isAddressAccesable(processAddress)) {
        processAddress = reinterpret_cast<DWORD_PTR*>(*processAddress);
    }
    return 0;
}

 

 

9 часов назад, youneuoy сказал:

ага, мусор будет или ошибка чтения. Как в cheat engine когда структуру смотришь - оно указателями всё подряд считает и даже развернуть их можно. 

Да, есть такой момент.

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

1)Скопируй эту строку ["XR_3DA.exe" + 0010E58C]

2)Открой Memory View, нажми ПКМ выбери Go to address, вставь эту стороку.

3)В меню перейди View, сними галочку Show module address, адреса будут показыватся без модулей.

На этом все. Скорее всего адресс 0050E588C.

 

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

Всё очень просто, надо написать блок __try и __except и всё, можешь пытаться разыменовывать что угодно, а исключение интерпретировать как неправильный указатель с мусором вместо адреса.

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

7 часов назад, imaginary сказал:

Всё очень просто, надо написать блок __try и __except и всё, можешь пытаться разыменовывать что угодно, а исключение интерпретировать как неправильный указатель с мусором вместо адреса.

У меня такой способ не работает.

Спойлер
#include <windows.h>
#include <iostream>


int main() {
    DWORD_PTR* processAddress = reinterpret_cast<DWORD_PTR*>(GetModuleHandleW(NULL));
    processAddress += 0x10000;

    __try {
        if (processAddress  && *processAddress) { //Завершение работы прилжения
            std::wcout << L"Good";
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER){
        std::wcout << L"Bad";
    }

    //-----------------------------------------------------------------

    INT v1 = 1;
    INT v2 = 0;
    __try {
        if (v1 / v2) {
            std::wcout << L"Good";
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER) { // Выводится "Bad"
        std::wcout << L"Bad";
    }

    return 0;
}

 

 

Когда есть предусмотренный способ проверки через VirtualQuery, зачем использовать try/except?

Я кстати в библиотеке WGW нигде не использую обработку ошибок. Если ее использовать, то использовать по максимуму. А если так, то код превратится не пойми во что.

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

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

Всё очень просто, надо написать блок __try и __except и всё, можешь пытаться разыменовывать что угодно, а исключение интерпретировать как неправильный указатель с мусором вместо адреса.

Если разыменуемая память доступна, то ошибки не возникнет, а вот мусор вернется, так что тут не вариант.

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

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

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

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