Говорят, что, если бы в JavaScript нормально работал garbage collector, весь код улетал бы в треш сразу после написания. У этого языка и впрямь миллионы преданных хейтеров, но тем не менее его продолжают активно использовать. Например, корпорация Adobe — когда создает расширения и дополнения для собственных продуктов. А то, что однажды было создано, при желании может быть сломано или пропатчено. Об этом увлекательном процессе мы сегодня и поговорим.

Практически каждая современная адобовская программа использует три вида дополнительных модулей: плагины (plugins), расширения (extensions) и скрипты. Для создания таких модулей используется JavaScript, и, чтобы порадовать программистов, в Adobe придумали собственную среду разработки под названием ExtendScript Toolkit c блек-джеком, объектными моделями, отладчиком и даже примитивным компилятором в бинарный код.

Да-да, чувак, ты не ослышался: я сказал «бинарный код». Несмотря на то что JavaScript — это интерпретируемый язык, программы на котором представляют собой обычный pain text, такой эксгибиционизм по вкусу далеко не всем. Жадные коммерсы хотят защитить свой код от чужих глаз и шаловливых рук. Именно для подобных разработчиков Adobe создала свой собственный уникальный и почти бинарный формат скрипта — jsxbin. Для его создания даже не требуется никакой дополнительный компилятор, достаточно в диалоге сохранения кода в ESTK указать не текстовый формат .jsx, а бинарный .jsxbin.

Словосочетание «почти бинарный» тут присутствует неслучайно. Он, строго говоря, не бинарный в общепринятом смысле этого слова, ибо набор символов, который в нем используется, — базовый текстовый, даже без спецсимволов, что позволяет вставлять такой «бинарный» код в текст обычных скриптов. Тем не менее это реально компилированный синтаксический псевдокод, восстановить исходный текст из которого — задача весьма неоднозначная и нетривиальная. Этот фарш сложно провернуть назад.

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

Я не собираюсь углубляться в бездонные пучины унылого кодинга. Наша цель несколько другая: научиться без лишнего погружения в сухую теорию быстро и просто вносить исправления в псевдокод адобовских расширений.

Конечно, в идеальном случае было бы лучше полностью реверсировать исходный код один в один и вносить изменения именно в него. Причем к этому есть вполне определенные предпосылки: несмотря на недокументированность формата, существует несколько вполне хороших, годных декомпиляторов разной степени удобства и функциональности. Не буду приводить ссылки на них по этическим соображениям, но пару названий укажу: это jsxbindec и jsxbin-to-jsx. Причем последний представлен даже в свободных исходниках, изучая которые дотошный и неленивый читатель может получить исчерпывающее представление о принципах компиляции формата jsxbin.

Хорошо, если нужный код отлично декомпилируется, а полученный результат запускается и работает идентично исходному плагину. Однако такое случается редко. Декомпиляторы неидеальны, а их присутствие в свободном доступе дает полный простор авторам-обфускаторам выдумывать всевозможные ловушки, сводящие декомпилятор с ума. Да и вообще, поскольку преобразование jsx -> jsxbin — это все-таки компиляция, оно не всегда однозначно обратимо. На практике это чаще всего выглядит так: jsxbin успешно декомпилируется в несколько мегабайтов кода, который в лучшем случае выдает синтаксические ошибки (их потом придется кропотливо и уныло фиксить), а в худшем — вызывает ошибки времени выполнения вида

Error 21: is not an object. Line: 3164 -> _0x20031 += ((parseInt(_0x1FFFD[_$_f79d[178]](_0x1f435)

Понятное дело, результат подобной декомпиляции потребуется сильно допилить напильником до полной работоспособности, причем, к сожалению, понадобится вникать в логику работы и построения программы. Что частенько сложнее, чем писать ее с нуля. Мы же, повторяю, люди занятые, ленивые и нелюбопытные. Нам бы поправить пару строчек, чтоб работало и остальное не поломалось.

Итак, сформулируем задачу. Предположим, исходный код определенной степени достоверности получен, проанализирован, искомое место найдено. Нам нужно сделать патч в бинарном коде без ущерба для работоспособности в целом. Например, мы нашли в декомпилированном коде конструкцию вида _isDemo=true, а нам надо заменить ее _isDemo=false без полной переcборки исходника.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Оставить мнение