как открыть код lua скрипта
Информация Гайд Всё о Lua скриптинге для MoonLoader
Для лёгкой и удобной работы с кодом Lua скриптов вам понадобится настроить для себя среду разработки. Для работы с Lua достаточно любого текстового редактора, но какой-нибудь блокнот Windows для этого подходит совсем плохо, поэтому лучше использовать специализированные программы. На текущий момент полная поддержка MoonLoader есть в Atom и Notepad++, помимо этого есть пользовательские дополнения для Visual Studio Code и Sublime Text.
Проект по-умолчанию.
В меню File выбираем пункт Open Folder. и указываем путь до папки moonloader, после этого она откроется как проект.
Проект по-умолчанию.
Как и в Atom, здесь есть возможность показа меню проекта, а точнее «Папка как Проект». В меню «Файл» выбираем пункт «Открыть Папку как Проект» и указываем путь к папке «moonloader».
Кодировка по-умолчанию.
Над лентой выбираем пункт Опции и переходим в Настройки. В меню слева выбираем пункт Новый документ и в разделе кодировки ставим флажок на список, в котором выбираем кодировку Windows-1251
После установки среды разработки, изучения основ Lua и ознакомления с документацией MoonLoader, можно приступать от теории к практике. Давайте сначала рассмотрим самое основное, на всякий случай.
В этом примере показаны не все директивы, за полным списком обращайтесь к соответствующей странице на вики.
События и колбэки
Событиями, а точнее их обработчиками, в MoonLoader называются функции, вызывающиеся в скриптах автоматически при каком-либо действии в игре, требующим обработки. Обработчики событий могут иметь входящие и возвращаемые параметры: входящие передают какую-то информацию скрипту, а возвращаемые позволяют повлиять на дальнейшую обработку после совершения события.
Зарегистрировать обработчик события можно двумя способами: просто добавить в скрипт функцию с соответствующим именем, либо воспользоваться функцией addEventHandler. Учтите, что первым способом обработчик может быть зарегистрирован только один раз.
Скрипты с зарегистрированными событиями не завершаются самостоятельно.
Пример: onScriptTerminate вызывается при завершении какого-либо скрипта
С основными принципами разработки вы теперь знакомы и при этих знаниях сможете выполнить большинство задач, однако некоторые задачи требуют применения специальных техник. Давайте рассмотрим некоторые из них.
Создание модулей
Модули делятся на два типа: Lua и DLL. Lua-модули пишутся, как вы уже могли догадаться, на языке Lua и в результате представляют из себя привычные Lua-скрипты, только с некоторыми особенностями.
Давайте рассмотрим пример простого модуля, назовём его example:
Использовать Lua c С++ легче, чем вы думаете. Tutorial по LuaBridge
Данная статья — перевод моего туториала, который я изначально писал на английском. Однако этот перевод содержит дополнения и улучшения по сравнению с оригиналом.
Туториал не требует знания Lua, а вот C++ нужно знать на уровне чуть выше базового, но сложного кода здесь нет.
Когда-то я написал статью про использование Lua с C++ с помощью Lua C API. В то время, как написать простой враппер для Lua, поддерживающий простые переменные и функции, не составляет особого труда, написать враппер, который будет поддерживать более сложные вещи (функции, классы, исключения, пространства имён), уже затруднительно.
Врапперов для использования Lua и C++ написано довольно много. С многими из них можно ознакомиться здесь.
Я протестировал многие из них, и больше всего мне понравился LuaBridge. В LuaBridge есть многое: удобный интерфейс, exceptions, namespaces и ещё много всего.
Но начнём по порядку, зачем вообще использовать Lua c С++?
Зачем использовать Lua?
Конфигурационные файлы. Избавление от констант, магических чисел и некоторых define’ов
Данные вещи можно делать и с помощью простых текстовых файлов, но они не так удобны в обращении. Lua позволяет использовать таблицы, математические выражения, комментарии, условия, системные функции и пр. Для конфигурационных файлов это бывает очень полезно.
Например, можно хранить данные в таком виде:
Можно получать системные переменные:
Можно использовать математические выражения для задания параметров:
Скрипты, плагины, расширение функциональности программы
C++ может вызывать функции Lua, а Lua может вызывать функции C++. Это очень мощный функционал, позволяющий вынести часть кода в скрипты или позволить пользователям писать собственные функции, расширяющие функциональность программы. Я использую функции Lua для различных триггеров в игре, которую я разрабатываю. Это позволяет мне добавлять новые триггеры без рекомпиляции и создания новых функций и классов в C++. Очень удобно.
Немного о Lua. Lua — язык с лицензией MIT, которая позволяет использовать его как в некоммерческих, так и в коммерческих приложениях. Lua написан на C, поэтому Lua работает на большинстве ОС, что позволяет использовать Lua в кросс-платформенных приложениях без проблем.
Установка Lua и LuaBridge
Итак, приступим. Для начала скачайте Lua и LuaBridge
Добавьте include папку Lua и сам LuaBridge в Include Directories вашего проекта
Также добавьте lua52.lib в список библиотек для линковки.
Создайте файл script.lua со следующим содержанием:
Добавьте main.cpp (этот код лишь для проверки того, что всё работает, объяснение будет чуть ниже):
Скомпилируйте и запустите программу. Вы должны увидеть следующее:
LuaBridge works!
And here’s our number:42
Примечание: если программа не компилируется и компилятор жалуется на ошибку “error C2065: ‘lua_State’: undeclared identifier” в файле LuaHelpers.h, то вам нужно сделать следующее:
1) Добавьте эти строки в начало файла LuaHelpers.h
2) Измените 460ую строку Stack.h с этого:
А теперь подробнее о том, как работает код.
Включаем все необходимые хэдеры:
Все функции и классы LuaBridge помещены в namespace luabridge, и чтобы не писать «luabridge» множество раз, я использую эту конструкцию (хотя её лучше помещать в те места, где используется сам LuaBridge)
Открываем наш скрипт. Для каждого скрипта не нужно создавать новый lua_State, можно использовать один lua_State для множества скриптов. При этом нужно учитывать коллизию переменных в глобальном нэймспейсе. Если в script1.lua и script2.lua будут объявлены переменные с одинаковыми именами, то могут возникнуть проблемы
Открываем основные библиотеки Lua(io, math, etc.) и вызываем основную часть скрипта (т.е. если в скрипте были прописаны действия в глобальном нэймспейсе, то они будут выполнены)
Создаём объект LuaRef, который может хранить себе всё, что может хранить переменная Lua: int, float, bool, string, table и т.д.
Преобразовать LuaRef в типы C++ легко:
Проверка и исправление ошибок
Но некоторые вещи могут пойти не так, и стоит производить проверку и обработку ошибок. Рассмотрим наиболее важные и часто встречающиеся ошибки
Что, если скрипт Lua не найден?
Что, если переменная не найдена?
Переменная может быть не объявлена, либо её значение — nil. Это легко проверить с помощью функции isNil()
Переменная не того типа, который мы ожидаем получить
Например, ожидается, что переменная имет тип string, тогда можно сделать такую проверку перед тем как делать каст:
Таблицы
Таблицы — это не просто массивы: таблицы — замечательная структура данных, которая позволяет хранить в них переменные Lua любого типа, другие таблицы и ставить ключи разных типов в соответствие значениям и переменным. Таблицы позволяют представлять и получать конфигурационные файлы в красивом и легкочитаемом виде.
Создайте script.lua с таким содержанием:
Код на C++, позволяющий получить данные из этого скрипта:
Вы должны увидеть на экране следующее:
Window v.0.1
width = 400
height = 500
Как видите, можно получать различные элементы таблицы, используя оператор []. Можно писать короче:
Можно также изменять содержимое таблицы:
Это не меняет значение в скрипте, а лишь значение, которое содержится в ходе выполнения программы. Т.е. происходит следующее:
Чтобы сохранить значение, нужно воспользоваться сериализацией таблиц(table serialization), но данный туториал не об этом.
Пусть теперь таблица выглядит так:
Как можно получить значение window.size.w?
Вот так:
Функции
Давайте напишем простую функции на C++
И напишем вот это в скрипте на Lua:
Затем мы регистрируем функцию в C++
Примечание 1: это нужно делать до вызова «luaL_dofile», иначе Lua попытается вызвать необъявленную функцию
Примечание 2: Функции на C++ и Lua могут иметь разные имена
Данный код зарегистрировал функцию в глобальном namespace Lua. Чтобы зарегистрировать его, например, в namespace «game», нужно написать следующий код:
Тогда функцию printMessage в скриптах нужно будет вызывать данным образом:
Пространства имён в Lua не имеют ничего общего с пространствами имён C++. Они скорее используются для логического объединения и удобства.
Теперь вызовем функцию Lua из C++
Вы должны увидеть следующее:
You can still call C++ functions from Lua functions!
Result:9
Разве не замечательно? Не нужно указывать LuaBridge сколько и каких аргументов у функции, и какие значения она возвращает.
Но есть одно ограничение: у одной функции Lua не может быть более 8 аргументов. Но это ограничение легко обойти, передав таблицу, как аргумент.
Если вы передаёте в функцию больше аргументов, чем требуется, LuaBridge молча проигнорирует их. Однако, если что-то пойдёт не так, то LuaBridge сгенерирует исключение LuaException. Не забудьте словить его! Поэтому рекомендуется окружать код блоками try/catch
Вот полный код примера с функциями:
Что? Есть ещё что-то?
Да. Есть ещё несколько замечательных вещей, о которых я напишу в последующих частях туториала: классы, создание объектов, срок жизни объектов… Много всего!
Также рекомендую прочитать этот dev log, в котором я рассказал о том, как использую скрипты в своей игре, практические примеры всегда полезны.
Скриптовый язык Lua
Основные свойства и возможности
Lua — популярный мощный скриптовый язык программирования. Lua в переводе с португальского означает «луна», и это слово не является аббревиатурой или акронимом. Lua разработан подразделением Tecgraf Католического университета Рио-де-Жанейро в Бразилии (Computer Graphics Technology Group of Pontifical Catholic University of Rio de Janeiro), история языка ведёт отсчёт с 1993 года. Lua распространяется свободно, с открытыми исходными текстами на языке Си. Основные особенности языка:
Изначально язык задумывался как описательный, для удобства формирования больших массивов данных при решении задач машинного моделирования. Сейчас язык часто позиционируется как лучший встраиваемый язык, что, впрочем, не мешает его использовать отдельно. Список программных продуктов, в которых Lua используется как встраиваемый язык, вы можете увидеть здесь или здесь.
Чтобы установить Lua на Windows, просто распакуйте бинарный дистрибутив. Можете ассоциировать расширение .lua с интерпретатором lua5.1.exe, а также прописать путь к интерпретатору в PATH.
Основные возможности языка:
Некоторые полезные ресурсы:
Hello, World!
Создайте текстовый файл test.lua в кодировке cp866 следующего содержания:
Запустите его на исполнение командой наподобие следующей:
Вы можете скомпилировать скрипт в байт-код командой наподобие следующей:
В результате вы получите файл luac.out (рядом с компилятором), который вы можете запустить на исполнение командой наподобие следующей, точно так же, как обычный скрипт:
Примечательно, что расширения имён файлов скриптов (в т.ч. откомпилированных в байт-код) могут быть произвольными — интерпретатор автоматически анализирует, что ему передали.
Программа lua5.1.exe при запуске без параметров является интерактивным интерпретатором. Запустите её и введите код наподобие следующего:
Приведённый код запустит на исполнение указанный файл скрипта. Для выхода наберите код: os.exit().
Пример вычисления факториала (рекурсия):
Консольная игра «угадай число»:
Особенности языка
Эта часть статьи рассчитана на тех, кто уже немного знаком с каким-либо языком программирования, и здесь мы приведём только некоторые особенности, которые в каком-то смысле определяют уникальное «лицо» языка. Полностью синтаксис Lua описан в документации к нему.
Lua — регистрочувствительный (регистрозависимый) язык.
Появление локальной переменной осуществляется с помощью ключевого слова local. Все остальные переменные — глобальные. Область видимости локальной переменной распространяется на всю порцию (chunk) кода, в котором эта переменная была объявлена. Такой порцией является, например, файл скрипта. Эквивалентом порции кода является блок. В общем случае блок специфицируется с помощью двух ключевых слов следующим образом:
Арифметические операторы, операторы сравнения переменных и логические операторы (and, or, not) вполне интуитивны, за исключением нескольких моментов. Оператор сравнения «не равно» записывается так:
Конкатенация строк записывается так:
Обмен содержимым двух переменных может быть записан так:
Если нужно присвоить значение переменной только в том случае, если этой переменной нет (или она равна nil, что одно и то же), можно поступить следующим образом:
Управляющие структуры Lua достаточно интуитивны. Цикл с условием:
Цикл с постусловием:
Другой вариант цикла for, для обхода итерируемых объектов:
Lua поддерживает концепцию замыканий (особый вид функции, определённой в теле другой функции), например:
Поскольку Lua — язык с динамической типизацией, тип данных связывается не с переменной, а с её значением в данный момент. Любой переменной может быть присвоено значение любого типа, вне зависимости от того значения, которое она содержала раньше. До первого присваивания переменная содержит значение nil (если к ней обратиться). В Lua восемь основных типов данных: nil (неопределенный), boolean (логический), number (числовой), string (строковый), function (функция), userdata (пользовательские данные), thread (поток) и table (таблица).
Таблицы, функции, потоки и userdata являются объектами, т.е. переменная содержит не непосредственное значение, а ссылку на объект, со всеми вытекающими последствиями. Присваивание, передача параметров и возврат результата из функции оперируют только ссылками на значения, и эти операции никогда не ведут к созданию копий.
Lua приводит типы автоматически, но не совсем так, как это делает большинство других языков:
При сравнении, в отличие от арифметических операций, не происходит явного преобразования, и, если что-то не так, интерпретатор выдаст ошибку.
Способы задания строк:
Последовательности символов типа «[[» называются «длинными скобками» (long brackets). В «универсальных» (или «длинных») строках действительно возможны любые символы, вплоть до символа NULL (конец строки). Например, если вы вставите в строку символ BEL, то при печати в консоли вы услышите звук системного динамика. В принципе, ничто не помешает иметь в программе строку в несколько десятков мегабайт. Непосредственной поддержки Unicode-строк в Lua нет. Однако, ничто не помешает поместить в строку, например, последовательность символов в кодировке UTF-8.
Способы задания чисел:
Все числа в Lua являются числами с плавающей точкой двойной точности. Несмотря на это, Lua остаётся очень эффективным в плане производительности.
При проверках только nil и false являются ложными значениями, всё остальное Lua считает истиной.
Так называемые таблицы (динамические ассоциативные массивы), на которых фактически основана вся синтаксическая мощь языка:
Ещё один небольшой пример, дающий представление о синтаксисе работы с таблицами:
Несмотря на такие синтаксические «вольности», таблицы реализованы в плане производительности очень эффективно.
Оператор : (двоеточие) позволяет Lua автоматически передать «self» параметр в функцию, реализуя инкапсуляцию:
Далее кратко упомянем об остальных типах данных, чтобы получить представление о них.
Тип userdata служит для хранения произвольных данных (структур Си) в переменных Lua. Фактически значения этого типа соответствуют просто блокам памяти и не имеют никаких предопределённых операций, кроме сравнения и присваивания. Значения этого типа не могут быть непосредственно созданы в программе на Lua, а должны создаваться только через Си API (т.е. в вызывающей скрипт программе). Тип thread соответствует потоку выполнения. Тип function соответствует функциям. Функции в Lua могут быть записаны в переменные, переданы как параметры в другие функции и возвращены как результат выполнения функций.
Lua позволяет перегружать операции для таблиц и userdata с помощью метатаблиц. Метатаблица представляет из себя обычную таблицу, в качестве ключей которой используются строки (события), а в качестве значений — методы (обработчики). C метатаблицей может быть связана еще одна метатаблица (ключ «__metatable»), и, если событие не определено в первой метатаблице, оно ищется во второй, и т.д. Все глобальные переменные являются полями в специальных таблицах Lua, называемых таблицами окружения (environment tables).
Lua как встроенный язык текстового редактора SciTE
Как пример рассмотрим использование Lua в текстовом редакторе SciTE.
SciTE — мощный кросс-платформeнный (Win32, Linux) популярный текстовый редактор с открытым исходным кодом. Русскую сборку SciTE со множеством полезных дополнений и подробной русской документацией вы можете взять здесь (редактор не требует инсталляции в обычном понимании этого слова; дистрибутив является просто самораспаковывающимся архивом). SciTE Lua Scripting Extension в качестве языка сценариев использует Lua 5.1.
Изложенное ниже ни в коем случае не является руководством по настройке SciTE с помощью Lua; это лишь маленький пример, показывающий, как может выглядеть использование Lua как встроенного языка. Для получения информации обращайтесь к документации в поставке SciTE, а также изучайте файлы конфигурации и уже существующие в поставке скрипты. Примеры скриптов Lua для SciTE и документацию по этому вопросу вы можете найти здесь и здесь, а также в вышеупомянутой русской сборке SciTE (там же есть и русская документация). С помощью написания сценариев на Lua вы можете настроить SciTE под ваши потребности, добавляя новое поведение и функциональность.
Вы можете объявить новые команды, которые доступны через меню Tools и клавиатуру. Например, в файл настроек SciTEGlobal.properties в каталоге установки SciTE можно поместить следующие команды:
В результате в меню «Tools» появится команда «Запустить мой скрипт», при выборе которой исполнится скрипт \tools\myScript.lua, если он существует по такому пути в папке установки SciTE. Чтобы проверить работу скрипта, сохраните в нём текст наподобие следующего:
Теперь в любой момент при вызове меню «Запустить мой скрипт» вы будете получать сообщение в нижней панели редактора.
Вы можете обрабатывать события, объявленные в интерфейсе расширений SciTE (SciTE Extension Interface), просто объявляя функции с именами этих событий: OnOpen, OnClose, OnSwitchFile и т.д. Для некоторых событий SciTE передаёт один или несколько аргументов в функцию обработки события. Обработчики событий возвращают булево значение (true показывает, что событие полностью обработано и другие обработчики не будут вызываться; в большинстве случаев обработчик должен вернуть false).
В файле \tools\SciTEStartup.lua в каталоге установки SciTE с помощью функции dofile грузятся скрипты, обрабатывающие события редактора (этот файл стартует при загрузке SciTE). Вы можете загрузить и свой скрипт, добавив в этот файл команду наподобие следующей:
Чтобы проверить работу скрипта \tools\myScript.lua, сохраните в нём текст наподобие следующего:
Теперь, после перезапуска SciTE, будет обрабатываться событие OnChar, в результате чего вы будете получать сообщение в нижней панели редактора при вводе каждого символа.
SciTE добавляет в глобальный контекст Lua ряд переменных, функций и объектов (таблиц), которые позволяют управлять редактором и изменять его внешний вид.
Пакет Lua for Windows
Пакет Lua для Windows (LfW) содержит всё, что необходимо для написания, выполнения и отладки самостоятельных сценариев Lua на Windows. В поставку включены многочисленные библиотеки и примеры, готовые к использованию, это пакет с «батарейками в комплекте». LfW поддерживает Windows 2000 и более новые версии Windows. Инсталлятор пакета версии 5.1.4.23 от 06.02.2009 имеет размер порядка 16 Мб.
Дополнительные библиотеки пакета предоставляют возможности:
Скрипт «Hello, World!» будет выглядеть точно так же, как в одноимённом разделе выше, с той разницей, что для его запуска следует использовать команду наподобие такой:
Интерпретатор wlua.exe предназначен для запуска скриптов с графическим интерфейсом, без отображения окна командного интерпретатора. Такие скрипты могут иметь расширение .wlua, которое после установки пакета уже ассоциировано с wlua.exe.
Простейший пример работы с COM:
Пример работы с ADO, вывод всех констант (перечислений) ADO:
Простейшие примеры работы с ADSI и WMI:
Простейшие примеры работы с Win32 API:
Скрипт выше подаст несколько звуковых сигналов системным динамиком, выведет на консоль значение переменной среды %USERPROFILE%, а затем отобразит окно с приветствием.
Скрипт выше выведет на консоль значение квадратного корня из двух, а затем текущий каталог.
Пример выше создаст окно с единственной кнопкой, на которой отображается текущее время. Нажатие на кнопку будет обновлять время.
Скриншоты примеров работы с графической библиотекой wxWidgets (сами примеры вы найдёте в поставке):
Людоговский Александр, 10.02.2009г.
Русские Блоги
О расшифровке скрипта LUA
Написал статью на форуме Кансюэ в прошлом году.«Анализ шифрования и расшифровки скрипта Lua для мобильной игры Android»Суть статьи: в этом году я написал дополнительную статью, интегрировав часть содержимого декомпиляции и конфронтации Lua, и используя 3 примера в качестве объяснения (включая соревнование Tencent 2018 года и дополнения, связанные с фэнтезийной мобильной игрой Westward Journey), в начале статьи также добавлено Связанная работа, удобная для всех при изучении Lua reverse. Эта статья состоит из 3 статей в 1, так что содержания слишком много.Друзья, которым интересно, должны набраться терпения, конечно, вы также можете прыгать и смотреть. Наконец, дайте мне ваш совет. Наконец, если у вас есть какие-либо вопросы, оставьте сообщение, обменяйтесь и узнайте вместе.
Связанных с работой
Чтобы некоторые студенты могли лучше изучить обратный инжиниринг Lua, я объединил некоторые из собранных материалов в часть работы по шифрованию и дешифрованию Lua для вашей справки. Прежде чем читать этот раздел, вам все еще необходимы базовые знания Lua. Вот «Благодарность за источник Lua» [19] Юньфэна Далу, и его рекомендуется изучать в сочетании с поисковыми системами.
Статья состоит из 2 частей: первая часть знакомит с соответствующими статьями о шифровании и дешифровании lua, а вторая часть знакомит с соответствующими инструментами lua.
Введение в статью
В этом разделе представлены различные статьи, связанные с Lua в Интернете, включая шифрование и дешифрование Lua, такие как анализ формата файлов, игры и соревнования на основе Lua, технология перехвата Lua и т. Д.
1. Начало работы с шифрованием и дешифрованием Lua:
Не-Bug 1 написал 4 статьи о формате и байт-коде файлов luac и luajit, а также о 010Editor с открытым исходным кодом, разбирающем код шаблона luac и luajit. Одноклассник Ганлв [7] написал 7 серий руководств по шифрованию и расшифровке Lua в My Love Cracking. Tencent gslab [9] написал вводное введение в реверс-инжиниринг игр на Lua, которое представляет собой более раннюю статью о расшифровке игр на Lua. Одноклассник INightElf [10] написал статью о введении декомпиляции lua-скриптов.
2. Мобильные игры на основе Lua:
Lua можно использовать не только для конечных игр, но и для мобильных игр, и из-за популярности мобильных игр он стал стимулом для обмена статьями по обратному анализу lua. Одноклассник wmsuper [11] расшифровал lua-скрипт игры Happy Xiaoxiaole от Tencent на платформе Android, а затем модифицировал lua-скрипт с целью обмана. Студенты Unity [8] расшифровали и изменили поток мобильной игры Lua «Place Jianghu» с помощью метода перехвата для достижения цели изменения игрового вознаграждения. Одноклассник LittleNA [12] расшифровал сценарии lua 3 мобильных игр 3 способами и исправил порядок кодов операций lua в мобильных играх в стиле фэнтези.
3. Соревнование на основе Lua:
Введение в инструмент
У игр lua и luajit с обратным дешифрованием есть связанные инструменты. В этом разделе представлены некоторые основные инструменты.
luadec [16]: Это декомпилятор Lua с открытым исходным кодом, написанный на языке C в сочетании с исходным кодом движка Lua. Он анализирует весь файл байт-кода Lua и восстанавливает его до исходного кода в максимально возможной степени. Конечно, поскольку восстановление является языком высокого уровня, совместимость является общей. Когда вы декомпилируете большое количество файлов, вы обязательно столкнетесь с ошибками. В это время вам нужно вручную исправить ошибки самостоятельно; и это легко сделать так, чтобы декомпиляция не удалась. В настоящее время поддерживаются версии lua5.1, 5.2 и 5.3.
chunkspy: очень полезный инструмент анализа lua, написанный на самом языке lua. Он анализирует весь байтовый файл lua, и, поскольку его вывод представляет собой сборочную форму lua, совместимость очень высока, а также вызывает определенные трудности с чтением. Chunkspy может не только анализировать файлы luac, но и включает интерактивную команду, которая может преобразовывать входной сценарий lua в форму сборки байт-кода lua, что очень полезно для изучения байт-кода lua. Этот скрипт интегрирован в инструмент luadec, и в настоящее время поддерживаются версии также lua5.1, 5.2 и 5.3.
unluac: это также декомпилятор lua с открытым исходным кодом, написанный на языке java и имеющий более низкую совместимость, чем инструменты luadec. Как правило, он используется редко и поддерживает только lua5.1. Вы можете попробовать его, когда вышеперечисленные инструменты не работают.
2. Связанные с Luajit:
luajit-decomp [17]: Инструмент декомпиляции luajit с открытым исходным кодом на github, написанный на языке au3. Сначала преобразуйте файл байт-кода luajit в сборку через собственный exe-файл luajit, а затем инструмент преобразует сборку luajit в язык lua. Поскольку в дизассемблированном байт-коде luajit отсутствует много информации, такой как имена переменных, имена функций и т. Д., Результат декомпиляции читается нечетко, подобно F5 в IDA. Но совместимость очень хороша, поскольку его можно разобрать, его можно декомпилировать, поэтому вам нужно заменить соответствующую версию движка luajit при его использовании (для удовлетворения потребностей разборки). В настоящее время поддерживаются все версии luajit.
ljd [18]: это также инструмент декомпиляции luajit с открытым исходным кодом на github. Он написан на python. Он отличается от того, как luajit-decomp декомпилирует сборку luajit. Он анализирует весь файл luajit с самого начала и может получить дополнительную информацию и степень восстановления. Выше, но из-за большей точности совместимость будет слабее. Проверьте вилку этого проекта, чтобы получить больше совместимых версий. В настоящее время поддерживаются версии luajit2.0, luajit2.1 и т. Д.
Конфронтация декомпиляции
Используйте отладчик для отладки, почему инструмент декомпиляции анализирует ошибку и устраняет причину.
Используйте отладчик для отладки того, как исходный механизм анализирует файл.
Используйте инструмент анализа формата файла, чтобы проанализировать файл, чтобы увидеть, в какой точке анализ не удался.
Следующие три примера будут использованы для борьбы и исправления декомпиляции Lua.
Пример 1: простой вопрос
Это пример проблемы, замеченной на форуме Xuexue. Проблема в том, что игра (возможно, мобильная игра в дороге) изменила длину строки lua int32 на int64, что вызвало пример сбоя декомпиляции. Содержимое относительно простое. См. Способ восстановления. Мой ответ в посте, адрес: https://bbs.pediy.com/thread-217033.htm
Пример 2: Конкурс Tencent Game Security 2018
Проблема с кодом операции и ее решение
Цель исправления кода операции состоит в том, что при вводе файла luac субъекта инструмент дизассемблирования Chunkspy и инструмент декомпиляции luadec могут выводить правильные результаты.
Сначала мы анализируем файл tmgs.dll движка lua в ida, а затем находим функцию luaV_execute (ищем строку «предел для ‘должен быть числом») и обнаруживаем, что параметр case под переключателем (код операции lua) не работает Да, здесь мы можем подтвердить, что код операции виртуальной машины lua для этого вопроса был изменен.
Функция luaV_execute обычного движка lua | Функция luaV_execute расширенного движка lua |
---|---|
Экспорт текста 2 версий luaV_execute через ida
Извлеките таблицу восстановления кода операции через скрипт Python
После того, как инструменты (Chunkspy и luadec) инициализируют файл lua, замените код операции таблицей восстановления
Тестовый запуск, исправление других ошибок
Наконец, замените полученную таблицу восстановления в инструмент. Точка восстановления Chunspy находится в функции DecodeInst. Измененный результат будет следующим:
Тест обнаружил ошибку, результат ошибки:
Из результата ошибки видно, что номер версии файла luac неверен. Версия lua 11 не может быть распознана здесь, на самом деле проблема, специально разработанная для того, чтобы инструмент распознал ошибку. Мы изменили 4-й байт (номер версии lua) 11 файла на 53 в порядке. Правильный результат:
Точка восстановления Luadec находится в функции f_parser файла ldo.c, и добавьте функцию RepairOpcode, восстановление будет следующим:
Запустите его, найдите ошибку и оставайтесь в функции StringBuffer_add, где str указывает на неправильное место, вызывая ошибки чтения строки:
Здесь мы исправили код операции, и Chunkspy успешно разобрался, но с декомпиляцией luadec все еще есть проблемы, которые мы проанализируем в следующем разделе.
Проблема декомпиляции и ее устранение
Я просмотрел записи нескольких крупных парней и обнаружил, что ни один из них не устранил эту проблему.В процессе решения проблемы непосредственно анализировался ассемблерный код Lua. Давайте посмотрим на причину ошибки и посмотрим на стек вызовов vs:
Наконец, luadec работает отлично, и декомпиляция прошла успешно.
Пример 3: Мобильная игра Fantasy Westward Journey
В этом разделе рассказывается о некоторых проблемах, обнаруженных при обучении взламывать код Lua мобильной игры Fantasy Westward Journey в прошлом году. Они организованы и распространены сегодня, поэтому могут не подходить для текущей версии мобильной игры в стиле фэнтези. Мы все еще используем его для справки.
На тот момент при декомпиляции мобильной игры Fantasy Westward Journey возникло около 12 проблем. После модификации исходный код Lua можно было полностью воспроизвести. Здесь использовалась версия luadec5.1.
Исправить один
Вопрос 1: Поскольку код операции Lua мобильной игры мечты был изменен, предыдущее решение заключалось в том, чтобы найти код операции мечты, заменить исходный код операции инструмента декомпиляции и изменить режим операции перед декомпиляцией. Проблема в том, что результаты некоторых тестов в порядке, но когда байт-код luac всей мобильной игры будет декомпилирован, появятся различные ошибки. Причина в том, что luadec5.1 по умолчанию использует порядок кодов операций во многих местах и делает специальные Обработка, поэтому вам нужно найти эти специальные места обработки и изменить их одно за другим. Но это очень проблематично, поэтому я думаю о другом способе, вместо изменения исходного кода операции и режима операции, но когда luadec анализирует байт-код, восстанавливает код операции до исходного кода операции.
Исправить два
Исправить три
Решение 3. Анализ показал, что параметр c OP_NEWTABLE здесь представляет размер ключа в хэш-таблице, а параметр c был неправильно преобразован в декомпилированном коде, что привело к ошибке синтаксического анализа. Измененный код выглядит следующим образом:
Исправить четыре
Вопрос 4: Ошибка инструмента декомпиляции и выход.
Решение 4. Отслеживание обнаружило, что в функции AddToTable PrintTable вызывается, когда ключ равен 0, а PrintTable освобождает таблицу, и при следующем вызове таблицы происходит сбой доступа к памяти. Измените код следующим образом:
Исправить пять
Вопрос 5: Когда функция возвращает результат с несколькими значениями и назначается нескольким переменным, ошибка декомпиляции выглядит следующим образом (дизассемблирование lua):
Когда приведенный выше код анализируется до строки 27, выдается сообщение об ошибке при извлечении R3 из регистра. Причина в том, что, когда предыдущий вызов возвращает несколько значений, он только помечается в F-> Rcall и не отмечается в регистре. Скомпилированный результат должен быть :
Решение 5. Если reg пуст, а Rcall не пуст, добавьте отметку return more и измените 2 функции:
Исправить шесть
Вопрос 6: Ошибка декомпиляции возникает, когда функция имеет только один оборот.
Исправить семь
Вопрос 7: Произойдут некоторые ошибки инициализации таблицы.
Исправить восемь
Вопрос 8: Произошла ошибка при разборе части переменных параметров, но инструмент не сообщает об ошибке при декомпиляции.
Решение 8. Когда is_vararg равно 7, F-> freeLocal добавляет еще раз:
Исправить девять
Вопрос 9: Инструмент декомпиляции выводит на китайском языке символы типа url (аналогично «\ 230 \ 176 \ 148 \ 231 \ 150 \ 151 \ 230 \ 156 \ 175»), а не китайские.
Решение 9. В функции DecompileString в файле proto.c закомментируйте строковую функцию преобразования по умолчанию:
Затем добавьте условия ограничения для оценки в следующих 3 местах, потому что байт char является отрицательным числом для китайских символов, поэтому функции isalpha и isalnum будут работать неправильно, поэтому добавьте условия ограничения, меньшие или равные 127:
Исправить десять
Вопрос 10: Не удалось разобрать. Поскольку некоторые файлы содержат очень длинные строки, вызов функции sprintf не выполняется.
Решение 10. Увеличьте размер кеша:
Исправить одиннадцать
Вопрос 11: Когда op_setlist opcode b == 0, декомпиляция не выполняется.
Решение 11. При обнаружении оператора lua, подобного следующему, инструмент декомпиляции завершится ошибкой. Ситуация находится в файле @ lib_ui.lua:
Во-вторых, существует проблема с сетлистом. Когда b == 0, это фактически означает, что значения от регистра a + 1 до вершины стека (вершины) все присвоены таблице, и декомпилятор не оценивает b == 0, плюс Вот и все. Так что измените его следующим образом:
Цикл for, добавленный StartTable, указывает, что если выполняется newtable (r 0 0), а последующая неинициализированная табличная операция перезаписывает регистр r (покрывает таблицу), это указывает, что новая таблица пуста, и в таблице нет последующей таблицы. Присвоение; если регистр r инициализируется позже, это доказывает, что новая таблица не пуста, а является таблицей переменных параметров.
Исправить двенадцать
Первая строка local a, b, c не будет декомпилирована, что приведет к различным ошибкам в следующем коде.
Когда startpc переменной равен текущему pc, количество переменных равно 0, а текущий pc равен 0, это означает, что переменная объявлена в первой строке, а добавленное else if должно разрешить эту ситуацию (это оказывается прямой ошибкой без разрешения).
подводить итоги
Вышеупомянутое сначала суммирует статьи, связанные с обратным проектированием Lua, и связанные инструменты, которые были опубликованы в последние годы, а затем объясняет противостояние между дизассемблированием и декомпиляцией Lua и использует 3 примера в качестве иллюстраций. Первый пример иллюстрирует восстановление мобильной игры Zhengtu. Второй пример восстанавливает код операции виртуальной машины lua и успешно декомпилирует lua-скрипт. Третий пример отлично исправляет большое количество ошибок при декомпиляции lua-скрипта мобильной игры мечты.
Технология шифрования и дешифрования Lua будет продолжать развиваться, но на этом статья заканчивается. Затем я могу написать подробный отчет об анализе конкурса Tencent Game Security Competition 2018 (с подробным описанием каждого байта), включая, помимо прочего, обратный инжиниринг STL, анализ алгоритма AES, анализ сценария Blueprint и т. Д. Следите за обновлениями.
Справочная статья
[1] Фей Чонг «Анализ формата файла Luac для обратного проектирования Lua» https://www.anquanke.com/post/id/87006
[2] Летающие насекомые «Байт-код Luac и дизассемблирование реверса программы Lua» https://www.anquanke.com/post/id/87262
[3] Летающие насекомые «Формат файла Luajit для обратного проектирования Lua» https://www.anquanke.com/post/id/87281
[5] Nick Cano 《Hooking LuaJIT》 https://nickcano.com/hooking-luajit
[6] Желудок вызван интересом «Посмотрите, как я атакую LuaJIT через хук» https://www.anquanke.com/post/id/86958
[7] Расшифровка lua-скрипта Ganlv 1: строка загрузки https://www.52pojie.cn/thread-694364-1-1.html
[8] unity «[Место Цзянху] Мобильная игра LUA на основе процесса модификации расшифровки HOOK» https://www.52pojie.cn/thread-682778-1-1.html
[9] Лаборатория безопасности игр «Введение в методы реверсирования и взлома игр на Lua» http://gslab.qq.com/portal.php?mod=view&aid=173
[10] INightElf «[Оригинал] Введение в первую декомпиляцию скрипта Lua» https://bbs.pediy.com/thread-186530.htm
[11] wmsuper «Счастливая расшифровка скрипта Xiaoxiaole Lua» https://www.52pojie.cn/thread-611248-1-1.html
[12] littleNA «Анализ шифрования и расшифровки Lua-скрипта мобильных игр Android» https://litna.top/2018/07/07/Analysis of the encryption and Decryption of Android Mobile Games Lua Script /
[13] «Kanxue 2016CrackMe, вопрос 2» https://ctf.pediy.com/game-fight-3.htm
[14] «Kanxue 2017CrackMe, вопрос 15» https://ctf.pediy.com/game-fight-45.htm
[15] «Конкурс технологий Tencent Game Security» https://www.52pojie.cn/forum-77-1.html
[16] luadec https://github.com/viruscamp/luadec
[17] ljd https://github.com/NightNord/ljd
[18] luajit-decomp https://github.com/bobsayshilol/luajit-decomp
(Полный текст окончен, спасибо, что прочитали)
Интеллектуальная рекомендация
Демонстрация XSS-атаки веб-безопасности
Демонстрация XSS-атаки веб-безопасности окружение: Локальный html файл, браузер IE (Google будет блокировать междоменные запросы, какие операции нужно развернуть, здесь все упрощено), фон django, база.
WF от входа к мастеру (глава 6): примеры загрузки и выгрузки (передача)
Изучив эту главу, вы освоите: 1. Поймите, почему экземпляр рабочего процесса должен быть выгружен и перезагружен, и его время 2. Понять, почему экземпляр рабочего процесса должен быть сохранен и его в.