-
Автор темы
- #1
Всем 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(); //Очищаем массив
}
Последнее редактирование: