RS Game Maker Community
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

 
Расширенный поиск
  Главная  Форум   Вики Блоги FAQ Игры Статьи Примеры Войти Регистрация  
Вики
Все желающие приглашаются редактировать вики. Можете писать о своих (или чужих) играх, размещать туториалы, постить статьи - главное навесить категорию.
Страниц: 1   Вниз
  Печать  
Декомпилятор для GameMaker:Studio
0 Пользователей и 1 Гость смотрят эту тему.
input.txt
Не очень
Активный участник
**

Репутация: 17
Online Online

Сообщений: 116


12.8 Gb

18 Июня 2017 в 15:10
В старые времена GML был интерпретируемым языком, и код хранился в исполняемом файле чуть ли не с комментариями, так что "декомпилятор" было написать крайне легко. С выходом GM:S хорошие времена для мамкиных хакеров закончились – теперь YoYoGames встроили в исполняемый файл виртуальную машину собственного изобретения и GML компилируется в байт-код для неё. При этом формат байт-кода и файла периодически заботливо меняют.
Насколько мне известно, на данный момент для GM:S не существует инструментов для декомпиляции. Есть конечно распаковщики ресурсов (типа Altar.NET), но они не производят никакого анализа и уж точно не генерируют код на GML. Таким образом, мой проект предназначен для того, чтобы закрыть эту нишу.

Итак, я сотворил прототип декомпилятора на С++. Все желающие могут скачать его с репозитория и оценить, как он не работает. Для удобства я также подготовил архив с тестовым проектом, на котором декомпилятор точно не падает.

Текущие возможности
Сейчас декомпилятор может восстанавливать следующие конструкции:
  • if, if-else
  • while, for, repeat-until do-until (for превращается в эквивалентный while)
  • Арифметические выражения любой сложности, с операторами разного приоритета и вложенными скобками. Иногда код после декомпиляции выглядит лучше исходного
  • Аналогично, логические выражения (отдельный пункт, т.к. они представлены совершенно другим образом)
  • Вызовы функций (в смысле скриптов) с любым количеством аргументов.
  • +=, -=, *=, /=, …
  • Массивы, в том числе двумерные.
  • Обращение к полям объектов.
Все перечисленное может иметь любую сложность и глубину вложенности (a.b.c[d.e || true, f.g.h && s[t, u && v]] = s || x && --lol; ^_^)

Работа над проектом будет продолжаться, пока GMS2 не выйдет из беты. Так что даже есть шансы, что он будет закончен.
Последнее редактирование: 19 Июня 2017 в 12:43 от input.txt
 
tolich
to ne lich
Ветеран форума
*****

Репутация: 214
Offline Offline

Сообщений: 1 486


moonlite

Ответ № 1 19 Июня 2017 в 10:05
Что за repeat-until? Испокон веку было do-until.

input.txt
Не очень
Активный участник
**

Репутация: 17
Online Online

Сообщений: 116


12.8 Gb

Ответ № 2 19 Июня 2017 в 12:51
Do, конечно. Это я, видимо, с Lua его перепутал.
В любом случае, сейчас перепроверил - он тоже нормально восстанавливается.
Огион
Завсегдатай
****

Репутация: 131
Offline Offline

Сообщений: 957


Ответ № 3 20 Июня 2017 в 12:33
Круто.
Есть какая-нибудь интересная инфа о внутренней работе GM, которая может быть полезна простому разработчику?
input.txt
Не очень
Активный участник
**

Репутация: 17
Online Online

Сообщений: 116


12.8 Gb

Ответ № 4 20 Июня 2017 в 23:04
Подборка интересных фактов:
  • Аксессоры – это на самом деле функции, и их можно даже вызвать напрямую.
    a = list[| i ];<=>   ds_list_find_value( list, i );
    list[| i ] = a;<=>   ds_list_set( list, i, a );
    a = map[? key ];<=>   ds_map_find_value( map, key );
    map[? key ] = a;<=>   ds_map_set( map, key, a );
    a = arr[@ i ];<=>   array_get( arr, i );
    arr[@ i ] = a;<=>   array_set( arr, i, a );
    a = grid[# i, j ];<=>   ds_grid_get( grid, i, j );
    grid[# i, j ] = a;<=>   ds_grid_set( grid, i, j, a );

    Это может упростить работу со вложенными массивами
    inner[5] = "Hello";
    arr[1] = inner;

    // show_message( arr[1][5] );   // ERROR
    show_message( array_get( arr[1], 5 ) );   // "Hello"

    Так же, как и функции, не проверяют тип аргумента. Хотя его вообще нельзя проверить, потому что id структуры это просто число, так еще и для каждого типа отдельная нумерация.
    var map = ds_map_create();
    map[? 13 ] = "map";

    var list = ds_list_create();
    list[| 13 ] = "list";

    show_message( map[? 13 ] );  // "map"
    show_message( list[| 13 ] ); // "list"
    show_message( map[| 13 ] );  // "list" !!!
    show_message( list[? 13 ] ); // "map"  !!!
  • Двумерные массивы можно использовать как одномерные с размером до 32000*32000 = 1024000000.
    i = 5;
    j = 2;
    a[i, j] = 42;
    // a[i, j] == a[i*32000 + j] == a[5*32000 + 2] == a[160002] == 42;
    for( var i = 0; i < 1000000; ++i ) {
        a[i] = i + 1;
    }
    show_message( a[65535] ); // 65536
Последнее редактирование: 20 Июня 2017 в 23:16 от input.txt
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

RSGMC (gmakers.ru) © 2007—2017
Счётчик–@Mail.ru