Наконец-то дошли руки до третий части.
Речь пойдет о создании структур программно. Пример, что будет в конце записи
Сразу к делу. Нужен поинтер и процесс.
Запустим туториал из Cheat Engine из меню Health->Cheat Engine Tutorial.
Прохождение туториала подробно описано здесь
Подключаемся к процессу идем на 8-мой шаг. В руководстве есть поинтер
[[[["Tutorial-i386.exe"+XXXXXX]+C]+14]+0]+18
Вместо XXXXXX может быть любое смещение. Поэтому надо бы поискать
Нашил адрес.
Поставили бряк.
Нашли esi
Поставили бряк
Вышли сюда
Поинтер получили, дальше пойдет Lua.
Открываем Lua консоль и проверяем поинтер
Выведем адрес и его значение
Окей. Поинтер верный.
Другой вариант читать значение поинтера примерно такой
local address = getAddress("game.exe")
address = readPointer(address + 0x123)
address = readPointer(address + 0x456)
local value = readFloat(address + 0x789)
Есть и такие варианты
value = readInteger("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]")
value = readFloat("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]")
value = readDouble("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]")
Теперь самое интересное — создание структур с помощью Lua
Построим структуру [[[[005FD660]+C]+14]+0]+18. На +18 будет наш адрес.
Сначала построим один уровень —"005FD660"
Если выполнить скрипт выше, то мы построим структуру одного уровня.
Построим теперь структуру двух уровней "[005FD660]+C". Второй уровень нужно развернуть
Для этого после создания структуры создам дочернюю
myStructure2 = createStructure('MyStructure2')
myStructure2.autoGuess('[005FD660]', 0, 50)
-- И поместим её по индексу
local offset = 0
myStructure.getElementByOffset(offset).setChildStruct(myStructure2)
-- Чтобы развернуть список поитеров. К сожалению разворачивается только два уровня
structureFrm.Menu.Items[1][6].doClick()
Итого получается такой скрипт до второго уровня
Создадим и развернем весь указатель [[[[005FD660]+C]+14]+0]+18
Не будем делать через цикл, чтобы не усложнять.
Полный скрипт
Результат
Ну и на закуску.
Допустим мы знаем что по адресу X будет всегда тип float (как X,Y,Z координаты). Но расструктуризация будет показывать другой тип, дизассемблер будет показывать другой тип — 4 байта. Что делать?
И сразу еще допустим double тип всегда хотим как float тип (в виде комментов в дизассемблере или в расструктуризации)
Воспользоваться следующей функцией
-- Может менять тип адреса x в окне дизассемблере в комментариях, когда в инструкции существует адрес
-- Может менять тип адреса в окне расструктуризации
-- Изменив тип, будет ображаться значение другого типа
onAutoGuess(function) :
Registers an function to be called whenever autoguess is used to predict a variable type
function override (address, ceguess): Return the variable type you want it to be. If no change, just return ceguess
Ну и вот два примера
upd: спрятал код под спойлеры