- PVSM.RU - https://www.pvsm.ru -

История реверс-инжиниринга одного пушистого зверька

История реверс инжиниринга одного пушистого зверька

Тихим утром третьего января, когда Москва уже дремала после новогодних праздников, в нашей квартире раздался звонок в дверь. Почта наконец-то доставила посылку с новогодними подарками, заказанными на Амазоне. Среди прочего в ней находился и подарок для сына — электронный питомец Furby [1]. Покупка его была, в общем-то импульсной. Игрушка значилась в бестселлерах новогоднего сезона и стоила относительно недорого. В сортах Furby я не разбирался, но когда-то давно что-то позитивное об игрушке слышал.

Сынишку, в силу его годовалого возраста, подарок не сильно впечатлил, а позволять бросать сложное электронное устройство на пол и отрывать этому устройству уши мне было жалко, и все шло к тому, чтобы убрать подарок на полку до лучших времен, однако мой взгляд пал на одну надпись на красочной упаковке...

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

Неужели распознавание аудио работает в наше время так надежно и даже в довольно шумной обстановке? Что-то тут не так. И как приложение передает команды Furby? ИК отпадает (ранние версии Furby, как выяснилось, имели ИК-порт для общения между собой), Bluetooth тоже. Остается только аудио. Это интересно… Вот если бы удалось хакнуть протокол общения с этим созданием и уметь управлять им с компьютера… Найти какие-то «пасхальные яйца», скрытые или сервисные команды! Или…

В общем, как вы поняли, отец семейства сделал себе на Новый Год подарок.

***

Для начала синхронизировал iPhone с компьютером и заглянул внутрь файла приложения (.ipa). Среди прочей требухи там нашлось несколько десятков коротких WAV-файлов, пронумерованных особым образом. Все это очень смахивало на готовые аудиокоманды. Первый файл начинался с номера 350. После воспроизведения этого файла в Audacity Furby чего-то деловито пожевал и выдал радостное «Mmm, yum!». «Ага!» — подумал Штирлиц, — «Теперь-то ты у меня наешься!».

Команды в приложении начинались с 350-й и заканчивались 900-й, с большими пробелами в нумерации. Значит потенциально Furby умеет воспринимать гораздо большее число команд, чем есть на руках этих готовых WAV-файлов. Надо искать дальше.

Внешний вид сигнала в Audacity наводил на мысль, что используется какая-то частотная модуляция, причем шел один сигнал, дальше небольшая пауза, затем визуально такой же сигнал снова. Общая продолжительность — полторы секунды. Раз модуляция частотная, то неплохо бы взглянуть на спектр. Посмотрел график — на нем отчетливо выделялось пять пиков на одинаковых расстояниях друг от друга в районе 16-19КГц:

История реверс инжиниринга одного пушистого зверька

Башня из Мордора — это, конечно, красиво, но как это расшифровать? Покопался в Audacity еще немного и отрыл режим отображения аудио в виде спектрограммы. Вот эта картинка уже была гораздо красивее первой:

История реверс инжиниринга одного пушистого зверька

Здесь отчетливо видны две посылки с паузой посередине, отличающиеся друг от друга порядком следования «нот» (базовых частот). Причем средняя частота является несущей, постоянно чередуясь с другими четырьмя «нотами».

Для удобства декодирования последовательности сделал в графическом редакторе маску, которую наложил поверх скриншота спектрограммы, присвоил каждой ноте последовательно числа от 0 до 3 и начал анализировать последовательно идущие команды (как мы помним, разработчики iOS-приложения услужливо пронумеровали нам все WAV-файлы). Поначалу оказалось, что в соседних командах числа иногда «прыгают», т.е. идут не так, как хотелось бы при последовательном инкрементировании чисел. После некоторого анализа стало понятно, что «ноты» надо нумеровать так, как на рисунке ниже:

История реверс инжиниринга одного пушистого зверька

Здесь посылка расшифровывается как 3233 3012 1032 (для удобства восприятия я разбил последовательности на блоки по четыре цифры; в четверичной системе каждый такой блок — это один байт).

Дальнейший анализ команд, перевод их бинарную форму и побитовое сравнение выявило следующую структуру посылки и команды в целом:

  1. Первый байт (в примере это 3233), будучи записанным в бинарном виде, имеет следующую структуру: 11 1 01111, где старшие два бита всегда равны 11, следующий бит равен 0 для первой посылки в команде и 1 для второй, а 01111 — это сами данные (часть идентификатора команды);
  2. Второй байт (3012) — контрольная сумма, зависящая от 6 бит команды (где 1 бит — идентификатор посылки и 5 бит — сами данные);
  3. Третий и заключительный бит посылки всегда равен 1032.

Что это значит? Во-первых, команда разбивается на два пакета по 5 бит данных в каждом. В сумме мы получаем 10-битное число, т.е. потенциальное число команд, которые может посылать или принимать Furby — 1024. Однако метод вычисления контрольной суммы вычислить не удалось. Проанализировав номера команд получилось, что я могу на основе имеющихся WAV-файлов найти 7 из 32 контрольных сумм для первой посылки и 31 из 32 контрольных сумм для второй посылки. В сумме это давало 217 потенциальных команд вместо имеющихся 76 (в виде готовых WAV-файлов), что тоже неплохо.

Написал скрипт, который генерировал по нужному номеру команды WAV-файл, подобный готовому, и начал перебирать доступные мне диапазоны команд. Как оказалось, недокументированные команды действительно были — Furby реагировал на них разным образом, пел песенки, читал рэп, чихал, имитировал сон и делал прочие незамысловатые вещи.

Это подстегнуло исследовательский аппетит, однако алгоритм вычисления контрольной суммы реверс-инжинирингу упорно не поддавался, а значит большая часть команд оставалась для меня недоступной.

В очередной раз прочесывая Интернет на предмет каких-нибудь зацепок я вдруг обнаружил ссылку на официальное приложение Furby для Android (про которое на коробке с игрушкой не было ни слова). «Android → Java → байт-код → исходники → … → ПРОФИТ!». Никогда еще Штирлиц не был так близок к разгадке…

***

Найдя наконец на какой-то помойке нужный мне .apk-файл, я залез внутрь и не увидел ни одного WAV-файла с командами, хотя в целом набор ресурсов был похож на тот, что в приложении для iOS. Раз WAV-файлов нет, то приложение как-то генерит команды на лету? Это то, что мне нужно! Декомпиляция и просмотр Java-кода дал несколько интересных зацепок, но как оказалось, вся интересная начинка, а именно генерация и анализ аудио, находится внутри нативной .so-библиотеки, в которой есть один метод, который мне был нужен, а именно private static native byte[] GenerateComAirCommand(int paramInt);.

Как же достучаться до нативного метода? Пораскинув мозгами, Штирлиц решил качать Android SDK. В итоге был собран маленький проект, в который включена сама нативная библиотека и минимальная обвязка, предоставляющая доступ к одной только нужной мне функции. Само же приложение при старте просто создавало WAV-файлы для минимально необходимого мне набора WAV-файлов, где в командах были те самые недостающие старшие и младшие 5 бит, для которых мне были нужны контрольные суммы. После некоторого курения Stack Overflow (опыта написания приложений под Android у меня на тот момент не было) приложение запустилось и сгенерировало мне на виртуальной SD-карте эмулятора набор нужных мне WAV-файлов, которые я перетащил через adb pull в нормальную файловую систему. Анализ этих файлов дал мне полное покрытие — все 64 контрольных суммы, по которым можно воссоздать любую из 1024 команд.

В ходе анализа реакций Furby на команды был найден еще один диапазон команд, на который Furby так или иначе реагировал. Однако каких-то атомарных команд типа «открой глаза», «закрой глаза», «пошевели ушами» обнаружено не было. Равно как и не была найдено команд самоуничтожения или зачитывания EULA на фурбише (это не значит, что каких-то специализированы команд нет, просто они могут активироваться, например, особой последовательностью или вообще другим набором кодов — но это как-то выяснить вряд ли возможно).

***

Однако я решил пойти дальше и написать анализатор ответов Furby, так как некоторые команды, хотя и не дают видимого результата, могут вызывать реакцию Furby в виде ответных команд, что тоже интересно. В итоге был написан Perl-скрипт, анализирующий поток PCM-данных с микрофона, делающий на лету и расшифровывающий эти посылки. Писалось все это под Windows, где для Perl, к сожалению, нету нормальных способов записи данных с микрофона, поэтому пришлось сделать консольную программу на Delphi, которая читает с микрофона данные и выводит их непрерывно в STDOUT. Поток данных перенаправляется в скрипт, где уже происходит анализ. Такой вот Unix way для Windows.

«Стоп, стоп, стоп,» — скажет утомленный читатель, — «А для чего все это нужно?»

Мне было интересно посмотреть, «что у него внутри», не ломая игрушку физически (все-таки покупал не себе). Попутно получил знания о генерации и анализе звука в Perl, о FFT, оконных функциях, о работе с Android, что само по себе увлекательно.

Возможно кому-то данная статья пригодится при реализации собственного протокола, есть ведь всякие интересные примочки для iPhone [2], передающие данные как раз через аудиоразъем.

Ну и, наконец, возможность управлять Furby через компьютер потенциально открывает эмоциональный метод нотификации о каких-то событиях. Например, при приходе почты от определенного адресата можно попросить Furby что-то станцевать, по приходу коммита в Git от определенного человека — помурлыкать, а от другого — издать звук менее приличный (коих у Furby есть в запасе). Правда для этого все же нужно решить уже парочку задач хардверных. Во-первых, запретить Furby засыпать через 10 минут неактивности (а активностью считается физическое тормошение — для этого у него имеется датчик положения в пространстве) и питать его не от батареек, а от блока питания или USB. Может быть на Хабре есть знатоки железа, которые захотят окончательно укротить зверька?

Сам код после некоторого причесывания выложен на GitHub [3]. Пожелания и находки всячески приветствуются. Разумеется, вся изложенная информация и программный код предоставлен исключительно в образовательных целях.

Oo-tah-toh-toh. Kah way-loh.

Автор: afan

Источник [4]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/delphi/25234

Ссылки в тексте:

[1] Furby: http://www.amazon.com/s/?field-keywords=furby

[2] примочки для iPhone: https://squareup.com/

[3] выложен на GitHub: https://github.com/iafan/Hacksby

[4] Источник: http://habrahabr.ru/post/166377/