Skip to content

Плагин-строй

Программирование плагинов, примеров, инфо

17 Темы 43 Сообщения
  • Structure hunter (beta)

    Прикреплена
    4
    0 Голоса
    4 Сообщения
    2k Просмотры
    MasterGHM

    Для работы с репозиторием скачиваем SourceTree (или любой другой git клиент)

    Руководство как ей пользоваться ищем на yotube или статьи.
    Что такое git аналогично.
    Как работать с git hub сервисом тоже можно найти.

  • Что в разделе

    Прикреплена
    1
    0 Голоса
    1 Сообщения
    15 Просмотры
    Нет ответов
  • CE Вывод иерархии компонентов

    1
    0 Голоса
    1 Сообщения
    25 Просмотры
    Нет ответов
  • CE вывод списка записей и вывод свойств компонентов

    2
    0 Голоса
    2 Сообщения
    32 Просмотры
    MasterGHM
    Ищем свойства userData.

    UserData в Lua это пользовательский тип. Точно не знаю, но я думаю в документации в CE Lua (celua.txt или здесь на офф. сайте) тип userData у всех классов или большинства классов. Например, проверим, что главная форма CE это userData тип

    local mainFormCE = getMainForm() print(type(mainFormCE)) > userdata (вывод из консоли)

    Выводим список свойств следующим образом через getmetatable функцию. Метатаблица — это особая таблица свойств Lua-переменной

    local mainForm = getMainForm() local listUserData = createStringlist() for k,_ in pairs(getmetatable(mainForm)) do listUserData.add(k) end local allowCustomInput = false local id, name = showSelectionList("Title", "Caption", listUserData, allowCustomInput) print ('Index: '..id..", Name: "..name) listUserData.destroy()

    Результат в виде списка свойство переменной mainForm
    1a800863-fb55-46e7-a2b0-b3daed1613af-изображение.png
    Чтобы наглядно было. Свойства эти похожи на свойства из Дельфи. Можно загуглить, они поддробно описываются.

    Берем например свойство цвет. Прочитаем оригинальное и запишем свое любое

    local mainFormCE = getMainForm() print(mainFormCE.getColor()) > 536870912 -- в hex-е это 0x20000000. Можно перевести в калькуляторе или через print(string.format("%08X", 536870912))

    Случайное свое впишем ради наглядного примера
    mainFormCE.setColor(546484)

    72d5c265-f388-4d4f-b24c-f3dcb46d8f39-изображение.png

  • CE Lua чистка памяти от утечек

    2
    0 Голоса
    2 Сообщения
    25 Просмотры
    MasterGHM
    Оптимизация CE Lua кода по сборке мусора

    Есть инструкции, которые добавляют мусора больше чем другие.
    Показываем объем памяти мусора

    print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))

    Ниже код того как попробовать узнать сколько мусора добавил код при парсинге ассемблерной строки двумя способами

    local s = " 0045464A - FF 05 A4B54500 - inc [0045B5A4] { [000003EA] }" function GetDebugString(address) return splitDisassembledString(s) end \-- address, bytes, opcode function GetDebugString2(address) local clearString = string.gsub(s, '%s','') return string.match(clearString, '^(.-)%-(.-)%-(.-)$') end function NoOptimizeCode() GetDebugString2() end function OptimizeCode() GetDebugString() end local countRepeat = 500000 -- add more cycle local x1 = 0 local x2 = 0 x1 = getTickCount() print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) for i = 1, countRepeat do NoOptimizeCode() end print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) x2 = getTickCount() for i = 1, countRepeat do OptimizeCode() end print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) print(string.format("%.2f", (x2 - x1)/(getTickCount() - x2)) )

    Пример результатов могут отличаться. Фиг его знает почему. Возможно работает сборщик мусора в разные моменты времени

    Lua memory usage 1.8 MiB
    Lua memory usage 1.8 MiB
    Lua memory usage 1.8 MiB
    1.49

    Lua memory usage 1.8 MiB
    Lua memory usage 2.3 MiB
    Lua memory usage 2.3 MiB
    1.47

    Lua memory usage 2.3 MiB
    Lua memory usage 2.8 MiB
    Lua memory usage 2.8 MiB
    1.49

  • CE Script Editor [Notepad+]

    Перенесена
    1
    0 Голоса
    1 Сообщения
    24 Просмотры
    Нет ответов
  • CE Lua ColorPicker (скрытый компонент)

    6
    0 Голоса
    6 Сообщения
    50 Просмотры
    PitronicP

    значит не мой случай, мне женька только экзешники скинул, а как я понял нужны полностью исходники.

  • CE Compact View

    2
    0 Голоса
    2 Сообщения
    34 Просмотры
    MasterGHM

    Ниже находится обучающий пример плагина для CE Lua с установкой компактного режима применяя парадигму ООП — инкапсуляции.

    Для программирования плагинов на Lua могут пригодится приемы ООП. Это касается сущностей, их поведений и взаимодействий между ними. В данном примере CECompactView — описание класса на основе мета-таблицы и оно является сущностью. Функции класса — uncompact() и compact(), которые реализуют поведения этой сущности. Основной скрипт с описанием сущности можно поместить в отдельный файл .lua и далее можно кратко инициализировать сущность и управлять ей

    Например

    \-- Создание экземпляра класса через new() функцию, где аргументом является состояние компактный или некомпактный ce_compact_view = CECompactView:new(true) \-- Проверить состояние \--print(ce_compact_view:get_state() and 'Compact View Mode' or 'Full View Mode') \-- Установить компактный режим \--ce_compact_view:compact() \-- Установить не компактный режим \--ce_compact_view:uncompact()

    Сам класс или мета-таблица.

    \-- Класс инкапсулирующий поведения компактного состояния окна CE CECompactView = {} function CECompactView:new(state) local obj = {} -- Состояние компактное или нет: true или false obj.compact_mode = state -- Форма CE, где getMainForm — поддерживаемая функция CE и возвращает главную форму CE obj.form_ce = getMainForm() -- Получение элементов контекстного меню главной формы local menu_items = obj.form_ce.menu.items -- Создание нового контекстного меню с названием CompactView и именем ItemCompact obj.menu_item_compact = createMenuItem(menu_items) obj.menu_item_compact.name = 'ItemCompact' obj.menu_item_compact.caption = 'CompactView' -- Добавление контекстного меню на главную форму menu_items.add(obj.menu_item_compact) -- Сменить состояние окна CE: компактное или нет function obj:set(state) -- view_components состояния скрытия компонентов obj.compact_mode = state -- видимость компонентов обратна компактному режиму local view_components = not state obj.form_ce.panel1.visible = view_components obj.form_ce.panel4.visible = view_components obj.form_ce.panel5.visible = view_components obj.form_ce.Splitter1.visible = view_components -- Записать имя по состоянию obj.menu_item_compact.caption = state and 'Full View Mode' or 'Compact View Mode' -- Поставить обработчик по состоянию obj.menu_item_compact.onClick = state and obj.compact or obj.uncompact print(state and 'Compact View Mode' or 'Full View Mode') end -- Некопактное окно CE function obj:uncompact() obj:set(true) end -- Компактное окно CE function obj:compact() obj:set(false) end -- Состояние окна CE: компактное или нет function obj:get_state() return obj.compact_mode end -- Связь таблицы (смотрим докуметацию по Lua) setmetatable(obj, self) obj.__index = self -- Активировать состояние obj:set(state) -- Возвращает ссылку на экземпляр return obj end \------------ \-- Создание экземпляра класса ce_compact_view = CECompactView:new(true) \-- Проверить состояние \--print(ce_compact_view:get_state() and 'Compact View Mode' or 'Full View Mode') \-- Установить компактный режим \--ce_compact_view:compact() \-- Установить не компактный режим \--ce_compact_view:uncompact()

    Скрипт можно сохранить в Lua файл и добавить в папку autorun.

  • CE disassembler

    1
    0 Голоса
    1 Сообщения
    639 Просмотры
    Нет ответов
  • CE Tool Lua Regular expressions 2

    2
    0 Голоса
    2 Сообщения
    26 Просмотры
    MasterGHM
    Lua поиск элемента до и после строки

    Была задача получить два списка из документа, в котором было с пару десятков тысяч строк. На практике выяснилось, что искать текст после ключевого слова легче чем искать текст до ключевого слова. Об этом и будет дальше

    В утилите "Lua Regular Expressions (v. 1.0)"
    image.png
    Текст во вкладке "gmatch"

    Game1
    gameCompany
    DAU
    53.21k
    -20%
    Game2
    gameCompany
    DAU
    20.35k
    -20%

    Поиск элемента после строки: "DAU "DAU%c%c(.-)%c%c"

    53.21k;20.35k;

    Поиск элемента до строки: "%c%c(.-)gameCompany%c%c"
    (паттерн со двигом скобок для поиска предыдущей фразы)
    не прокатит для вывода списка игр над фразой gameCompany

    ;53.21k
    -20%

    Game2
    ;

    Очевидно, можно сделать поиск по похожим фрагментам, которые идут последовательно сверху вниз.

    Cначала добавим первую пустую строку и видим повторяющиеся фрагменты

    "%c%cGame1%c%cgameCompany%c%c"

    пишем шаблон ".*%c%c(.-)%c%cgameCompany%c%c" и опять мимо

    Game1;53.21k
    -20%

    Game2;

    Потому что текст над Game2 пошел выше Game2. Тогда делаем захват, только первой фразы и дальше не идем "%c%c(%w-)%c%cgameCompany%c%c"

    Game1;Game2;
    И тогда все ок.

    Но это еще не все. Осталась первая пустая строка, которую добавили, если её удалить, тогда "%c%c(%w-)%c%cgameCompany%c%c"

    Game2;
    Не видит Game1.

    Значит мы можем убрать %c%c, и будет "(%w-)%c%cgameCompany"

    Game1;Game2;

    Дальше название игры может быть таким "My Game: my Game". Здесь и пробел и двоеточие. В таком случае текст уже будет

    My Game1: my Game

    gameCompany

    DAU

    53.21k

    -20%

    My Game2: my Game

    gameCompany

    DAU

    20.35k

    -20%

    Пробуем "(%w-)%c%cgameCompany"

    Game;Game;
    Что не верно, т.к. захват одним (%w-)

    Мы должны в скобках развернуть фразу имени игры. В ней могут быть пробелы, числа, текст и двоеточие

    '([%w%s]-)%c%cgameCompany'

    my Game; my Game;

    Затем ([:%w%s]-)%c%cgameCompany

    My Game1: my Game;

    My Game2: my Game;

    Затем %c?%c?([:%w%s]-)%c%cgameCompany

    My Game1: my Game;
    My Game2: my Game;

    Вот и все. Если попариться один раз, то тексты уже парсить будет гораздо быстрее.

    Так я вывел столбы DAU и названий игр в таблицу, что было в районе 500 строк из пару десятков тысяч строк

    p.s. Текст в консоли Lua отличается %c%c, а %с

    p.s.p.s. Можно раcсплитить текст по "/n/r" или "/n" в таблицу строк и по индексам данных находить предыдущую или последующую фразу. Но мне проще две строки ввести "%c?%c?([:%w%s]-)%c%cgameCompany" и "DAU%c%c(.-)%c%c"

  • Эта тема удалена!

    Перенесена
    0
    0 Голоса
    0 Сообщения
    6 Просмотры
    Нет ответов
  • CE mapbranches

    1
    0 Голоса
    1 Сообщения
    634 Просмотры
    Нет ответов
  • CE Tiny Dumper

    Перенесена
    2
    0 Голоса
    2 Сообщения
    34 Просмотры
    MasterGHM

    Пошаговое руководство по Tiny Dumper

    В этом руководстве по шагам описано как снять дамп со стека и раструктуризовать его. Если лень читать, то предлагаю посмотреть хотя бы последний скрин. Там можно увидеть результат. Это самый важный скрин.

    Перед запуском CE устанавливаем файлы плагина в папку autorun (frmTinyDumper.xml и TinyDumper.lua)

    Запускаем игру например "Painkiller - Battle out of Hell 1.64" поставленная в оконный режим через 3DAnalyze.

    Оконный режим ставить обязательно, т.к. будет пошаговая отладка. В противном случае игра зависнет, а с CE рабтать нельзя будет

    Запустить CE с установленным плагином и подключиться к игре

    Ищем адрес здоровья (или брони, или патронов), тип Double (8 байт)
    0x24571EA8 = 99.2900238037109

    Ставим бряк на доступ или на запись на адрес 0x24571EA8

    2bf8d038-de92-4de0-88f6-944b9093adf5-image.png

    Идем в игру и встаем под удар персонажем

    Появляются инструкции
    3b2e99be-4a03-455c-a575-28511d347064-image.png
    и там же нажимаем на кнопку Stop, чтобы бряки не мешались в окне бряков

    Берем например инструкцию

    1015C194 - 89 53 08 - mov [ebx+08],edx
    6ad80302-80f1-4905-8bac-bdbfbb930bfd-image.png
    По ней идем в дизассемблер и на инструкции жмем F5 - установка бряка на доступ

    2755fb71-f09c-4815-88c7-191fbfdf2dc7-image.png

    Открываем окно бряков, выделяем инструкцию и пишем условие на прерывание с остановкой процесса

    EBX==0x24571EA0 (это условие взяли, потому что ebx находится в инструкции, а значение взяли EBX из отладчика)

    2c1e1ed4-0df0-4314-981f-f8e31550959d-image.png
    43e9dfd5-1c49-4bf2-bf1a-b588c308181c-image.png

    Нажимаем Ок, идем в игру
    9. Видим, что произошла остановка игры
    148b600b-4ffe-4e2c-893a-df3330aff53f-image.png
    10. Открываем окно ТиниДампера
    6db64901-ca0e-4d32-8be9-2fcb27894556-image.png

    Пишем значение регистра esp и название будущей зарегенной метки
    26586a39-c6f1-40ee-a44b-bd966578e736-image.png

    Нажимаем "Dump and Close" и CTRL+U чтобы видеть под рукой зареганные ваши метки

    7f7a0d40-9107-4c19-b13f-2105a57422a5-image.png

    Открываем окно расструктуризации CTRL+D и пишем метку в свободное поле
    1104aed5-e0c1-45bd-b880-877433c6c1a1-image.png

    Далее следуем действия как на рисунках
    9cac0888-208c-4f0e-9ae2-b53f6c49aeb4-image.png
    7db1307b-9305-4fd6-9b34-e75c2c8cc466-image.png

    Наконец результат
    6d506668-7bed-4cae-9c22-47af124c0c16-image.png

    Не только сохраняются данные, которые пропадут на следующий такт процессора, но и расструктуризовали и можем сравнивать эти данные с другими дампами стека. Зачем, как и для чего это выходит за рамки этого руководства.

    Сейчас процесс игры остановлен на бряке кода. Чтобы продолжить игру. Удаляем бряк из окна бряков и отпускаем игру по F9.

    Теперь снимаем другие дампы на том же адресе для адресов здоровья врагов на предмет отличиях их или для поиска указателей... Во всяком случае сохраненный дамп может дать какие-то подсказки и зацепки. Главное не начать новый уровень игры или не загружать сохранения, т.к. обычно при переходе на новый уровень данные могут измениться... На этом пока все

    -----
    Tiny dumper 1.2 Сравнение структур после перезагрузки. Поиск фильтра свой-чужой-дружественый

    Запускаем игру, запускаем CE и присоединяем процесс игры к CE

    Сохраняем игровой слот перед тем как искать структуры

    Находим три структуры игроков: свой игрок, дружественный, враг

    Дампим три структуры из пункта 3 указывая: базовый адрес структуры, уникальную метку

    Игру закрываем, снова открываем, загружаем слот, присоединяем процесс игры к CE

    В Tiny dumper 1.2 вызываем контекстное меню правой кнопки мышки и вызываем опцию "Rewrite dumps" - дампы из кеша перезаписываются в память в процесса игры

    Снова находим три структуры игроков: свой игрой, дружественный, враг

    В окне расструктуризации создаем три группы

    Группа1 "Свой игрок":

    -адрес после перезагрузки

    -метка из тини дампера своего игрока до перезагрузки

    Группа2 "Чужой игрок":

    -адрес после перезагрузки

    -метка из тини дампера чужого игрока до перезагрузки

    Группа3 "Дружественный игрок":

    -адрес после перезагрузки

    -метка из тини дампера дружественного игрока до перезагрузки

    Если повезет, то находим фильтр - фиолетового цвета строка. Если филетовых строк несколько, то запоминаем их смещения и значения на всякий случай

    Пишем АА-скрипт со смещением фильтра. Правильно написанный АА-скрипт не будет крешить игру.

    Активируем АА-скрипт и проверяем в игре, что свой и дружественный игроки не получают урон, а вражеские получают урон. Если это не так, то берем другие смещения из пункта 9 и повторяем 10.

    Если фильтр найти не удалось, то ищем 3 многоуровневых указателя до верхего статического адреса для своего, для 2-х врагов. Открываем Structure Spider.

    Указываем в поиске уровень вложенности указателей.

    Попеременно вводим два статических адреса - начала структур своего и чужих игроков. Правило поиска выбираем исходя из типов игроков. Если это свой и чужой, то искать отличные. Если это чужой и чужой, то искать одинаковые. Перезапускам игру и опять проделываем эти действия.

    Если не нашлось ничего, то что-то делали не так или отличия между группами игроков нет. Однако графический интерфейс обычно связан только с нашим героем и не связан с другими. Поэтому по связи GUI как минимум фильтр свой-чужой можно сделать всегда. Что касается дружественных игроков, то нужно будет исследовать более углубленно.

  • CE Stack Viewer

    1
    0 Голоса
    1 Сообщения
    21 Просмотры
    Нет ответов
  • CE Action Logger 1.0 Beta

    4
    0 Голоса
    4 Сообщения
    62 Просмотры
    MasterGHM

    Отправил

  • CE Plugin: AA Maker 2.4.2

    Перенесена
    7
    1 Голоса
    7 Сообщения
    157 Просмотры
    PitronicP

    Хотя можно добавить в это окно как на скриншоте я стрелкой показал. одновременно и имя в таблице и имя скрипта в асм.
    photoeditorsdk-export.png

  • CE Dissect Data Scaner 1.0.2 (4 hardware breakpoints)

    6
    0 Голоса
    6 Сообщения
    140 Просмотры
    MasterGHM

    Сегодя или завтра еще выложу исходники на другой аналогичный плагин (не новый). Там breakpoint на область памяти (на структуру). Но это все старые иходники. Видео по нему у меня есть на yutube канале.

    Если, кто захочет усовершенствовать плагины, то, наверно, я могу создать отдельную ветку репозитория и кто-то сможет коммитить туда изменения.

    Аналогично используя форум и репозиторий возможна совместная разработка таблиц и исходников на CE для плагинов и для игр. Просто нужно чтобы, кто-то инициировал. Если, кто сможет организовать это все, то смогу дать необходимые права. Временм у меня к сожалению, не много. Но если что-то подсказать, то буду связи.