Гайд Переносим структуру из CE в C++

Тема в разделе "C/C++", создана пользователем Vadim.dll, 18 май 2019 в 09:38.

  1. Vadim.dll

    Vadim.dll Интересующийся

    Регистрация:
    4 июл 2015
    Сообщения:
    179
    Симпатии:
    58
    Итак, найдя структуру в Cheat Engine, неплохо бы ее перенести в C++. Можно конечно каждое значение получить по оффсету, но как по мне, это не самое лучшее решение. Сегодня я покажу, как из внешней программы получить структуру с диалогом, которую мы искали в https://blast.hk/threads/34493/ этом уроке и запихнуть ее в структуру, для удобства в использовании.

    Значит имеем такую структуру в CE:
    upload_2019-5-18_9-22-13.png

    Суть такова, главное расположить данные в той же последовательности, что и в CE, переменные, о назначении которых мы не знаем, можно помечать как Unknown или любое другое слово.

    Я например, зная несколько значений нескольких переменных перенес данную структуру таким образом:
    
    struct Dialog {
        void* pUnkn;
        int iTextX;
        int iTextY;
        int iUnkn1[2];
        int iSizeX;
        int iSizeY;
        void* pUnkn2[3];
        int iIsActive;
        int iUnkn2;
        int iDialogID;
    };
    
    Как видим, первый у нас указатель, куда он ведет - я не знаю, поэтому пишу как pUnkn,
    вторая и третья переменные - значения смещения текста по X и Y. Что делают четвертая и пятая переменные я не знаю, поэтому называю их iUnkn1[2], [2] здесь, чтобы запихнуть две эти переменные в массив, чтобы не писать их по отдельности:
    
    int iUnkn[2]
    // Смысл одинаков
    int iUnkn1
    int iUnkn2
    
    Далее у нас идут размеры окна iSizeX, iSize Y, потом три неизвестных указателя, далее активен ли диалог, неизвестный int и наконец ID диалога.

    Протестировать данную структуру можно следующим образом:
    
    int main()
    {
        DWORD pID = GetProcId(L"gta_sa.exe"); // Получаем ID процесса Gta sa
    
        HANDLE pGta = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // Открываем процесс
        DWORD pSamp = (DWORD)get_module(pGta, L"samp.dll"); // Ищем библиотеку samp.dll в процессе
    
        DWORD structAddr; // Адрес на нашу структуру с диалогом
        ReadProcessMemory(pGta, (LPCVOID)(pSamp + 0x26E898), &structAddr, 4, 0); // Получаем адрес на нашу структуру
    
        Dialog dial; // Объявляем наш диалог
        ReadProcessMemory(pGta, (LPCVOID)structAddr, &dial, sizeof(Dialog), 0); // Считываем данные в нашу структуру
    
        cout << "Dialog ID: " << dial.iDialogID << endl;
    }
    
    По сдвигу 0x26E898 находится указатель на структуру, а не сама структура, как можно увидеть в том же CE, поэтому для начала нужно считать адрес структуры с Диалогом, а потом уже саму структуру.
    Сделано это т.к указатель на эту структуру по сдвигу 0x26E898 статичен, а вот адрес самой структуры - нет, поэтому если читать сразу из адреса структуры, который вы только что нашли, то после перезахода в игру это не будет работать. Также не обязательно указывать вообще все, что находится в структуре, как можно заметить, после DialogID там есть еще несколько переменных, но если они вас не интересуют, то их можно не записывать.

    Полный код:
    
    #include <iostream>
    #include <Windows.h>
    #include <TlHelp32.h>
    #include <tchar.h>
    #include <psapi.h>
    
    using namespace std;
    
    DWORD GetProcId(const wchar_t* procname)
    {
        PROCESSENTRY32 pe;
        HANDLE hSnap;
    
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
        if (Process32First(hSnap, &pe)) {
            do {
                if (wcscmp(pe.szExeFile, procname) == 0)
                    break;
            } while (Process32Next(hSnap, &pe));
        }
        return pe.th32ProcessID;
    }
    
    DWORD get_module(HANDLE hProcess, const wchar_t* name)
    {
        HMODULE hMods[1024];
        DWORD cbNeeded;
        unsigned int i;
    
    
        if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
        {
            for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
            {
                TCHAR szModName[MAX_PATH];
    
                if (GetModuleBaseName(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
                {
                    if (wcscmp(szModName, name) == 0) return (DWORD)hMods[i];
                }
            }
        }
    
        CloseHandle(hProcess);
    
        return 0;
    }
    
    struct Dialog {
        void* pUnkn;
        int iTextX;
        int iTextY;
        int iUnkn1[2];
        int iSizeX;
        int iSizeY;
        void* pUnkn2[3];
        int iIsActive;
        int iUnkn2;
        int iDialogID;
    };
    
    int main()
    {
        DWORD pID = GetProcId(L"gta_sa.exe"); // Получаем ID процесса Gta sa
    
        HANDLE pGta = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // Открываем процесс
        DWORD pSamp = (DWORD)get_module(pGta, L"samp.dll"); // Ищем библиотеку samp.dll в процессе
    
        DWORD structAddr; // Адрес на нашу структуру с диалогом
        ReadProcessMemory(pGta, (LPCVOID)(pSamp + 0x26E898), &structAddr, 4, 0); // Получаем адрес на нашу структуру
    
        Dialog dial; // Объявляем наш диалог
        ReadProcessMemory(pGta, (LPCVOID)structAddr, &dial, sizeof(Dialog), 0); // Считываем данные в нашу структуру
    
        cout << "Dialog ID: " << dial.iDialogID << endl;
    }
    
    Работает на SAMP 0.3.7 R3
     
    Сэнд, Cucumber, DonHomka и 5 другим нравится это.
  2. B3JlOM_}I{OTTbI

    B3JlOM_}I{OTTbI проверенный какой-то

    Регистрация:
    16 мар 2017
    Сообщения:
    1.409
    Симпатии:
    604
    seanize, social enemy, Stranger! и ещё 1-му нравится это.
  3. Vadim.dll

    Vadim.dll Интересующийся

    Регистрация:
    4 июл 2015
    Сообщения:
    179
    Симпатии:
    58
    Спасибо, отличный инструмент! Смог решить с ним свою проблему!