Wednesday, August 5, 2015

Step tracker

Достоинства открытого протокола для мелкой электроники и в частности трекеров шагов, можно не заморачиваться с приложениями пользователи с конспиративными наклонностями(из фонда fsf.org) сами напишут приложении и построят, если нужно графики и тому подобное. Пользователи более или менее довольны, что могут сами проверить: что отправляется и принимается и если что: сами осуществить поддержку устаревших в каком-то плане устройств. Можно если что добавить поддержку этих устройств на новых платформах. Но возникает проблема в цене, если протокол доступен пользователь может уйти от идеи материальной поддержки производителя или его сервисов, он же сам может все сделать. Также конкуренты могут сделать дешевле или добавить в свое устройство поддержку вашего сервиса и не вкладывать деньги в поддержку сервиса, и вы будете осуществлять его своим и чужим. А он будет только клепать устройства. Поэтому возникает достаточно сложная задача в каком объёме будет окупаться ваш продукт, в цену будет вкладываться разработка устройства, производство и сервисные услуги, такие как сообщества пользователей устройства и страница рейтингов пользователей, если это игра или подразумевается какой-то вид вовлечения в сообщество под средством игры(кто быстрее ходит, сбрасывает вес, бывает в новых местах). Причем последний пункт может быть сразу вложен в цену продукта так и быть оплачен отдельно через платную поддержку.

И так история разбора протокола одного трекера....

При этом не использовались методы обратного инжинеринга, подобного декомпиляции программного или аппаратного продуктов. Все данные получены через наблюдение данных отображаемых устройством и передаваемых через usb шину. Замечалось что на экране показывается и какие пакеты идут с устройства к программе и уточнялись примерно по показаниям программы особенности данных, такие как примерное распределение значений данных и предположения как можно было реализовать с нуля и как можно хранить эти данные. Как результат единственно используемое средство это слежение за трафиком и просмотр общедоступных данных отображенных на устройстве и статистика на сервере.
Общая структура системы была такова: устройство в виде ремешка с экраном на котором отображались количество шагов, расстояние пройденное за день и потраченные килокалории. В полночь карета превращалась в тыкву и все значения на экране обнулялись. Связь с внешним миром у устройства была только через usb, есть другие версии устройств с Bluetooth, но у меня было только подобное.
Существовали различные приложения для этого устройства:
  1. Приложение под мобильную платформы, через otg на android не заработало, так как не видело устройства. Содержало не очень приятную особенность, получало почти все возможные разрешения, зачем оно ему нужно, не знаю. 
  2. Под iphone не проверял так как такого в наличии у меня не было, сказать ничего не могу. 
  3. Поэтому осталось только приложение под windows. К сожалению именно так под линукс не было, но на результат это впрочем не влияло. Поэтому пришлось скачать альфа версию десятки и поставить на виртуалку. Приложение выполняло роль посредника вычитывало данные с трекера и синхронизировало их с сайтом. И содержало ссылку на сайт, где можно было просмотреть эти данные.
Для того чтобы дамп стал возможен нужно добавить своего пользователя в группу (vboxusers для debian), которая дает virtualbox захватывать на себя usb устройства по фильтру. Поэтому нужно уточнить тип устройства с которого будем снимать трафик и внести его в список устройств которые нужно пробросить в виртуальную машину и добавить себя в группу. После этого устанавливаем windows и программу обслуживания трекера. После этого нужно начать вычитывать данные с файла в который сохраняется весь трафик с шины.
Для сохранение трафика устройства ищем свое устройство в /sys/kernel/debug/usb/devices или lsusb, в моем случае это был преобразователь последовательного порта в usb именно так оно отображалось в системе, обращаем внимание только на номер шины, так как мы будем сохранять все пакеты на шине (должно быть что-то подобное Bus=04) и запускаем сохранение этих данных вычитывая /sys/kernel/debug/usb/usbmon/4u, перед этим вызывать modprobe usbmon. Или через tcpdump -i usbmon4 -w usblog.pcap как уж будет удобнее. Я выбрал первое.
После этого я начал анализировать пакеты, которые идут устройству и выявил, что общение всегда начинается похожего на статусный пакет, в ответ на который всегда возвращается номер трекера и еще пара байт, которая до сих пор непонятно для чего предназначена.
Следующим шагом нужно было понять, с какими параметрами происходит соединение, по сохраненному трафику это было не понятно, так как средство, которое я использовал для визуализации, не содержало фильтров для подобного трафика. Поэтому проверил набор стандартных скоростей и характеристик потоков и одна из скоростей подошла. Если бы не подошла, то пришлось бы все же посмотреть на код драйверов для этого преобразователя чтобы расшифровать технический трафик.
Попробовав отправить наш статусный пакет трекеру, и получив тот же самый ответ, что и в нашем трафике - я понял, что на верном пути, параметры связи совпали и можно пробовать следующие пакеты.
Следующим шагом было несколько раз сбросить устройство с интерфейса и установить часы, это были единственные пункты подразумевающее действия, на которые может повлиять пользователь. Запомнив время в которое выполнялись эти команды, стало возможным отфильтровать эти 2 команды. И можно было начинать разбираться с форматом пакета. По дампам на устройство всегда уходили 17 байтные пакеты, первый байт был постоянен в одно значение для всех пакетов. Второй байт зависел от команды, трое из которых мы отфильтровали (были еще, но на данном этапе они были не важны). Затем 14 байт предположительно данных завершающихся нулем и один байт, похожий на хеш сумму так как изменялся в зависимости от данных, и для одного значения устанавливаемых часов всегда совпадал, как и для других команд, на содержимое которых мы не могли влиять.
Поэтому я предположил что это crc8, по сути, единственный хеш который приходил в голову сразу, и начал искать его реализацию или сайт, которые могут посчитать хеш по уже известным данным. Проверив данные, что у меня есть на соответствие по результату crc, оказалось, что не угадал. На одном сайте был пример простейшего хеша заключающегося в сумме всех байт по модулю 256 и он подошел к уже известным пакетам. И проверив это предположение попытавшись отослать немного измененный пакет для установки времени и время установилось в том виде что указывал в пакете. И теперь можно разбираться с форматом этого времени, по внешнему виду значения всех чисел в дате было в классическом человеко-читаемом виде(не секунды с начала эпохи) в bcd формате когда в полубайте храниться десятичное число и в hex виде совпадает посимвольно обычному десятичному числу.
После этого осталось три не опознанных пакета, первый всегда предшествовал остальным двум и содержал 4 не нулевых байта, и после выполнения остальных команд это число уменьшалось, поэтому я предположил, что это количество дней содержащихся в памяти. Остальные две команды возвращали одна большой дамп каких-то пакетов и одна только один пакет. Посмотрев статистику за предыдущие дни - я увидел, что интервал для данных меньше часа и предположил что первая это как раз дамп по времени, а вторая какой-то итого. Так первая выдала больше одного пакета я начал высчитывать эти данные несколько раз, и заметил, что всегда возвращается 96 пакетов и в каждом пакете был увеличивающийся байт. И тут можно предположить, что оно возвращает значения по 15 минутный интервалам за день. Так данные показываются на индикаторе только за сегодня я провел эксперимент, делая шаги и замечая когда и сколько их я сделал. В результате я узнал что среднее значение в этом пакете это шаги.
Далее я обратил внимание, что в этих запросах на дамп байт после кода команды увеличивают. И сделав запрос с циклом от минимального 0 до максимально значения, которое было в дампах полученных вначале, можно было сделать вывод, что это день начиная от сегодня. Но оставалось понять, что делает вторая команда, если она всегда возвращает нули. И на следующий день я обнаружил, что мой трекер забыл предыдущее дни, и тут меня осенило - это удаление дня из памяти. И оставалось понять, как 4 байта описывают заполненность памяти и почему на 3 возвращается только 2 дня, на 7 только 3, а на следующий по счету день вместо 96 пакетов приходит один и байт после кода команды другой. Методом не сложных умозаключений, смотря на hex код, я понял, что это не количество, а маска заполненности памяти.
Теперь осталось понять самую малость, что за остальные два числа в режиме бодрствования и что за данные в режиме сна. (Трекер имеет два таких режима, и в режиме сна шаги не считает, но проверяет качество сна, если верить графикам). Первый случай решился достаточно просто, я решил просуммировать оставшиеся числа в столбик, и оказалось, что это расстояние и затраченные энергия. Перед этим я думал, что это какие-то слагаемые шагов, так как иногда сумма этих чисел была равна шагам, но эта идея отпала когда я выяснил, что это не корректно - сумма крайних столбцов не равна среднему. Для определения, где старший байт, а где младший - я сделал более 300 шагов за интервал и там, где появилась эта единица то и старший разряд.
А теперь сон, при включенном сне один байт после кода операции меняется это выявить оказалось достаточно просто, но что делают остальные байты, которые не всегда нули и наверное что-то значат? Попытка включить режим сна и походить привела к тому, что этот интервал засчитывался как бодрствование. Данные по графикам на сайте были не точны, но каждый вид активности глубокий сон или легкий отображался другим цветом и сравнив данные на графике и распределение чисел в дампе по интервалу построив график в libreoffice calc получилось, что это значения по какому-то интервалу. Но остался вопрос размерности этих чисел, может быть один байт если это не шаги и большого уровня данных быть не должно осталось только это каким-то образом проверить.
Как понять тип сна я смоделировать не мог, так не мог сравнивать, вид сна на экране не отображается, только то что мы в режиме сна.Чтобы понять безопасность сервиса, я решил посмотреть, что и как отправляется на сервер, оказалось, что ничего шифровалось. И данные в режиме сна идут побайтно, получается это значение в интервале около 2 минут. Остались личные данные вида роста, пола и веса, но изменение их на сайте не создавало новых пакетов, поэтому я решил, что они обратно не передаются.
Вот и вся история, если нашли ошибки в рассуждениях пишите... Буду благодарен за уточнения и пожелания.

Saturday, August 1, 2015

SSD firmware update

Если судить по последним сообщениям проблема с последней прошивкой связанна с реализацией raid в ядре linux, поэтому обновление должно быть безопасно для обычных пользователей.
Samsung более не распространяет архив с кодом для обновления. Вместо него предлагая образ для cdrom, но если его записать на flash он не распознаётся как загрузочная. Поэтому для обновления нужно поступить немного по другому:
  1. bunzip2 FreeDOS-1.1-memstick-2-256M.img.bz2
  2. dd if=FreeDOS-1.1-memstick-2-256M.img of=/dev/sdb bs=512k 
  3. mount -t auto -o loop Samsung_SSD_840_EVO_EXT0DB6Q.iso /media/usb1/ 
  4. mount -t auto -o loop /media/usb1/isolinux/btdsk.img /media/usb2/ 
  5. mount -t auto /dev/sdb1 /media/usb0/ 
  6. cp /media/usb2/samsung/ /media/usb0/ -vr 
  7. umount /media/usb2/ 
  8. umount /media/usb1/ 
  9. umount /media/usb0/ 
  10. sync

Sunday, June 21, 2015

Сила эмуляции

Если посмотреть на современные компьютеры с несколько необычного угла,то можно увидеть: что ничего по сути не поменялось. Да все стало миниатюрнее и содержит большее количество транзисторов, но количество реально работающих транзисторов и объёмы памяти доступные для процессора не поменялись. Конечно это не совсем так и я сильно утрирую, но всё же посмотрим к чему это нас приведет.

Рассмотрим, как же современная аппаратура работает.
  • При включении питания процессор включается и инициализирует свои внутренние структуры можно даже считать, что он вычитывает из своего ROM внутри себя начальную программу, так как современные процессоры кроме совсем простых RISC процессоров, содержат собственный микрокод который при старте конфигурирует внутренние структуры и загружает интерпретатор внешнего бинарного кода, так как сам процессор не знает ничего о своих CISC командах и все эти команды интерпретируются, скорее даже прекомпилируются в начале конвейера в VLIW(very long instruction word) и уже эти команды он выполняет. При этом благодаря идее темного кремния - части процессора которые в данный момент не работают отключают и уменьшают количество включенных транзисторов на каждом этапе. И по сути пытаются не делать универсальные блоки - так как экономить на транзисторном бюджете не нужно, можно создать отдельные блоки для сложения и вычитания и просто выключать лишнее и получать более оптимальное соотношение потребляемой мощности к производительности так как специализированная схема, заточенная под одну операцию всегда эффективнее.
  • После этого начинается загрузка BIOSа, которая содержит совсем маленький загрузчик цель которого включить уровне кеша выше первого, так как только первый уровень кеша доступен на этапе старта и это очень ограниченное количество килобайт. Или почти intel 80. Эти инструкции настраивают следующие уровни кеша и остальную встроенную в процессор периферию, и уж затем копируют туда следующие участки кода BIOSа перекрывая участки оригинального BIOSа и распаковывая его.
  • Инициализируем самые критичные блоки и обновляем микрокод процессора и мы имеем несколько мегабайт доступной памяти и можем регулировать питание внешних устройств и т.п.. Или почти intel 86 процессор.
  • И вот теперь можно протестировать внешнюю память и настроить ее - и мы получаем intel 386 и выше процессор и у нас несколько гигабайт адресное пространство. И начинаем инициализировать остальную периферию. И если это старые BIOS мы выходим в состояние 86 процессора в 16 режиме или если это UEFI - то в родном 32/64 режиме это уже зависит, как повезет.
  • И так мы имеем первый уровень интерпретации. Процессор интерпретирует CISС инструкции - память отображена один в один по адресам, но уже работает система когда все обращении к участку памяти он скрытно копируется в кеш и уже там над ним что-то делают.
Ползем далее - операционная система создает виртуальное адресное пространство или TLB структуры и блокирует все обращение к привилегированным инструкциям. Далее код уже не видит память и не может общаться с периферией. Но можно работать с виртуальными файловыми системами и получать данные не зная, как же это все работает внутри.
Далее мы идем в следующий уровень виртуализации - контейнеры браузеры, виртуальные машины. Нам создают отдельную нить исполнения и перехватывают все наши действия и обращения к памяти и эмулируют новую аппаратуру если нужно - и от сюда нам уже не выбраться - мы не видим ровным образом ничего - нам только сказали - захочешь чего либо - вызови это прерывание.

Аппаратура и драйвера тоже ничего по сути не видят, им их запросы к памяти через IOMMU блокируют с аппаратной стороны и через вынесение их кода на менее привилегированные уровни блокируют обращении с периферией - разрешая через прерывания вызывать код ядра из уровня ниже. Или используя отображение памяти - когда пробрасывается в область памяти процесса память с видеокарты или dma - для скрытого копирования памяти между устройствами удаётся скрыть все особенности аппаратуры и обращения к памяти.

А что этот код будет делать? и кто там? - мы не узнаем, может там совсем другая архитектура и мы в виртуалке?

А есть же еще TrustZone и SMM(system managment mode) код - который может стартовать до BIOSа или быть отдельным процессором, который видит наш процессор и его память с периферией, а мы его нет. На этих механизмах построен менеджмент серверов когда через отдельную сеть управляется состоянием сервера - без его участия, например вход в BIOS и проброс кадра видеокарты через сеть или DRM(digital rights management) логика.

HTTP2 vs Cache Proxy

Http2 убивает идею кешировантие на прокси, этот стандарт приносит передачу сразу в несколько потоков с использование приоритетов на каждый поток, но в нем не заложена идея кеширования на промежуточных узлах. Это становиться не возможно, после того как любое соединение становиться шифрованным и требует валидных сертификатов. В следствии этого нельзя несколько раз передать туже информации разным пользователям, так как для каждого соединения используются разные ключи для потока. Значит можно работать только по схеме CDN, когда на промежуточных узлах есть оригинальный сертификат и все данные перепаковываются им. Было бы замечательно, если бы существовала технология, когда данные с определённого не зашифрованного потока можно было закешировать и передавать отдельным зашифрованным каналом подписи для таких данных, а сами данные по усмотрению промежуточных узлов брались из отдельного кеша. Даже если в кеше были бы данные зашифрованные и хозяин данного кеша не мог получить эти данные в открытом виде, но оставались бы хеши от содержимого и подпись этого содержимого. Это вернет кеширование в общее потребление - и сразу несколько клиентов могли бы получать общие библиотеки по общему каналу, а подписи для этих библиотек и специфичную для пользователя информацию по другому.

Bootable usb flash

Маленькая инструкция для создания загрузочной usb flash disk: 
  1. запускаем dmesg и ищем в последних записях упоминание о usb storage, предположим, что это будет sdb
  2. пробуем отмонтировать диск umount /dev/sdb1 
  3. очищаем sudo dd if=/dev/zero of=/dev/sdb count=100 
  4. создаем заново разделы sudo fdisk /dev/sdb, в ней создаем диск нажав n и соглашаемся со всеми предложениями, записываем разделы через w 
  5. форматируем новый раздел mkfs.vfat /dev/sdb1 
  6. восстанавливаем загрузочные записи sudo apt-get install mbr && sudo install-mbr /dev/sdb
  7. если нужно, копируем нужный нам дистрибутив linux через unetbootin, или если образ создан с возможностью старта с флешки, то это все можно было не делать и просто запустить dd if=cool_dist.iso of=/dev/sdb

Thursday, May 21, 2015

Датчик освещения

Опубликовал свое первое приложение в гугл маркете, написал я его полгода назад и сразу выложил исходный код с альфа версией на маpкете, но тогда оно было доступно только ограниченному кругу тестеров, включающему только те аппараты которые мне доступны. Теперь же это 'произведение' доступно всем желающим в собранном виде. Функциональность приложения очень проста, оно берет изображение с фронтальной камеры с минимальным разрешением и заблокированной экспозицией и рассчитывает среднее значение которое ставит как значение яркости экрана. Для удобства тестирования приложение отображает значение с датчика освещения и примерное значение освещения на основе кадра фронтальной камеры.
Идей для дальнейшего улучшения может быть добавление виджета для рабочего стола или экрана блокировки, но у андроида динамическое изменение содержимого виджета и доступ к камере не доступен напрямую без хаков. Скорее это не очень красивый код получится, поэтому пока не найду, как красиво это сделать будет только явный запуск. Или добавление в ядро линукса псевдо датчика освещённости, который будет использовать камеру.

DDOS vs CDN

Текущие методики чистки трафика от паразитного как то DDOS или накручивание счетчиков представляют собой правила на блокирование трафика по регионам адресов и дополнительные проверки на живость пользователя через капчи даже скрытое от пользователя когда браузер сам высчитывает какую-то магию или проверку на какие-то специфичные свойства браузера - куки в local storage или флеше, теги в кешируемом содержимом.
Эти способы имеют не очень приглядные особенности - заблокировав людей по принципу присутствия включенного js или флеша, сразу отбрасывают людей с выключенным js или если сбойнул какой-то код или мобильных пользователей с альтернативными браузерами. При этом желающих обойти эту проблему решение лежит на поверхности - разобраться что куда ставиться и с эмулировать или запустить эмуляцию всего браузера и или если есть доступ к банерной системе - грузить этот сайт вместе со своим банером на пользовательских системах.
При ограничении трафика по адресу вы сразу отбрасываете пользователей с этого региона и теряете часть добросовестных пользователей, в случае тора для сайтов связанных с образовательной деятельностью или обсуждающих какие-то проблемы общества - мы теряем наиболее активных пользователей которым из-за ограничение трафика провайдером или из желания сохранить конфиденциальность своих интересов от третьих лиц.
Возможным решением таких проблем было бы максимальная кешируемость страниц с информацией с попыткой по максиму использовать CDN и лимитация трафика по объёму по регионам и выполнение проверок на живость только на этапе заполнения форм, когда js уже может быть жизненно важен для работоспособности.