17 часов назадКартинки можно дополнить текстом.
http://www.chemometrics.ru/materials/textbooks/matrix.htm
2 дня назадМы были на прошлой неделе в Белоруссии проездом, было очень холодно: ночью в Гомеле -32 %) Спасибо за приглашение, у меня есть сильное желание приехать и послушать доклады, интересные темы, но всё же в следующий раз, когда будет потеплее ;)
5 дней назадНаконец нашел что-то путное по теме. Начну разжевывать. Несколько дней уйдет, однако.
1 неделя назадМне пришлось столкнуться с тем, что элементарно не работает комбинация клавиш Ctrl + C и Ctrl + V. Причем переустанавливали Flash и не раз. Может быть, есть здесь те, кто сталкивался с этой проблемой и как-то смог решить ее?
1 неделя назадХотелось бы узнать, Как вы относитесь к пиву? Если положительно, то какое предпочитаете? Если отрицательно, то почему? Просто интересно...
В данной статье я хочу покуситься на самое святое, что у нас есть: на сам Flash Player.
Факт 1: иногда встроенные классы Флеша имеют забавные приколы, например самопроизвольный вызов load в конструкторе класса Sound, или жёсткий глюк в ExternalInterface, о котором я расскажу ниже.
Факт 2: глюки бесят, и иногда хочется узнать, из-за чего они происходят, или заранее знать, где спрятаны грабли.
Факт 3: ABC-код довольно легко декомпилируется.
Предположение: Далеко не все методы встроенных классов FP являются нативными, некоторые из них возможно написаны на нашем родном AS3 (точнее на ABC-коде).
Старожилы наверняка помнят исходники стандартных классов для разных версий флеш-плеера вплоть до 8-го. Отсюда и возникло предположение, что и в версиях 9 и 10 тоже должно быть хоть что-то ненативное.
Предположение оказалось верным, а это значит, что Флэш можно потрошить.
Подробнее - под катом.
Во-первых, о морально-этических и юридических аспектах сего действия. Декомпиляция, как известно - это ай-яй-яй. Хотя, если декомпиляция выполняется для достижения взаимодействия с другой программой, то можно. Следовательно, если я хочу наладить взаимодействие моей флеш-игры с флеш-плеером, то я чист перед законом (и российским, и украинским, и международным).
Во-вторых, что меня вообще сподвигло на данный кулхацкерский шаг? Ну, в том числе элементарное любопытство, не без этого, но главной причиной стала пренеприятнейшая проблема: при попытке отправить ByteArray через ExternalInterface я получал исключение Coercion error где-то в кишках ExternalInterface. Захотелось взять скальпель и в эти кишки заглянуть.
В-третьих, сразу хочу заметить, что (возможно) есть более простой способ добиться примерно того же результата, например просто взять playerglobal.swc и декомпилять его, но такой вариант слишком поздно пришёл мне в голову - когда всё уже было сделано, и кроме того я столкнулся с рядом трудностей, так что результаты были менее впечатляющие: не все классы удалось вытянуть. Так что если у вас получилось - прекрасно, расскажите, как сделали. А я расскажу про свой извращенский способ.
Берём флеш-плеер в любом виде. Например, Stand Alone плеер или flash.ocx. Лучше сделать копию файла и работать с ней.
Где-то внутри него должен быть кусок ABC-кода. Как оказалось, в 9-м плеере их даже не один, а целых два. В одном находятся совсем базовые классы типа Object, Array, Math, а в другом - уже более флешовые: например, пакет flash.display и всё в таком роде.
Найти, где начинаются эти фрагменты, довольно просто: каждый ABC-код начинается с магической последовательности: 10 00 2E 00.
Можно искать её с помощью любого hex-редактора.
Правда, могут попадаться и "обманки" - ведь эта последовательность может встретиться и просто так. Отличать их просто - если вскоре после последовательности начинаются до боли знакомые названия, значит это оно. Если же там всякое бинарное непотребство, значит ищем дальше.
Когда нашли, где начинается байт-код, можно смело вырезать из файла всё, что предшествует магической строке.
У нас получается файл, начинающийся с 10 00 2E 00 - то есть почти готовый abc-файл. Единственная проблема - в нём всё ещё много мусора: голову-то отрезали, а хвост остался. К сожалению, вот так сразу определить, где кончается ABC-код нельзя - информация о длине блока не хранится.
Я поступил так: модифицировал известную многим утилитку abcdump (благо она опенсорсная и написана на православном языке), чтобы она входной файл парсила-парсила-парсила, а когда до конца распарсила, смотрела, где остановилась и сохраняла в отдельный файл ровно тот кусок файла, который ей потребовался.
В результате такой дистилляции получался чистейший экстракт abc-кода.
Напомню, что фрагментов abc-кода в флеш-плеере как минимум два, так что придётся повторить эту операцию.
Одна проблемка. У меня не было под рукой декомпилятора, который бы умел работать с abc-файлами. Ну, кроме того же самого abcdump, но это не декомпилятор, а дизассемблер, и получаемый им текст довольно трудночитаемый.
Поэтому пришлось делать следующий шаг.
Итак, декомпиляторы (по крайней мере имеющийся у меня Sothink SWF Decompiler) не любят чистые abc-файлы, им подавай обязательно swf.
Единственный способ, который пришёл мне в голову (но наверняка не единственный из существующих) - это создать суррогатную SWF с каким-нибудь произвольным коротким кодом (например, тупо stop(); ) и пересадить в неё мой abc-код.
Это было самой геморройной задачей. Дело в том, что в SWF-то как раз длины указываются сплошь и рядом, поэтому вот так просто всунуть что-то другого размера нельзя - надо обязательно подкорректировать длины. Во-первых, длину файла (с 5-го по 8 байт), во-вторых, длину тега (которая может быть где угодно).
Разумеется, работать лучше с некомпрессированной SWFкой.
Всё сделать правильно сделать получилось не сразу, сперва флешка постоянно получалась инвалидной. Однако после длительных мучений (во время которых я ощущал себя средневековым алхимиком), мой гомункул наконец ожил.
Оставался последний элементарный шаг - отдать его на съедение декомпилятору - и вуаля! - тот радостно наштамповал мне ИСХОДНИКИ ФЛЭШ ПЛЕЕРА.
Исходники, конечно, всё равно получились не очень красивые - с кучей нативных функций, с плохими отступами и некрасивыми названиями локальных переменных, а порой и вовсе с какими-то некомпилируемыми выражениями, но для созерцания и поиска истины - достаточно интересные.
И я таки нашёл, в чём же причина глюка с ExternalInterface.
В методе _toXML (очень приватном и статическом, то есть вообще никак не переопределяемом) есть такой замечательный пример индокода:
if (param1.hasOwnProperty("length")) {
return _arrayToXML(param1);
}
Царский указъ: отныне со всяким, кто длиной владеет, поступать аки с массивом.
private static function _arrayToXML(param1:Array) : String
Только вот не всякий объект, имеющий свойство length, совместим с типом Array.
Например, ByteArray не совместим. Coercion Error.
И да, конструктор класса Sound выглядит так:
public function Sound(param1:URLRequest = null, param2:SoundLoaderContext = null) {
load(param1, param2);
}
Но метод load хотя бы публичный, а значит можно переопределить.
Наверняка есть более простой способ добиться того же самого результата. Буду рад услышать ваши варианты.
Наверняка кто-то вообще не видит смысла в полученных результатах. Ваше право.
Наверняка кто-то захочет, чтобы я выложил готовые исходники. Извините, но тут уже могут быть тёрки с законом, я и так рассказал слишком много.
Но в любом случае, рассчитываю на обратную связь.

Комментарии
Браво!
ну, да, переименуй playerglobal.swc в playerglobal.zip и достань оттуда library.swf... кстати, прикольно посмотреть на получившийся swf, выложи где-нить (он же не исходники).
кстати, прикольно посмотреть на получившийся swf, выложи где-нить (он же не исходники).
О, а это идея.
Правда выполнял я эти манипуляции давно, ещё с 9-м плеером. Так что данные немного устарели, а найти в себе силы на повторение всего этого с новой версией всё никак не могу.
Но чуть попозже выложу swfки от 9-го плеера.
кстати, было бы интересно пропатчить АВС в самом плеере по принципу private->public
я бы себе такой поставил
Индусы - такие индусы
и вот поправить же 5 минут, но поправят через 10005000!!
Расскажы по секрету как из swf cделать swz?
Расскажы по секрету как из swf cделать swz?
Мне кажется, это близко к невозможному. Надо знать секретную часть ключа адобовцев.
В плеере только публичная часть, до и то искать её замучаешься.
Конечно молодец. Но, тут говорят, что сорцы плеера и ас3 как бы открыты.
Во-вторых, 10 00 2E 00 — это версия 10.46 abc. В-третьих в SWF все логично и длину тебе нужно было написать в двух местах — длина самого SWFа и длина тэга DoABC
пруфлинк?
например http://hg.mozilla.org/tamarin-central/file/072e85a58498/core (via @blooddy)
поищи тут
Но, тут говорят, что сорцы плеера и ас3 как бы открыты.
Сорцы плеера открыты только избранным.
Сорцы AVM2 открыты всем подряд, но там нет флешовых классов. Есть только базовые: Object, Array, XML и т.д.
Хорошая статья. А может выложишь все что удалось декомпильнуть? или хотя бы по ExternalInterface?
Круто! Спасибо!
Нереально жжешь! Спасибо!
А чем ты компилировал модифицированную abcdump ?
java -jar flexsdk\lib\asc.jar -exe avmshell.exe -import builtin.abc -import shell_toplevel.abc abcdump.as
flexsdk замени на путь до Flex SDK
Необходимые файл: avmshell.exe, builtin.abc и shell_toplevel.abc можно взять тут:
- стабильный билд: ftp://ftp.mozilla.org/pub/js/tamarin/builds/milestones/tamarin-central-03/
- распоследний билд: ftp://ftp.mozilla.org/pub/js/tamarin/builds/tamarin-redux/3902-cac47117e...
хм... ASV + cmd = код плеера. Можно было сделать в одну строку консоли*:
cd $asv -$home/flex4sdk_b2/frameworks/libs/player/10/playerglobal.swc
* $asv и $home - переменные сис-мы. ASV = ActioscriptViewer
Большая работа проделана, можешь запостить в адобу как им поправить багу ) Если серьезно, то я бы глянул на весь исходник. Просто интересно, как в адобе умудряются так черезжопно код писать))
Гуглить
docsultant Nemo440
format.abc HaXe
HXswfML googlecode
- все дано уже сделано до нас и подано на блюдечке с голубой каемочкой...
Всё уже давно сделано и до нас и до них
Nemo440 использует код abcdump.
hxswfml - это порт swfmill на HaXe
Штуки, безусловно, полезные, но на декомпиляторы не тянут.
Вот я б хотел на ASV 6 посмотреть хоть одним глазком.
ну так это, заплати и будешь двумя смотреть
Прежде, чем платить, хочется таки посмотреть
значит надо бурака убедить залить скринкаст. а то demoversion у них суперстар.
Бесспорно (в том что касается HXswfML - не совсем, но не суть важно). Только вроде нужен был не декомпилятор, а что-нибудь ABC файл прочитать + интерфейс? Или я не правильно понял:
Наверняка есть более простой способ добиться того же самого результата. Буду рад услышать ваши варианты.
?
Хотелось из abc получить код на as3.
Спасибо за статью.

1. Получение подобного результата действительно возможно с помощью tamarin и его abcdump.as (1.5K строк кода - разобраться можно)
2. Вариант playerglobal.swc->playerglobal.zip->library.swf + декомпилер тоже работает практически всегда
3. В плане поглядеть на нативные функции/классы интерес есть. Пример: Поинт и Матрикс - это обычные ас классы, посему выигрыша в производительности ну никак не дают (можно менять спокойно и на свои, более оптимизированные под задачу), Матрикс3Д уже имеет нативные функции, следовательно и побыстрее работает. Интересны Эррей, Вектор и Стринг - какие функции в нативе (следовательно быстрее) реализованы.
Так что в целом мозги прочищает в плане оптимизации
4. Кому не хочется наступать на "рамки закона" или облом копаться в свф, можно обратиться к tamarin (ссылки на проект выше). Там базовые классы core языка присутствуют в as формате.
5. Для желающих поэксперементировать с оптимизацией, доступом к памяти и т.п. в tamarin есть abcasm - вменяемый ассемблер.
Хм... я лентяй видать - asv6 и дело в шляпе
Прикольно, всегда ставил проверку в Sound.load, на отсутствие запроса, поэтому наверно и не парился. А по поводу ExternalInterface, у них такая же логика/херня висит и в JavaScript коде, который оборачивает данные в XML перед отправкой во flash.