Вторая часть будет в качестве небольшого дополнения к [первой]. Почему небольшой? Да потому, что для динамического выделения памяти нам нужно изменить в коде одну строчку. Нам понадобится новая WinAPI-функция - [VirtualAllocEx]:
В общем-то всё, что она делает - принимает в аргументах хэндл процесса, размер выделяемого куска памяти в байтах, ну и пару флагов, определяющих способ выделения и нужные права. Возвращает она что? Правильно! Адрес выделенного куска, куда уже можно записывать.
Так что мы просто берём и значение переменной caveAddress, хранящей адрес нашего кейва, присваиваем нужный вызов:
caveAddress = (Int32)(VirtualAllocEx(handle,IntPtr.Zero,(uint)(valueon.Length+5),AllocationType.Commit,MemoryProtection.ExecuteReadWrite));
Соответственно, выделить нам нужно память размером с наш скрипт + ещё пять байт для прыжка обратно в код игры (1 байт для jmp и 4 - для адреса). Штучка (Int32) нужна для конвертации в нужный тип данных (по-умолчанию функция возвращает IntPtr), иначе нам будет не посчитать буфер для записи.
Всё, что нам потребуется после этого (когда мы захотим отключить функцию трейнера) - это:
1. Записать старую инструкцию на место (value off -> addressFrom).
2. Очистить выделенную под кейв память при помощи [VirtualFreeEx].
Как пользоваться вторым пунктом (а заодно - что нужно для записи) - узнаём на [pinvoke.net]. На всякий случай скажу, что для очистки нам нужен флаг Decommit.
В общем-то всё, что она делает - принимает в аргументах хэндл процесса, размер выделяемого куска памяти в байтах, ну и пару флагов, определяющих способ выделения и нужные права. Возвращает она что? Правильно! Адрес выделенного куска, куда уже можно записывать.
Так что мы просто берём и значение переменной caveAddress, хранящей адрес нашего кейва, присваиваем нужный вызов:
caveAddress = (Int32)(VirtualAllocEx(handle,IntPtr.Zero,(uint)(valueon.Length+5),AllocationType.Commit,MemoryProtection.ExecuteReadWrite));
Соответственно, выделить нам нужно память размером с наш скрипт + ещё пять байт для прыжка обратно в код игры (1 байт для jmp и 4 - для адреса). Штучка (Int32) нужна для конвертации в нужный тип данных (по-умолчанию функция возвращает IntPtr), иначе нам будет не посчитать буфер для записи.
Всё, что нам потребуется после этого (когда мы захотим отключить функцию трейнера) - это:
1. Записать старую инструкцию на место (value off -> addressFrom).
2. Очистить выделенную под кейв память при помощи [VirtualFreeEx].
Как пользоваться вторым пунктом (а заодно - что нужно для записи) - узнаём на [pinvoke.net]. На всякий случай скажу, что для очистки нам нужен флаг Decommit.
Этот комментарий был удален автором.
ОтветитьУдалитьИнтересная статья, а видеоурока не будет? (для наглядности :D)
ОтветитьУдалить