Информация Гайд Вызываем удаленно игровую функцию и WinAPI

Тема в разделе "C/C++", создана пользователем CleanLegend, 15 апр 2019 в 23:21.

Метки:
  1. CleanLegend

    Всефорумный модератор

    Регистрация:
    28 мар 2013
    Сообщения:
    304
    Симпатии:
    492
    Привет, сегодня мы будем вызывать игровую функцию из exe.
    Пример вызова в dll:
    
    #define FUNC_CMessages__AddMessageJumpQ 0x69F1E0
    void AddMessageJumpQ(char *text, unsigned int time, unsigned short flag, bool bPreviousBrief)
    {
        ((void(__cdecl *)(char *, unsigned int, unsigned short, bool))FUNC_CMessages__AddMessageJumpQ)(text, time, flag, bPreviousBrief);
    }
    
    AddMessageJumpQ("hello", 500, NULL,false); // вызываем
    
    Для вызова из exe мы будем использовать:
    -OpenProcess
    -VirtualAllocEx
    -WriteProcessMemory
    -CreateRemoteThread

    Создаем структуру для передачи аргументов в удаленный поток(CreateRemoteThread):
    struct Struct
    {
        char text[256];
        unsigned int time;
        unsigned short flag;
        bool bPreviousBrief;
        DWORD pAdr;
    }FuncArgs;
    Создаем прототип:
    typedef void(__cdecl *_SendMSG)(char*, unsigned int, unsigned short, bool);
    Создаем нашу функцию, которую будем вызывать. Под ней создаем еще одну, для получения размера
    DWORD __stdcall RemoteThread(Struct *sArg)
    {
        _SendMSG msg = (_SendMSG)sArg->pAdr; // передаем адрес
        msg(sArg->text, sArg->time, sArg->flag, sArg->bPreviousBrief); // вызываем
        return 0;
    }
    void __stdcall RemoteThread_end() {}
    Заполняем структуру:
    
    strcpy(FuncArgs.text, "Hello world!");
    FuncArgs.time = 500;
    FuncArgs.flag = NULL;
    FuncArgs.bPreviousBrief = false;
    FuncArgs.pAdr = 0x69F1E0;
    
    Функция для получения id процесса:
    DWORD GetProcId(const char* procname)
    {
        PROCESSENTRY32 pe;
        HANDLE hSnap;
    
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
        if (Process32First(hSnap, &pe)) {
            do {
                if (strcmp(pe.szExeFile, procname) == 0)
                    break;
            } while (Process32Next(hSnap, &pe));
        }
        return pe.th32ProcessID;
    }
    // получаем хэндл процесса
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcId("gta_sa.exe"));
        // Выделяем память под наш поток в gta_sa
        LPVOID pRemoteThread = VirtualAllocEx(hProcess, NULL, (DWORD_PTR)RemoteThread_end - (DWORD_PTR)RemoteThread, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        // Записываем его
        WriteProcessMemory(hProcess, pRemoteThread, (LPVOID)RemoteThread, ((DWORD_PTR)RemoteThread_end - (DWORD_PTR)RemoteThread), 0);
        // Выделяем память для нашего объекта в gta_sa
        Struct *myArg = (Struct*)VirtualAllocEx(hProcess, NULL, sizeof(Struct), MEM_COMMIT, PAGE_READWRITE);
        // Записываем его
        WriteProcessMemory(hProcess, myArg, &FuncArgs, sizeof(Struct), NULL);
        // Запускаем наш поток pRemoteThread с аргументами myArg
        HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, myArg, 0, 0);
        // Закрываем дескриптор потока
        CloseHandle(hThread);
        // Освобождаем выделенную память
        VirtualFreeEx(hProcess, myArg, sizeof(Struct), MEM_RELEASE);
        // Закрываем дескриптор процесса
        CloseHandle(hProcess);
    Получаем:
    [​IMG]

    Пример с WinAPI(Beep):

    Создаем структуру и прототип:
    typedef BOOL(__stdcall *__Beep)(DWORD, DWORD);
    struct sBeep
    {
        DWORD Freq;
        DWORD Duration;
        DWORD pAdr;
    
    } myBeep;
    Заполняем структуру:
    
    myBeep.Freq = 500;
    myBeep.Duration = 50;
    HMODULE kernel = LoadLibrary("Kernel32.dll"); // Получаем адрес kernel32
    myBeep.pAdr = (DWORD)GetProcAddress(kernel,"Beep"); // получаем адрес функции Beep
    FreeLibrary(kernel);
    
    DWORD __stdcall RemoteThread(sBeep *sArg)
    {
        __Beep msg = (__Beep)sArg->pAdr;
        msg(sArg->Freq, sArg->Duration);
        return 0;
    }
    void __stdcall RemoteThread_end() {}
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcId("gta_sa.exe"));
        // Выделяем память под наш поток в gta_sa
        LPVOID pRemoteThread = VirtualAllocEx(hProcess, NULL, (DWORD_PTR)RemoteThread_end - (DWORD_PTR)RemoteThread, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        // Записываем его
        WriteProcessMemory(hProcess, pRemoteThread, (LPVOID)RemoteThread, ((DWORD_PTR)RemoteThread_end - (DWORD_PTR)RemoteThread), 0);
        // Выделяем память для нашего объекта в gta_sa
        sBeep *myArg = (sBeep*)VirtualAllocEx(hProcess, NULL, sizeof(sBeep), MEM_COMMIT, PAGE_READWRITE);
        // Записываем его
        WriteProcessMemory(hProcess, myArg, &myBeep, sizeof(sBeep), NULL);
        // Запускаем наш поток pRemoteThread с аргументами myArg
        HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, myArg, 0, 0);
        // Закрываем дескриптор потока
        CloseHandle(hThread);
        // Освобождаем выделенную память
        VirtualFreeEx(hProcess, myArg, sizeof(sBeep), MEM_RELEASE);
        // Закрываем дескриптор процесса
        CloseHandle(hProcess);
     
    #1 CleanLegend, 15 апр 2019 в 23:21
    Последнее редактирование: 16 апр 2019 в 11:36
    AppleThe, iAmerican, Rinat_Namazov и 11 другим нравится это.
  2. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26 окт 2013
    Сообщения:
    3.198
    Симпатии:
    3.190
    а самое интересное не написал. Переключение процессов планировщиком происходит в момент вызова CreateRemoteThread или по истечению кванта? Т.е. поток выполняется сразу или отложено, при переключение процесса?
     
  3. CleanLegend

    Всефорумный модератор

    Регистрация:
    28 мар 2013
    Сообщения:
    304
    Симпатии:
    492
    Сразу
     
    SR_team нравится это.
  4. CleanLegend

    Всефорумный модератор

    Регистрация:
    28 мар 2013
    Сообщения:
    304
    Симпатии:
    492
    Обновил. Изменил реализацию, добавил пример с WinAPI
     
  5. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26 окт 2013
    Сообщения:
    3.198
    Симпатии:
    3.190
    вот это уже выглядит круто, но компилятор может расположить функции в ином порядке
     
    CleanLegend нравится это.
  6. iAmerican

    Друг

    Регистрация:
    17 фев 2014
    Сообщения:
    566
    Симпатии:
    222
    клёвый гайд , взял себе
     
    SiTrak нравится это.