Untrusted. Обходной путь

Я бы изменил мир, но Бог не дает исходники

В мире Untrusted исходники нам как раз дадут. Главное, что бы хватило смекалки грамотно их изменить. Суть игры в том, что надо пройти 21 локацию имея на руках ее исходный код (на JavaScript), который частично можно редактировать. Под прохождением понимается — дойти до точки выхода убив какого-то монстра / обойдя препятствия / забрав какой-то предмет и т.д.

Так как у нас мы можем изменять исходники, то появляется большое пространство для «спекуляций». Достаточно посмотреть на баг-лист с тэгом security.

Казалось бы, что большинство лазеек уже прикрыто (eval, call, prototype и т.д). Так же автор старается избавить игрока возможности использовать «_». Таким образом, часть методов должна быть недоступна игроку. Ниже представлен список «стоп-слов»:

Game.prototype.verbotenWords = [
    '._', '"_', "'_", // prevents calling _unexposed methods
    '\\u005f', '\\x5', // equivalent to '_'
    'fromCharCode', // prevents String.fromCharCode(95) => "_"
    'eval', '.call', 'call(', 'apply', 'bind', // prevents arbitrary code execution
    'prototype', // prevents messing with prototypes
    'setTimeout', 'setInterval', // requires players to use map.startTimer() instead
    'requestAnimationFrame', 'mozRequestAnimationFrame', // (more timeout-like methods)
    'webkitRequestAnimationFrame', 'setImmediate', // (more timeout-like methods)
    'prompt', 'confirm', // prevents dialogs asking for user input
    'debugger', // prevents pausing execution
    'delete', // prevents removing items
    'atob(','btoa(',//prevent bypassing checks using Base64
    'Function(', //prevent constructing arbitrary function
    'constructor', // prevents retrieval of Function using an instance of it
    'window', // prevents setting "window.[...] = map", etc.
    'document', // in particular, document.write is dangerous
    'self.', 'self[', 'top.', 'top[', 'frames',  // self === top === frames === window
    'parent', 'content', // parent === content === window in most of cases
    'validate', 'onExit', 'objective', // don't let players rewrite these methods
    'this[' // prevents this['win'+'dow'], etc.
];

Первый раз увидев этот список, я понял, что до некоторых вариантов мне б пришлось долго додумываться. Но все таки, неужели никак нельзя вытянуть символ «_»? Можно. В браузере есть много разных объектов, доступных из JavaScript. В Google Chrome есть chrome. У которого, в свою очередь, есть app с методом runningState(). В контексте игры Untrusted этот метод возвращает строку «cannot_run». Вот отсюда и возьмем нужный символ. Дальше — дело техники. Например, можно очистить карту от созданных ранее элементов:

var c = chrome.app.runningState().charAt(6);
map[c+'reset']();

Об этом способе я отписал автору — ссылка. Но лазейка будет закрыта еще не скоро.

Посмотрим, что можно сделать «обнулив» карту.

Уровень 9:

Уберем всю воду и поставим героя поближе к выходу:

var c = chrome.app.runningState().charAt(6);
map[c+'reset']();
map.defineObject('raft', {});
map.placePlayer(1, 4);
map.placeObject(1, 2, 'raft');
map.placeObject(1, 3, 'exit');

Объект рафт должен быть определен и на карте должнен присутствовать один его экземпляр.

Уровень 16:

Во второй блок для редактирования пишем:

var c = chrome.app.runningState().charAt(6);
map[c+'reset']();
for (var i = 0; i < 25; i++) {map.createLine([0,0],[1,1],function(){})}
map.placePlayer(1, 4);
map.placeObject(1, 3, 'exit');

Все исходные лазеры убраны, но, так как есть проверка на их количество, дорисовываем свои как захотим. Ну и размещаем персонажа и выход рядом.

Уровень 21:

var c = chrome.app.runningState().charAt(6);
map[c+'reset']();
map.placePlayer(1, 4);
map.overrideKey('rest', function() {
    	map.placeObject(1, 1, 'exit');
        map.placeObject(1, 2, 'theAlgorithm');
	map.placeObject(1, 3, 'phone');
});

Из уровня с кучей агресивно настроенных мобов, получился уровень, где нужно нажать кнопку «R» и стрелку «up» три раза.

Разумеется, у всех уровней есть честное прохождение: 9 — создать синомим типа рафт и сделать несколько его экземпляров, 16 — переопределить функцию getRandomInt, 21 — создание ряда динамических объектов, которые уничтожают другие динамические объекты при соприкосновении.

Однако, куда интереснее было найти именно «обходной» путь.

, ,

1 comment
  1. b82a Said:

    Какое разное мышление. На 9 уровне я плотину вверх пустил, после того как сел, а «обнулить» карту вообще не приходило в голову. Забавная игра.

Оставить комментарий

Top ↑ | Main page | Back