Исходник Patch Instruction [external 32bit]

Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2018
Сообщения
541
Реакции[?]
132
Поинты[?]
4K
Всем qq, делал для себя функцию, подобие скрипта в Cheat engine (Хуком это тяжело назвать).
Сам искал к сожалению не нашёл, выкладываю для вас, может кому нибудь пригодится.
C++:
LPVOID PatchInstruction(DWORD dst, std::vector<BYTE> src, std::vector<BYTE> &orig, size_t size, HANDLE hProcess)
{
    if (size < 5) // Инструкция должна быть >= 5, т.к. прыжок использует 5 байтов
        return NULL;

    LPVOID AllocMem = VirtualAllocEx(hProcess, NULL, src.size() + 5, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // + 5 размера для возврата
    if (AllocMem == NULL)
        return NULL;

 
    if (orig.empty()) { //Проверяем пустой ли массив
        orig.resize(size, 0); // иниц массива
        //ReadEx - это ReadProcessMemory с доступом
        ReadEx((BYTE*)dst, orig.data(), orig.size(), hProcess); // Запись оригинальных байтов
    }

    size_t size_jmp = 5;
    std::vector<BYTE> buf_jump(size, 0);
    std::vector<BYTE> buf_return(size_jmp, 0);

    memset(buf_jump.data(), 0x90, size); //Заливаем массив нопами

    buf_jump[0] = 0xE9; //Ставим команду jmp
    *(DWORD*)&buf_jump[1] = ((DWORD)AllocMem - dst) - size_jmp; //Ставим адрес для прыжка на нашу функцию

    buf_return[0] = 0xE9; //Ставим команду jmp
    *(DWORD*)&buf_return[1] = (dst + size) - ((DWORD)AllocMem + src.size() + size_jmp); //Ставим адрес для прыжка возврата

    //PatchEx - это WriteProcessMemory, только с разрешённым доступом
    PatchEx((BYTE*)AllocMem, src.data(), src.size(), hProcess);
    PatchEx((BYTE*)AllocMem + src.size(), buf_return.data(), buf_return.size(), hProcess);
    PatchEx((BYTE*)dst, buf_jump.data(), buf_jump.size(), hProcess);

    buf_jump.clear(); // Очищаем массив
    buf_return.clear(); // Очищаем массив

    return AllocMem; //Возращаем созданную память, чтобы потом можно было очистить
}
C++:
    static std::vector<BYTE> origCode;
    static LPVOID AllocMem = NULL;

    if (!bChange) {
        std::vector<BYTE> shellcode = {
            0xC7, 0x86, 0x8B, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //mov [esi+0000098B],00000001
            0xC7, 0x86, 0x8F, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00  //mov [esi+0000098F],00000001
        };
        AllocMem = mem::PatchInstruction(g_addr.AZMP + 0xb282e, shellcode, origCode, 14 /*Размер инструкциий для изменения*/, Process.Handle);
    }
    else {
        mem::PatchEx((BYTE*)g_addr.AZMP + 0xb282e, origCode.data(), origCode.size(), Process.Handle); //Перезаписываем байты на оригинальные
        VirtualFreeEx(Process.Handle, AllocMem, NULL, MEM_RELEASE); //Очищаем выделенную память
        origCode.clear(); //Очищаем массив
    }
 
Последнее редактирование:
Сверху Снизу