Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
#Круги добра
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Классическая игра в аркадном стиле для любителей ретро-игр. Защитите космический корабль с Печенькой (и не только) на борту, проходя уровни.

Космический арканоид

Арканоид, Аркады, Веселая

Играть

Топ прошлой недели

  • SpongeGod SpongeGod 1 пост
  • Uncleyogurt007 Uncleyogurt007 9 постов
  • ZaTaS ZaTaS 3 поста
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
0 просмотренных постов скрыто
9
Selevoy
Selevoy
2 месяца назад

Скины на Алису⁠⁠

Доченька очеловечила бездушную машину. Надо патентовать, а то Яндекс идею стибрит.

Скины на Алису Дочь, Творчество, Яндекс Алиса, Моддинг
Показать полностью 1
[моё] Дочь Творчество Яндекс Алиса Моддинг
2
507
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
2 месяца назад

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C⁠⁠

Недавно я исследовал китайские онлайн-барахолки и наткнулся на лот с продажей абсолютно новых КПК Sharp Zaurus за 4.500 рублей. Будучи прожженным гиком и ярым фанатом всего, что хоть как-то похоже на ноутбук и работает на ARM-процессоре, я не смог устоять и решил приобрести его в свою коллекцию необычных Linux-гаджетов. А поскольку устройство абсолютно новое и опечатанное, я решил оформить распаковку и ретроспективу в виде ламповой статьи!

❯ Предыстория

В наше время нет никаких проблем купить себе интересный гиковский гаджет. То и дело небольшие компании по типу Planet Computers и Pine64 выпускают необычные устройства, по большей части предназначенные для доводки напильником и ковыряния ради самого процесса. Более того, в эпоху DIY, многие начинающие инженеры сами себе собирают гиковские штучки: я и сам являюсь одним из таких доморощенных маминых конструкторов.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Cosmo Communicator

Но в девяностых и нулевых всё было не так просто: Open Hardware-компьютеров вообще практически не существовало (кроме смартфона Neo Freerunner), а серийные Linux-устройства можно было пересчитать по пальцам. Но обширное коммьюнити не отчаивалось и пыталось портировать ядро на все гаджеты, где есть MMU и хоть какая-то документация на процессор. HP Jornada, Dingoo A320, HTC Magician, HTC Gene - на все эти устройства Linux был полноценно портирован исключительно силами коммьюнити!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

RZX-50 использовал наработки сообщества по Dingoo A320.

Среди легендарных гиковских гаджетов, особенно выделяется серия портативных компьютеров Sharp Zaurus. Ещё в 2001 году, японская корпорация поверила в перспективы Linux и Qt и выпустила один из первых серийных КПК с «пингвином» на борту - SL-5000D. Модель отличалась полноценной QWERTY-клавиатурой, которая пряталась под выдвигающимся блоком системных клавиш, крупным цветным дисплеем с приличным разрешением 240x320, мощным процессором Intel StrongARM и наличием свободного SDK для разработки программ с использованием Qt.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Несмотря на высокую цену, устройство стало бестселлером среди гиков, которые старались выжать из устройства максимум. Кастомные прошивки, ядра с разгоном процессора, порты программ с ПК - всё это появилось задолго до Android-смартфонов! Попробуйте представить себе, насколько круто было запустить полноценный Wolfenstein3D в 2002 году на портативном гаджете...

Будучи коллекционером и одним из таких энтузиастов, мне тоже захотелось обзавестись легендарным японским КПК. Сначала я купил за копейки SL-5500D из утиля с эффектом, известным как «уксусный синдром» - когда из-за неправильного хранения поляризационная пленка дисплея начинает отслаиваться и из-за кристаллизации клея изображение начинает «плыть».

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

А затем мне попался лот с абсолютно новым SL-7500C для китайского рынка по весьма приятной цене в 4.500 рублей. Благодаря подписчику Роману и сервису YouCanBuy, я смог заказать гаджет и привезти в Россию, за что вам огромное спасибо!

❯ Распаковываем

Поскольку многие модели Zaurus продавались в основном на рынке Японии, в другие страны их нередко ввозили «серым» импортом. Китай, однако, был исключением - там ввозом устройств занималась корпорация CEC и буква 'C' в конце названия модели как раз говорит о том, что у нас версия для Китая. От японской она отличается упаковкой и языком прошивки.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Гаджет приехал ко мне в посылке, где находился фирменный пакет, коробка с аксессуарами и опломбированная отдельная коробка для самого гаджета. В коробке с аксессуарами лежат два огромных талмуда - один с инструкцией для устройства, а второй для внешнего CF-модема GC, который позволяет добавить устройству GPRS и даже возможность звонить! Самого модема в комплекте не было, зато был диск с софтом и драйверами, проприетарный дата-кабель, блок питания (5В с Barrel-jack, как на PSP и КПК HTC/HP), запасной стилус, аккумулятор и гарантийная информация. В общем, почти стандартный набор для тех лет.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

А вот сам гаджет упакован особенно: отдельная коробочка с ленточной подпоркой, обшитая красной тканью, в которой гордо расположился SL-7500C. В подобных коробочках поставляются либо шедевры ювелирной работы... либо крутейшие гиковские гаджеты!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

В качестве аккумулятора здесь используется литий-ионный элемент на 950мАч. Учитывая что АКБ хранится отдельно, мне было интересно остался ли в нём ещё хоть какой-то заряд спустя 21 год после выхода устройства. При первичном замере на клеммах было 0В (это на BMS, в самом аккумуляторе было ~2.6В), однако АКБ сразу же раскачался от лабораторного блока питания и подал признаки жизни.

На первый взгляд кажется, что литий-ионные АКБ не могут жить так долго, но при условии правильного хранения, аккумуляторы могут лежать и 10, и 15 лет, сохраняя заводской заряд. У меня лежат запечатанные аккумуляторы для сонериков и моторолл, которые всё ещё неплохо держат заряд и даже у SL-5500D, который я показывал чуточку выше, аккумулятор всё ещё жив спустя почти 25 лет!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Ну что-ж, пришло время подзарядить аккумулятор и впервые за 21 год включить нашего красавца...

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

❯ Знакомимся ближе

Даже спустя 22 года после релиза этот красавец включается и работает как ни в чем не бывало, причём родной аккумулятор всё ещё держит заряд минимум несколько часов. При включении нас встречает консоль Linux, затем логотип Qtopia и рабочий стол устройства, который представляет из себя вариацию на тему Windows. Изначально интерфейс у большинства «Завриков» на японском или китайском языке и возможности сменить язык на английский нет - нужно прошивать кастомную прошивку.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

У Zaurus есть своя консоль восстановления, откуда можно прошить кастом, сделать бэкап и отформатировать пользовательский раздел. Вызывается она включением с зажатой кнопкой «ОК», далее можно выбрать метод обновления: с CF-карточки, SD или через USB. «Завры» очень прихотливы к SD-картам, даже обычные MMC он не видит и нормально работает только с CompactFlash!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Самой популярной кастомной прошивкой была CackoROM, предположительно от разработчиков из СНГ. В довесок к стандартной Qtopia, CackoROM добавлял менеджер пакетов, позволяя устанавливать новый софт, терминал, порты различных программ на Qt с KDE и кастомное ядро. Даже Midnight Commander портировали. Буквально LineageOS в мире Zaurus!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Прошиваемся

После прошивки, printk начинает выводить логи на экран, что прибавляло к крутости владельца 100 очков... А ведь раньше даже во времена Android убирали бутанимацию и делали вывод сообщений ядра!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

SL-7500 - кровный брат-близнец модели C750, работающий на идентичном железе. Под капотом у них флагманское для своих лет железо:

  • Процессор - Intel XScale PXA255 на частоте 400МГц с одним ARMv5-совместимым ядром собственной разработки Intel. Процессор набирает почти в два раза больше очков MIPS, чем Pentium MMX и идёт на равных с Pentium II 300 - уже в 2003 году!

  • ОЗУ - 64Мб типа SDRAM. Классика для КПК тех лет, хотя в 2003 году ещё выходили модели и с 32Мб памяти.

  • Постоянная память - 64Мб типа NAND, производства Samsung. Для расширения памяти есть слот для SD, а также для карт CompatFlash.

  • Дисплей - TN-матрица разработки CG-Silicon с огромным по меркам тех лет разрешением - 640x480, диагональю в 3.7" и отличной цветопередачей с глубиной пикселя в 16-бит. У компактного КПК дисплей был не хуже, чем у некоторых актуальных для тех лет десктопов!

  • Коммуникации - USB, COM-порт, Wi-Fi и ИК-порт. CF также можно использовать для расширения функционала устройства с помощью дополнительных модулей.

После загрузки нас встречает рабочий стол Qtopia, разделенный на несколько вкладок: основные приложения, Java-приложения, настройки и проводник. Есть также фирменное меню пуск и панель задач - у «Заврика», как и у любого уважающего себя Linux-гаджета, есть многоконность!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Также здесь есть поддержка Java, но не J2ME как на телефонах, а Jeode с профилем, близким к CDC (J2SE ~1.1). По сути, это почти полноценная Java-машина с поддержкой awt - а значит на ней можно запустить различный ретро-софт. Из коробки здесь есть демо-апплеты, а также игра крестики-нолики, да и в целом поверх этой JVM можно реализовать MIDP 1.0 и запускать игры и программы для ретро-телефонов.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Zaurus отличался очень неплохими мультимедийными возможностями. Уже из коробки был предустановлен MP3-плеер, а также видеоплеер с поддержкой формата 3gp. Конечно едва ли в те годы можно было посмотреть на нём фильм, SD-карточки были ещё слишком малого объёма, но вот счастливые обладатели CF-карт на 256Мб уже могли попробовать посмотреть сильно пережатый фильмец!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Помимо этого, у Zaurus был полноценный веб-браузер NetFront 3.1 от компании Access. Это вам не урезанные WAP-сайты: миниатюрный гаджет мог просматривать настоящие WEB 2.0 страницы, а двумя движениями ноутбук превращался... в компактный планшет! В SL-7500C к сожалению нет ни WLAN, ни Bluetooth, поэтому подключить его к сети я не смог. Но уверяю у вас, OpenNet он бы точно открыл!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Поскольку Zaurus - это ещё и органайзер, в нём предустановлен различный офисный софт. Заметки, клиент E-Mail, календарь, записная книжка - всё это входит в стандартный набор программ. В целом, Zaurus можно считать прямым конкурентом тех же самых HP Jornada, LG Phenom и других WinCE-субноутбуков тех лет.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

Ну и какой-же Linux-КПК обходится без возможности зайти в консоль под рутом и управлять системой как вздумается? На Zaurus легко можно было запускать консольный софт вообще без особых изменений, а также GUI-софт. Причём Qt был необязателен: многие эмуляторы рисуют сами себя либо сразу в фреймбуфер, либо используют библиотеку SDL. Возможности моддинга гаджета были неограниченными!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

❯ Заключение

Вот такой необычный Linux-гаджет разработали в Японии в далёком 2003 году. На первый взгляд кажется что у него совсем нет применений в современном мире, однако на практике это вполне достойный портативный терминал, печатная машинка, игровая консоль и... телефон, если конечно у вас есть CF-радиомодуль. Подытоживая, можно сказать что Zaurus - один из самых ярких представителей ушедшей эпохи карманных портативных компьютеров.

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статью) можно найти на моём YouTube канале.

Как вам Sharp Zaurus SL-7500C?
Всего голосов:
А что думаете о Zaurus в целом?
Всего голосов:

Очень важно! Разыскиваются девайсы для будущих статей!

Друзья! Для подготовки статей с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я и хочу заняться и написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост

А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны Motorola на Linux (например, EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E5, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!) и устройства на Windows Mobile. Всем большое спасибо за донаты!

«22 года спустя»: Распаковываем Linux-мечту гика из 2003 года — новый Sharp Zaurus SL-7500C Опрос, Покупка, Гаджеты, Linux, Гик, Моддинг, Прошивка, Япония, Sharp, Кпк, Ноутбук, Ретроспектива, Железо, Intel, Длиннопост
Показать полностью 22 2
[моё] Опрос Покупка Гаджеты Linux Гик Моддинг Прошивка Япония Sharp Кпк Ноутбук Ретроспектива Железо Intel Длиннопост
49
204
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
3 месяца назад

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру⁠⁠

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Осторожно: в данной серии статей я рассказываю о реверс-инжиниринге и хакинге простых кнопочных звонилок. Цель простая: расширить скудный функционал телефонов ценой до 1 000 рублей и сделать их привлекательной моддинг-платформой для самых разных гиков. Если вы когда-нибудь слышали про эльфы и патчи, и вам интересно узнать, как происходит процесс взлома и изучения прошивок, а также написания новых программ для кнопочников — приглашаю вас под кат!

❯ Предыстория

Недавно я познакомился с Ilya_ZX, человеком-легендой в моддинг сцене телефонов из нулевых. Илья рассказал мне забавную историю: ещё будучи студентом, он увидел как одногруппник играет на своём LG G1800 в легендарную мобильную игру нулевых — «Змейку». Его тогдашний Siemens A60 не умел ничего кроме игрушки Stack Attack, даже Java-игры не поддерживались, а молодому парню очень хотелось сыграть в Змейку на скучных парах!

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Казалось бы, на дворе 2005 год, можно просто пойти на рынок и купить уже изрядно подешевевшую Б/У 3310 и поиграть в «трушную» змейку именно там. Но Илья был не просто студентом технаря, он с юности интересовался программированием, реверс-инжинирингом и телефонами! И он решил поспорить с одногруппником — сможет ли он реализовать Змейку на своём A60? Всего за один месяц он умудрился исследовать прошивку телефона на диковинной процессорной архитектуре, найти необходимые функции для работы с дисплеем, вводом и окнами и написать ту самую змейку. Попробуйте теперь представить лицо его одногруппника, который проиграл спор молодому реверсеру :)

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Сначала Илья написал игру на Паскале для самопального «симулятора» A60, а затем переписал её на ассемблере для C166s!

На момент написания статьи мне 23 года, я лишь чуточку старше тогдашнего Ильи. После рассказанной истории, я подумал «А чем я хуже?» и принялся реверсить прошивку бюджетного кнопочника 10-й давности - Explay B240. В прошлой статье, мы с вами проделали первые шаги по хакингу телефона: загрузка прошивки в IDA Pro и поиск системных функций, хакинг файлового менеджера для запуска программ с MicroSD-флэшки, разработка загрузчика исполняемых файлов и организация таблицы функций. В целом, это весьма неплохая поучительная статья для новичков в реверс-инжиниринге.

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Однако итоговый результат в виде заливки экрана желтым цветом может показаться незначительным. Поэтому в сегодняшней статье мы с вами напишем первую действительно полезную программу!

❯ «Змейка»

Напомню, что загрузчик внешних программ работает по очень простому принципу: мы нашли в дизассемблере функцию обработки сообщений окна встроенной игры и хукнули её, дабы при открытии окна она загружала программу с MicroSD-флэшки в ОЗУ и передавала ей управление. При этом загрузчик сразу интегрирован в проводник: при запуске файла с расширением .app, патч кладет строку с абсолютным путем к нему в одну из «угнанных» глобальных переменных, открывает хукнутое окно игры, а далее бинлоадер транслирует все сообщения от ОС в загруженную программу.

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Наглядная демонстрация работы

Таким образом, жизненный цикл приложений значительно упрощается по сравнению с "эльфами" на тех же Motorola и Siemens: по сути, нам остаётся лишь проинициализировать состояние программы в MSG_CREATE и освободить динамическую память в MSG_CLOSE. Читателям, которые хоть раз писали программы под Windows, такой подход может показаться очень знакомым!

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Для реализации змейки, нам необходимо уметь обрабатывать кнопки и рисовать что-то на дисплей. С кнопками проблем никаких не возникает: система шлёт сообщения типа MSG_KEYDOWN_KEY и MSG_KEYUP_KEY на каждое событие с клавиатурой. А вот с графикой чуточку сложнее: поскольку встроенные в прошивку функции завязаны на работу с вшитыми ресурсами, мы напишем нужные функции сами.

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

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

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

void Paint(LoaderContext* context)
{
LcdId lcd = { 0, 0 };
uint16* fb = ((uint16*(*)(LcdId* id)) LcdGetFrameBuffer)(&lcd); // Get framebuffer for primary screen

uint16 startEnd[4] = { 0, 0, 240, 320 }; // Rect
((void(*)(LcdId* lcdId, uint32 start, uint32 end, uint16 col)) LcdDrawRectPtr)(&lcd, ((uint32*)&startEnd[0])[0], ((uint32*)&startEnd[0])[1], 0x0); // Draw fullscreen rectangle

((void(*)()) LcdUpdateRect)(); // Update rect
}

Далее я реализовал функцию для отрисовки текста на экране. Шрифты самые примитивные — 8x8, побитовые, примерно как в знакогенераторе оригинального IBM PC. Принцип отрисовки прост: каждый символ (глиф) хранится в виде 8 байт. В каждом байте один бит представляет из себя пиксель по координате Y, если он равен нулю — значит пиксель прозрачный, в обратном же случае он должен быть закрашен нужным цветом.

Алгоритм для отрисовки шрифтов выглядит так:

int LcdDrawChar(LoaderContext* context, uint16* frameBuffer, char chr, uint32 x, uint32 y, uint16 color)
{
if(x >= 0 && y >= 0 && x + FONT_WIDTH < LCD_WIDTH && y + FONT_HEIGHT < LCD_HEIGHT)
{
int i, j;
unsigned char* glyph = (unsigned char*)(GLOBAL(context) + &embedded_font[chr * 8]);

for(i = 0; i < FONT_HEIGHT; i++)
{
short* fb = &((short*)frameBuffer)[(y + i) * LCD_WIDTH + x];

for(j = 0; j < FONT_WIDTH; j++)
{
if((*glyph >> (FONT_WIDTH - j)) & 0x1)
*fb = color;

fb++;
}

glyph++;
}

return true;
}

return false;
}

void LcdDrawString(LoaderContext* context, uint16* frameBuffer, char* str, uint32 x, uint32 y, uint16 color)
{
if(x >= 0 && y >= 0)
{
unsigned int i;

for(i = 0; i < strlen(str); i++)
{
if(!LcdDrawChar(context, frameBuffer, str[i], x, y, color))
return; // Out of screen

x += FONT_WIDTH;
}
}
}

Наверняка вы заметили страшный костыль в локальной переменной glyph с арифметикой над указателями. Дело в том, что на момент написания статьи, программа представляет из себя сырую склейку секций .text, .data, .bss и .rodata, поэтому на данный момент в ней нет релокаций, которые помогли бы сделать программу перемещаемой в памяти. В arm-none-eabi все вызовы функций без явного указателя — относительные, но при этом обращения к глобальным переменным и константам (например, строковым литералам) — абсолютные. Если попытаться напрямую использовать глобальную переменную по адресу 0x18 — программа будет пытаться читать или портить память в таблице векторов прерываний, что неизбежно приведет к HardFault. Поэтому для получения настоящего адреса переменной, к ней необходимо прибавить базовый адрес загрузки программы:

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

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

Далее мы рисуем нашу строку с текстом:

LcdDrawString(context, fb, SCONST(context, "Ya lyublu AvtoVAZ"), 0, 0, 0xFFFFFF);

И получаем следующий результат:

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Для змейки, если она не ASCII, этого всё равно мало. Поэтому нам нужна функция для вывода картинок на дисплей. Написать загрузчик tga или bmp не составляет труда, но хотелось бы чтобы программа была самодостаточной и несла с собой все необходимые ресурсы. Поэтому для конвертации картинок я использую вот этот инструмент: выбираем файл, формат ставим в 16-бит 565 и преобразовываем в C-массив.

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

void LcdDrawBitmap(uint16* frameBuffer, short* bitmap, uint32 width, uint32 height, uint32 x, uint32 y)
{
if(bitmap)
{
int i, j;
short* bmp = bitmap;

// Slow debug version
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
LCD_PLOT_565(clamp(x + j, 0, LCD_WIDTH), clamp(y + i, 0, LCD_HEIGHT), bmp[i * width + j]);
}
}
}
}

А отрисовать нашу картинку можно вот так:

LcdDrawBitmap(fb, (short*)(GLOBAL(context) + (uint32)&lada_bmp), LADA_WIDTH, LADA_HEIGHT, 0, 0);

Почему бы не спрятать дескриптор изображения в структуру?

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

И вот наш результат. Не удивляйтесь тестовому изображению, просто я — прирожденный ТАЗовод!

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Помощь

Переходим к геймплею. Сама по себе «Змейка» в реализации — простая игра, где каждый уровень представляет из себя примитивную сетку. Алгоритм работы заключается в том, что раз в n-миллисекунд вызывается один игровой тик, который двигает игрока в текущем выбранном направлении. Если в момент тика нажата одна из кнопок-стрелок — направление движения меняется — тут всё очевидно:

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

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

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

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

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

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

if(state->Segments[SEGMENT_HEAD].X == state->AppleX && state->Segments[SEGMENT_HEADER].Y == state->AppleY)
{
state->Score++;
MoveApple(state);
}

Для респавна яблочка можно использовать два подхода: параметрические таблицы с заранее прописанными координатами объекта (эдакая псевдослучайность) и обычный PRNG-генератор, который путем реверса можно найти в прошивке.

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Благодаря дипсику удалось определить, что в прошивке используется LCG. Вообще, нейронки очень сильно помогают при реверсе и могут легко анализировать стандартные алгоритмы: я тестировал от простых по типу memcpy, до относительно сложных как например программное деление по модулю и программная растеризация треугольника по Scanline-алгоритму.

unsigned int rand()
{
int v0; // r3
int v1; // r4
int v2; // r1

v0 = MEMORY[0x4710E80] - 1;
v1 = *(_DWORD *)(4 * MEMORY[0x4710E84] + 0x4710E88) + *(_DWORD *)(4 * MEMORY[0x4710E80] + 0x4710E88);
*(_DWORD *)(4 * MEMORY[0x4710E84] + 0x4710E88) = v1;
MEMORY[0x4710E80] = v0;
v2 = MEMORY[0x4710E84] - 1;
if ( v0 >= 0 )
{
--MEMORY[0x4710E84];
if ( v2 < 0 )
MEMORY[0x4710E84] = 54;
}
else
{
--MEMORY[0x4710E84];
MEMORY[0x4710E80] = 54;
}
return (unsigned int)(2 * v1) >> 1;
}

Если же голова оказывается в одном из сегментов или же за полем — игра окончена. Полный вес собранного приложения - 5 килобайт 644 байта! А ниже - демонстрация его работы:

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

❯ Заключение

Вот такой интересный моддинг бюджетного кнопочника у нас с вами сегодня получился. От слов к делу мы с вами написали первые действительно рабочие программы, которые может быть и не самые полезные, но поверьте, для гика важен сам процесс и объём получаемого от этого эндорфина...

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

Это приносит невероятное моральное наслаждение

А что ещё нужно парню в 23 года? Правильно: чтобы мотор бодро тянул любимую десятку и чтобы реверсилось всё легко и понятно! Исходный код и все что необходимо для установки бинлоадера есть в на моем гите.

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статью) можно найти на моём YouTube канале.

Важно: друзья! Я уверен, что статью будут читать выходцы с форумов моддеров и возможно даже ребята, связанные с прошивочными боксами. Если у вас есть исходный код или объектные файлы для телефонов Siemens (S-Gold или E-Gold — не имеет значения) и вы хотели бы помочь общему моддерскому делу — напишите пожалуйста мне в Telegram. Несмотря на то, что этот код уже давно никому не нужен и E-Gold/S-Gold уже более 15 лет снят с производства, гарантирую полную анонимность и крутой контент :)

Очень важно! Разыскиваются девайсы для будущих статей!

Друзья! Если вам понравилась сегодняшняя статья про разработку эльфов, то спешу объявить: для подготовки будущих материалов с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я сейчас занимаюсь, а затем написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны на Linux (например Motorola EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E6, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!). Всем большое спасибо за донаты!

Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост
Самая сложная «Змейка»: Как я отреверсил и хакнул кнопочный телефон, чтобы написать для него классическую игру Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Хакеры, Моддинг, Кастомизация, Игра змейка, Гифка, Длиннопост

А ещё я держу все свои мобилы в одной корзине при себе (в смысле, все проекты у одного облачного провайдера) — Timeweb. Потому нагло рекомендую то, чем пользуюсь сам — вэлкам:

Показать полностью 19
[моё] Телефон Гаджеты Программирование Реверс-инжиниринг Хакеры Моддинг Кастомизация Игра змейка Гифка Длиннопост
24
7
botfighter
botfighter
3 месяца назад

Ответ на пост «Маркетинг в ущерб функциональности»⁠⁠3

Есть у мну КПК эпохи Windows Mobile Fujitsu-Siemens LOOX 720 и была у него особенность, которая меня, как сейчас модно говорить, корёжила, а именно - выступающая камера.

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

Вот как выглядит масштаб трагедии в заводском исполнении:

Ответ на пост «Маркетинг в ущерб функциональности» Эргономика, Моддинг, Кпк, Ответ на пост, Длиннопост
Ответ на пост «Маркетинг в ущерб функциональности» Эргономика, Моддинг, Кпк, Ответ на пост, Длиннопост

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

Ответ на пост «Маркетинг в ущерб функциональности» Эргономика, Моддинг, Кпк, Ответ на пост, Длиннопост

Ещё попался HP iPAQ h2210, подавшийся в моддинг, но до конца этот путь пройти не успевший.

Ответ на пост «Маркетинг в ущерб функциональности» Эргономика, Моддинг, Кпк, Ответ на пост, Длиннопост
Показать полностью 4
[моё] Эргономика Моддинг Кпк Ответ на пост Длиннопост
5
4
GNVV
GNVV
3 месяца назад

Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы⁠⁠

🎮 Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы!

Моддер Razed создал потрясающую модификацию NaturalVision Enhanced для GTA 5, потратив около 8000 часов. Благодаря трассировке лучей и вниманию к деталям, виртуальный Лос-Сантос выглядит как настоящий.

Razed надеется на развитие моддинга с выходом GTA 6 и поддержку от Rockstar Games.

#GTA #GTA5 #моддинг #LosSantos #Razed #NaturalVisionEnhanced

Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Фотореалистичный Лос-Сантос в GTA 5: 10 лет работы Кросспостинг, Pikabu Publish Bot, GTA, GTA 5, Моддинг
Показать полностью 9
Кросспостинг Pikabu Publish Bot GTA GTA 5 Моддинг
3
762
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
3 месяца назад

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C⁠⁠

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Осторожно: Помните ли вы, как в вашем телефоне Siemens, Motorola и Sony поселились маленькие программы - "эльфы"? В рамках этой статьи мы во всех деталях исследуем прошивку бюджетного кнопочника, разберемся в её архитектуре, хакнем и напишем загрузчик тех самых эльфов с MicroSD-флэшки. При этом я постараюсь объяснить всё максимально простым и доступным языком!

Недавно я познакомился с легендой форума allsiemens.ru — Ilya_ZX, который известен своим огромным вкладом в тему реверса и моддинга телефонов на платформе E-Gold и S-Gold. Илья поведал мне интересную историю о том, как в начале нулевых, будучи студентом, поспорил с одногруппником, сможет ли он добавить «змейку» в свой Siemens A60. И спор он этот выиграл, путем бессонных ночей ковыряния прошивки в IDA Pro! Я подумал — «а чем я хуже?». Взял в руки кнопочный телефон на платформе Spreadtrum, сдампил прошивку и загрузил в дизассемблер...

Если вам интересен подробный процесс реверса различных модулей прошивки, как они взаимодействуют между собой, как я написал программу для применения патчей к фуллфлэшу и, собственно, бинлоадер с первой программой — жду вас под катом!

❯ Предисловие

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

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Поиск SKey и HASH в адресном пространстве телефона через уязвимость в Java-машине

Но общими усилиями сообщество моддеров делало невозможное. Люди искали уязвимости и патчили загрузчики на телефонах Motorola для обхода проверки подписи RSA, резали тест-поинты и разбирались в BootROM'е процессоров S-Gold в телефонах Siemens, чтобы написать генератор BootKEY для возможности прошивки кастомов и немного ковыряли телефоны Samsung, где не только не было никакого секьюрбута, но ещё и прошивки утекали со всей информацией о символах (файлы .lst).

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Razr V3i

Но что самое интересное — эльф-сцена до сих пор живая и в профильных чатах уже повзрослевшие ребята до сих пор обсуждают то, как им ускорить порт эмулятора NES путем перемещения кода в IRAM, разогнать процессор Freescale Argon LV и... кто бы мог подумать — написать эмулятор периферии S-Gold для запуска прошивки Benq-Siemens E71 в QEMU. И хотя форумы по Siemens'ам уже давно не работают, MotoFan всё ещё жив и хранит кладезь полезной информации для моддеров и реверсеров!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Одним из таких парней был и @ILYA_ZX, который сделал большой вклад в моддинг-сцену телефонов Siemens. Например, именно благодаря его исследованиям звуковой подсистемы, в S65 и M65 добавили полноценную поддержку MP3, чего не смогла сделать даже сама Siemens. Когда я услышал его историю о том, как он на спор с одногруппником отреверсил и написал «змейку» для своего Siemens A60, я сразу же вдохновился и понял... что нужно обязательно что-нибудь пореверсить и повторить успехи Ильи на какой-нибудь неисследованной платформе, причём желательно достаточно свежей, которую можно встретить в новых бюджетных кнопочниках...

❯ Первые шаги...

Я начал с поиска в своей коллекции телефонов цели для будущего моддинга. Одними из главных критериев были: относительно быстрая флэш-память для того, чтобы не поседеть в процессе заливки софта и поддержка прошивки через обычный USB без необходимости покупки отдельных кабелей и прошивочных боксов. У меня нашлись несколько телефонов на разных процессорах: MediaTek, Spreadtrum, а также Coolsand (похож на MTK и Spreadtrum, но MIPS, а не ARM). Я поочередно вычитывал с них прошивки с помощью специального сервисного софта, а затем ковырял их в дизассемблере и подбирал подходящую модель.

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Моё внимание привлёк телефон Explay B240, который за пару дней до начала процесса мне подарил подписчик Павел, за что ему огромное спасибо.

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

После загрузки прошивки в IDA Pro, я сразу же полез смотреть строки и искать самые первые необходимые функции: printf, аллокатор динамической памяти, функции libc для работы со строками, а также ABI-функции по типу деления (в ARM аппаратного деления нет).

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

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

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

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Это настоящий дар для реверсера!

Изначально код после загрузки в дизассемблер выглядел странно: и тут и там указатели на несуществующую память, побитые данные и очень малое количество прямых референсов на ROM. И тут Илья взял фулл, поковырял его и сказал — «да это ж Big-Endian, я нутром чую!». И как оказалось — действительно, телефон использовал BE порядок байт.

Для тех, кто не в курсе — в мире компьютеров есть два варианта представления одного и того же многобайтового числа (то есть полуслова, слова, длинного слова): Big Endian и Little Endian. В Little Endian байты числа исчисляются от младшего к старшему, а в Big Endian — от старшего к младшему. Таким образом, если программа, например, захочет загрузить BMP-картинку, ей необходимо будет перевернуть порядок байт в каждом машинном слове заголовка, чтобы получить правильные данные о размере изображения.

Существует также сетевой порядок байт — это Big Endian, он нужен для унификации протокола общения между компьютерами разной архитектуры!

ARM умеет работать в обеих режимах, но до ARMv6 BE и LE аппаратно переключался в процессорном ядре на этапе синтеза или, например, внешним пином. Как раз таки из-за этого перед дизассемблирование ARM-прошивки необходимо сначала узнать её Endianness: например вместо LE-инструкции FE B5 в Thumb у нас будет B5 FE.

Для меня это стало неожиданностью, поскольку из примеров BE на телефонах я знал только легендарные Motorola. После этого я выяснил, что телефон работает на чипсете Spreadtrum SC6500L 2010 года выпуска, который представляет из себя:

  • Одно ядро ARM9EJ-S на частоте 208МГц в паре с DSP для обработки GSM-радиоканала.

  • 4МБ интегрированной оперативной памяти типа PSRAM и 4МБ NOR-памяти.

  • Контроллеры LCD-дисплеев и различной периферии, включая SPI, I2C, I2S и GPIO.

  • Встроенный контроллер питания вместе с модулем чарджера.

И это очень достойные для простого телефона характеристики. Такой чипсет может потянуть не только змейку или Java-игры, но даже эмуляторы ретро-консолей! И 4Мб оперативной памяти для этого хватит с головой. Перспективы дальнейшего моддинга уж точно были!

В реверс-инжиниринге полезно всё: промежуточные elf'ы с прошивкой (axf), таблица символов и тем более исходный код. В поисках слитых исходников прошивки, я наткнулся на архив для гораздо более свежего чипсета — SC6531 (который до сих пор используется в 90% кнопочных телефонов, которые сейчас можно купить в условном DNS до 2.000 рублей), и для общего понимания архитектуры принялся его изучать.

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Поскольку кодовая база Spreadtrum тянется из нулевых, прошивка написана по «эмбеддерски» олдскульно: весь код на Plain-C, практически везде глобальные переменные (для экономии RAM, т. к. флэшка поддерживает XIP и маппится в адресное пространство процессора напрямую, а также во избежание фрагментации), UI-построен на модели сообщений как в Windows — то есть, огромные свич-кейсы. Вкратце, архитектуру можно описать так:

  • В основе лежит RTOS ThreadX, которая также называется Nucleus. В задачи ОСРВ входит реализация вытесняющей многозадачности, включая примитивы синхронизации — мьютексы, семафоры, системного аллокатора, обработчика аппаратных исключений и некоторых других низкоуровневых подсистем.

    Nucleus также использовался в телефонах на процессорах MediaTek, Coolsand/RDA, Infineon (Siemens, Panasonic), Freescale (Motorola) и многих других.

  • Над RTOS реализованы драйверы для работы с железом. Дисплей, звук, коммуникация с DSP, клавиатура — всё это тоже низкоуровневые подсистемы.

  • Далее идёт UI-подсистема MMI — Man Machine Interface. MMI представляет из себя менеджер окон, служб (например воспроизведение музыки в фоне), GUI-фреймворк для построения интерфейса и апплетов — встроенных в телефон приложений, а также менеджер ресурсов. При этом MMI оперирует жестко-прописанными в прошивке набором окон, где каждая структура содержит строковой идентификатор и указатель на функцию-обработчик событий, что заметно упрощает реверс-инжиниринг этой части прошивки.

❯ «Угоняем» окно MMI

Для того, чтобы запустить код с внешнего носителя, необходимо сначала найти функции для работы с файловой системой и пропатчить уже существующую часть прошивки, дабы она могла вызывать наш код в ответ на какое либо действие. С функциями для работы с ФС проблем не возникло. Поскольку трейсов много, я практически сразу нашел необходимый минимум — SFS_OpenFile, SFS_GetFileSize, SFS_SetFilePointer/GetFilePointer, SFS_ReadFile/SFS_WriteFile и SFS_CloseFile.

На вход SFS_OpenFile принимает указатель wchar_t на строку с полным путем к файлу с учетом диска (C:/ — системное хранилище, D:/ — внутренняя память, E:/ — MicroSD), числовой идентификатор с режимом открытия файла и два дополнительных параметра для атрибутов.

Имейте ввиду, что на некоторых мобильных ОС работа с файлами только асинхронная и на коллбэках!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Реализация SFS_OpenFile

Как я уже говорил ранее, у каждого окна в системе есть функция для обработки сообщений — концепция такая же, как и WndProc на Windows. Если эту самую функцию пропатчить, можно сразу «угнать» контекст MMI и использовать для того, чтобы писать свои собственные GUI-приложения. В качестве вектора атаки я решил использовать какое-нибудь не сильно нужное в повседневной жизни приложение. Например, встроенную игру «Сокобан».

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Улитка должна передвинуть ящики на место какашек

Поскольку реализация игры на моей версии прошивки значительно отличалась от той, что есть в исходном коде, то пришлось искать функцию «по наитию». Сначала нашел функции для управления таймером подсветки, затем от неё несколько WndProc и анализировав одну из функций (в частности то, что она вызывает функции для движения персонажа, а вектор задается значениями -1 и 1 для X и Y), понял, что это скорее всего то, что мне нужно.

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

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

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Момент заливки прошивки в телефон — самый рисковый, когда все 280 секунд процесса ты лихорадочно изучаешь листинг ассемблера патча в прошивке... чтобы обнаружить, что ты где-то упустил прибавление единицы к адресу функции, поскольку у тебя Thumb (инструкция BX/BLX изменяет режим процессора с ARM на Thumb, если в первом бите адреса функции единица, а в момент прыжка — устанавливает первый бит на ноль и получает таким образом корректный адрес), и получаешь ребут на ровном месте :)

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

И вот! Спустя несколько перепрошивок всё запустилось! Моей радости просто не было предела! Далее я немного усложнил патч и вызывал функции для работы с файловой системой, дабы понять, какие буквы «диска» используются. Всё заработало и я получил файл "Privet5.txt"!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Первый патч!

Поскольку вручную патчить прошивку неудобно, а Vi_Klay не хватает скриптинга, я написал свой редактор патчей с поддержкой С#. Скрипты автоматизируют выполнение многих руинных задач: ищут функции по паттернам, формируют таблицу функций и скрипт линкера, а также патчат фуллфлэш.

using System;
using System.IO;
using MonoPatcher.Scripting;

public static class Script
{

public static void Run()
{
string baseDir = "D:/windows-arm-none-eabi-master/bin/fasolim/";

byte[] firmware = File.ReadAllBytes(baseDir + "firmware.bin");
Patcher.CopyFile(baseDir + "firmware.bin", baseDir + "patched.bin");

if(!File.Exists(baseDir + "bin/binloader.bin"))
{
Patcher.Log.WriteLine("binloader.bin does not exist");

return;
}

byte[] binloader = File.ReadAllBytes(baseDir + "bin/binloader.bin");

using(FileStream strm = File.OpenWrite(baseDir + "patched.bin"))
{

Patcher.Log.WriteLine("Patching game window handler function...");
int handlerOffset = FindWindowHandlerFunction(firmware);
int fmOffset = FindFileManagerFunction(firmware);

if(handlerOffset == -1)
{
Patcher.Log.WriteError("Window handler function not found");

return;
}

if(fmOffset == -1)
{
Patcher.Log.WriteError("FileManager function not found");

return;
}

//Patcher.Log.WriteLine(string.Format("P{0:X}", handlerOffset));

long firmwareEnd = strm.Length;
//Patcher.Append(strm, binloader);

if(firmwareEnd % 4 != 0)
{
Patcher.Log.WriteLine("Please align fullflash to border of 4");

return;
}

// Apply skip boot animation patch
//byte[] skipAnim = File.ReadAllBytes(baseDir + "patches/nopoweronanim.bin");
Patcher.Patch(strm, 0x252FE8, baseDir + "bin/nopoweronanim.bin");
Patcher.InsertNOP(strm, 0x9DC3C4); // Alignment
Patcher.Patch(strm, 0x9DC3C4, baseDir + "bin/fmpatch.bin");

PatchFileAssociation(strm, firmware);
Patcher.InsertNOP(strm, handlerOffset - 2); // Alignment
Patcher.Log.WriteLine("Function address: {0:X}", handlerOffset);
Patcher.Patch(strm, handlerOffset, binloader);

//Patcher.HookFunction(strm, handlerOffset, (int)firmwareEnd | 1, true); // Remember about THUMB!
}
}
}

❯ Разбираемся в подсистемах телефона

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

За открытие файлов отвечает функция MMIAPIFMM_OpenFile, которая получает из расширения его внутренний числовой тип. Сначала я думал что у менеджера файлов есть ассоциация расширений с MIME-типами и ассоциативный массив с обработчиками для разных типов файлов, но как оказалось, здесь у нас был большой свич-кейс, что одновременно и плохо с точки зрения красоты и производительности кода, и хорошо для реверс-инжиниринга (есть прямые референсы на функции).

PUBLIC void MMIAPIFMM_OpenFile(wchar *full_path_name_ptr)
{
uint16 full_path_name_len = 0;
uint16 suffix_len = MMIFMM_FILENAME_LEN;
wchar *suffix_wstr_ptr = PNULL;
MMIFMM_FILE_TYPE_E file_type = MMIFMM_FILE_TYPE_NORMAL;
MMIFILE_FILE_INFO_T file_info = {0};

full_path_name_len = MMIAPICOM_Wstrlen(full_path_name_ptr);


case MMIFMM_FILE_TYPE_EBOOK:
{
MMIFMM_ShowTxtContent(full_path_name_ptr);
}

В телефоне есть читалка электронных книг, но пользы от неё немного — кодировок поддерживает мало, выглядит невзрачно. Если захотим, то сами напишем эльф для чтения книг в .txt. Разработчики прошивки очень удачно написали функцию MMIFMM_ShowTxtContent, куда передается указатель на полный путь к нашему файлу, а значит, именно её мы и будем с вами хукать... но сначала сменим ассоциацию файлов с txt на app:

/* Patch description: Replace file association from .txt to .app to make possible hooking EBook with our code */
public static void PatchFileAssociation(FileStream strm, byte[] firmware)
{
int offset = Patcher.PatternSearch(firmware, "01 00 00 00 74 78 74 00");
byte[] ext = { (byte)'a', (byte)'p', (byte)'p' };

if(offset == -1)
{
Patcher.Log.WriteError("Failed to apply file-extension patch");

return;
}

Patcher.Patch(strm, offset + 4, ext);
}

Суть хука простая: мы «воруем» глобальную переменную (массив символов) у какой-то другой, неактивной в данный момент программы и храним в ней строку с путём к нашему эльфу, а затем запускаем окно хукнутой игры. Эльфлоадер стартует, берёт указатель на программу и загружает её, перенаправляя все события ей. Такой вот незамысловатый хук:

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

В процессе реверса функций для открытия окон в прошивке я нашел скрытое меню... с дополнительной игрой, которая есть в прошивке, но штатными способами до неё невозможно добраться!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

Далее я адаптировал бинлоадер на новый лад и по итогу у меня всё заработало...

...но до получения результата мне пришлось два дня подряд не спать всю ночь и сидеть до 5 утра ;)

uint32 readBytes = 0;
uint32 handle;

void** loadAddr = (void**)LOAD_ADDRESS_VARIABLE; // Also filemanager put absolute path to binary here
unsigned int* stateVariable = (unsigned int*)STATE_VARIABLE;

if(msgId == MSG_CLOSE_WINDOW || msgId == MSG_KEYDOWN_CANCEL || msgId == MSG_CTL_CLOSE)
{
MMKCloseWin(window);
*stateVariable = 0;
}

// FIT IN 294 BYTES!!!
if(*stateVariable != STATE_NUMBER)
{
// Initialization state: Load runtime from E:/rt.so to memory, store it's address into some global variable.
wchar_t* str = (wchar_t*)loadAddr;

handle = FileOpen(str, 0x31, 0, 0);

if(!handle)
goto err;

uint32 size = 0;
FileGetSize(handle, &size);
*loadAddr = Alloc(size, "m", 1);
if(!(*loadAddr))
goto err;

FileRead(handle, *loadAddr, size, &readBytes);

if(readBytes == 0)
goto err;

*stateVariable = STATE_NUMBER;
}
else
{
// Program state: MMI keep sending our hooked function events, we pass them directly to loaded program.
// The program can also pass execution to another program by swapping WindowFunc with pointer to loaded program.
LoaderContext ctx = {
__api_table,
loadAddr
};
WindowFunc func = (WindowFunc)(*loadAddr + 1); // Beware of THUMB

func(&ctx, window, msgId, dparam);
}

return 1;
err:
CreateDebugFile(u"D:/E");
return 1;

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

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

И залил экран желтым цветом:

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост
Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

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

public static ImportedFunction[] Functions = new ImportedFunction[]{
// File IO
new ImportedFunction("Alloc", "B5 F7 1C 07 25 00 37 19 B0 82", "void*", "unsigned int size, char* where, unsigned int lineNumber"),
new ImportedFunction("wstrlen", "1C 01 D1 00 47 70 88 0A", "uint32", "wchar_t* str"),
new ImportedFunction("FileOpen", "B5 FE 1C 05 09 08", "uint32", "wchar_t* fileName, uint32 accessMode, uint32 shareMode, uint32 fileAttributes"),
new ImportedFunction("FileRead", "B5 FF 1C 06 1C 17 1C 1D B0 85 9C 0E 21 00 A0 86 F7 FF F8 2F 1C 23", "uint32", "uint32 handle, void* buffer, uint32 bytesToRead, uint32* bytesRead"), // FileRead as well as FileWrite are similiar due to identical arguments
new ImportedFunction("FileWrite", "B5 FF 1C 06 1C 17 1C 1D B0 85 9C 0E 21 00 A0 8D F7 FF F8 09 1C 23", "uint32", "uint32 handle, void* buffer, uint32 bytesToWrite, uint32* bytesWritten"),
new ImportedFunction("FileClose", "B5 10 1C 04 A0 8A 21", "uint32", "uint32 fileHandle"),
new ImportedFunction("FileGetSize", "B5 B0 1C 05 1C 0C 21 00", "uint32", "uint32 fileHandle, uint32* fileSize"),
new ImportedFunction("MMKCloseWin", "B5 70 25 00 F1 A7", "uint32", "uint32 windowHandle"),

/*new ImportedFunction("TurnOffBacklight", "49 1D B5 10 20 02 60 C8", "void", "uint32 value"),
new ImportedFunction("AllowTurnOffBacklight", "B5 F1 B0 92 24 00 94 11", "void", "uint32 value"),
new ImportedFunction("SetKeypadBacklight", "B5 10 1C 04 1C 01 A0 F4", "void", "uint32 value"),
new ImportedFunction("AllowBacklight", "B5 B0 1C 04 1C 02 48 BF 4D A5", "void", "uint32 value")*/
};

Саму таблицу функций можно расположить в конце прошивки или в теле какой-нибудь BMP-картинки... Например так делали с телефонами Motorola:

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

❯ Заключение

Вот такой программный моддинг у нас с вами получился. Надеюсь, вам было интересно! На самом деле ничего сложного в такой модификации нет: у меня были на руках не совсем актуальные, но всё же исходники, а прошивка была собрана в дебаге и в ней было достаточно строк для подробного анализа. Более опытные реверсеры умудряются раскапывать прошивки с куда меньшим количеством документации и без дебаггера, а это значит, что есть куда расти!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

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

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статью) можно найти на моём YouTube канале.

Отдельное спасибо: @ILYA_ZX и @Andy51 за мотивацию, @Azq2и @EXL за советы, а также авторам IDA Pro и Ghidra за крутые инструменты! Без вас этой статьи бы не вышло.

Важно: друзья! Я уверен, что статью будут читать выходцы с форумов моддеров и возможно даже ребята, связанные с прошивочными боксами. Если у вас есть исходный код или объектные файлы для телефонов Siemens (S-Gold или E-Gold — не имеет значения) и вы хотели бы помочь общему моддерскому делу — напишите пожалуйста мне в Telegram. Несмотря на то, что этот код уже давно никому не нужен и E-Gold/S-Gold уже более 15 лет снят с производства, гарантирую полную анонимность и крутой контент :)

Как вам такой моддинг?
Всего голосов:
Как вам статья?
Всего голосов:

Очень важно! Разыскиваются девайсы для будущих статей!

Друзья! Если вам понравилась сегодняшняя статья про разработку эльфов, то спешу объявить: для подготовки будущих материалов с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я сейчас занимаюсь, а затем написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны на Linux (например Motorola EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E6, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!). Всем большое спасибо за донаты!

Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост
Motorola, Siemens... Как я хакнул бюджетный кнопочный телефон и научил его запускать "эльфы" - нативные программы на C Опрос, Покупка, Телефон, Гаджеты, Программирование, Реверс-инжиниринг, Fly, Моддинг, Хакеры, Смартфон, Гифка, Длиннопост

А ещё я держу все свои мобилы в одной корзине при себе (в смысле, все проекты у одного облачного провайдера) — Timeweb. Потому нагло рекомендую то, чем пользуюсь сам — вэлкам.

Показать полностью 25 2
[моё] Опрос Покупка Телефон Гаджеты Программирование Реверс-инжиниринг Fly Моддинг Хакеры Смартфон Гифка Длиннопост
74
71
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
3 месяца назад

А вы помните эту игру?⁠⁠

Колупаю и реверсю легендарный Samsung 2003 года с обалденным экраном! Кто догадается, почему встроенные игры тормозили, а Java-игрушки работали хорошо?

А вы помните эту игру? Телефон, Гаджеты, Samsung, Покупка, Моддинг, Игры, Видео, Короткие видео
Показать полностью 1
[моё] Телефон Гаджеты Samsung Покупка Моддинг Игры Видео Короткие видео
39
1245
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
4 месяца назад

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции⁠⁠

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Нет, это не шутка и не кликбейт. Такое действительно возможно - правда через небольшой хак.

Недавно я задался вопросом: а возможно ли написать для ARM нативную программу, которая будет бесшовно работать сразу на 4-х операционных системах без необходимости перекомпиляции для разных платформ и ABI. Мне очень хотелось реализовать возможность писать кроссплатформенные эльфы для мобильных телефонов из нулевых и попытаться портировать на них эмуляторы ретро-консолей. Погрузившись в документацию на исполняемые форматы, я пришёл к выводу, что да - это возможно и смог реализовать такую программу на практике без читерства по типу VM! Всех гиков приглашаю под кат!

❯ Зачем и почему?

Давным-давно, в далёком 2001 году, мир увидел легендарный японский телефон - Sony CMD-J70. Ещё до создания совместного подразделения с Ericsson, Sony выпускала достаточно занимательные девайсы, которые привлекали внимание не только рядовых пользователей, но и моддеров всех мастей. Уже через пару лет после выхода, в программном плане телефон копали все кому не лень: кто-то менял графику, кто-то писал патчи, а со временем написали даже бинлоадер (PRGLoader) - загрузчик внешних "экзешников", позволявший запускать на телефоне произвольный софт, написанный на ассемблере!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Сейчас сложно себе представить, но в те годы это был нереальный отвал башки: на большинстве телефонов были доступны разве что Java/Mophun-приложения, которые обладали ограниченным функционалом и уж тем более не позволяли лезть в дебри прошивки телефона, а здесь были программы которые буквально позволяли делать с телефоном всё что захочешь: светомузыку из подсветки, кастомные игры, обои на главный экран... всё это было доступно только на куда более дорогих смартфонах с Symbian и Windows Mobile на борту!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Недавно мы с вами вспоминали о легендарном Siemens M55 и узнали, что у него находится под капотом. Несмотря на диковинную архитектуру Infineon C166, даже под этот телефон делались патчи и была написана как минимум одна кастомная игра. Но рассвет моддинг-сцены Siemens произошёл с выходом платформы S-Gold на базе стандартного ядра ARM926EJ-S, когда в ~2004 году энтузиасты полностью взломали алгоритм генерации BootKEY для загрузчика, а затем в 2006 году реализовали полноценный эльфлоадер, который позволял загружать программы написанные на C и скомпилированные самым обычным компилятором ADS. В отличии от бинлоадера для CMD-J70, "эльфятник" позволял угонять функции RTOS для создания потоков и привносил в бюджетные телефоны полноценную вытесняющую многозадачность с настоящим диспетчером задач и возможностью запуска несколько программ одновременно:

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Единицы читателей поймут, что происходит на данной фотографии...

Энтузиасты раскапывали прошивку в дизассемблере, изучали её и пытались понять как работают разные её подсистемы. Результатом стало появление нативного клиента почты с предком пуш-уведомлений, аськи (NatICQ), порты самых разных эмуляторов ретро-консолей и даже полная программная поддержка MP3 в тех телефонах, где её отродясь не было! И представьте себе, почти все эти программы можно было свернуть и продолжить работу в браузере или, например, Card Explorer'е! Одним из эльфописателей был Хабровчанин @ilya_ZX

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Но если вы думаете что одними телефонами Siemens энтузиасты были едины, то вы ошибаетесь - ведь круче были только "моторолки"! В 2004-году, недорогая Motorola E398 с двумя громкими динамиками, светомузыкой и поддержкой MicroSD-флэшек, стала настоящим бестселлером и привлекла к себе не меньше энтузиастов, чем Siemens. Ребята сплотились на форуме MotoFan, нашли уязвимость в загрузчике и хакнули верификацию RSA-подписи у прошивок, позволив не только модифицировать Seem'ы (что-то типа NVRAM), но и создавать для телефона кастомные прошивки - монстрпаки, которые прибавляли громкость и без того не самым тихим динамикам и в различных аспектах изменяли главное меню устройства. Со временем, @Andy51 и ещё несколько энтузиастов реализовали эльфлоадер (EP1) для E398, раскопали прошивку и написали много полезного софта, время от времени переключаясь на Linux-телефоны от Motorola...

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Вероятно многие читатели подумают мол "было и было, мой айфон/сяоми может запускать любой произвольный софт и эти ухищрения давным-давно неактуальны...". Но как бы не так: про моторолки и сименсы не просто всё чаще вспоминают, у них есть до сих пор активное моддерское коммьюнити, которое продолжает пилить для них кастомный софт и далее колупать прошивку. Всё тот же @EXL портировал крутой софтрендер для E398 и в 2025 году наконец-то взломал C350, @Azq2 пилит аппаратный эмулятор Infineon S-Gold и многие другие делают свой вклад в моддинг сцену уже не таких мейнстримных, но отнюдь не устаревших устройств!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Однако порог вхождения для написания эльфов достаточно высокий: нет никакой отладки кроме printf, любая ошибка в приложении приводит к зависанию или ребуту телефона (на сименсах с характерным "пик"), а API напрямую импортируется из прошивки телефона и может быть достаточно комплексным - ни о каких кроссплатформенных эльфах и речи не идет. Поэтому в какой-то момент мне стало интересно: а возможно ли написать такой эльфлоадер, который за своим рантаймом будет прятать детали реализации работы с аппаратной начинкой телефона и при этом загружать один и тот же бинарник на всех поддерживаемых платформах без особых патчей и изменений? Принявшись за изучение ABI ARM и спецификации Elf, я начал дизассемблировать и изучать самые маленькие тестовые программы...

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

❯ Формат ELF, ABI ARM и тулчейн

Начнём с самого простого: что же такое эти самые эльфы? Elf - формат исполняемых файлов, широко применяемый как в мире Unix-систем, так и в embedded-устройствах. Самые распространенные тулчейны - GCC и clang/llvm, по умолчанию собирают программы именно в этом формате и по своей сути, это прямой аналог .exe (PE) файлов из Windows. Помимо кода, Elf также содержит в себе множество секций и различных данных, при этом разработчики формата старались сделать его настолько гибким, чтобы его можно было использовать на любых архитектурах: от x86, до risc-v.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

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

.text - хранит в себе код программы и обычно записывается в память с флагами MMU R X (чтение и выполнение)

.data - преинициализированные данные, имеет флаги R W (чтение и запись). Например, заполненная структура в C:

int a[] = { 1, 2, 3 };

.bss - не инициализированные данные, иными словами глобальные переменные, которые при старте программы должны быть забиты нулями. Имеет те же флаги, что и .data.

.rodata - различные константы: строковые, const-преинициализированные массивы, а также структуры и т.п, имеет только флаг R и на системах с MMU попытка запись в эту секцию повлечет SIGSEGV.

За загрузку всех этих секций отвечает загрузчик Elf в ядре ОС. Однако это справедливо только для простых программ, которые загружаются в фиксированный адрес виртуальной памяти и которые не используют внешние библиотеки (.so, аналог в Windows - .dll). Поскольку адрес загрузки для всех библиотек предсказать невозможно, разработчики ABI придумали позиционно-независимый код (PIC и его производное - PIE), который может загружаться в любую область памяти и оттуда выполняться.

Реализация PIC может достигаться тремя разными способами:

  • Первый способ заключается в использовании глобальной таблицы смещений (GOT) и релокаций. Релокации - специальные данные в Elf, которые позволяют переместить программу в другой адрес путём патчинга адресов в секции .got "на лету": иными словами, сам код (.text) остаётся позиционно-независимым (дабы библиотеку можно было загрузить один раз и использовать во множестве процессов) и обращается к GOT относительно PC, но в самом GOT (который представляет из себя массив void* addresses[]) указатели на остальные сегменты находятся так, будто программа загружается по смещению 0x0. Задача динамического линкера - посчитать абсолютный адрес для всех указателей в GOT: в простейшем случае, это got[address] += baseAddress.
    Релокации могут затрагивать сразу literal pools в обход GOT, если архитектура предусматривает их наличие.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост
  • Релокацией занимается динамический линкер или интерпретатор в мире Unix (тот самый ld.so, что часто "not found" :) ), а самих релокаций есть много разных видов в зависимости от архитектуры процессора. В ARM чаще всего встречается R_ARM_REL32

  • Второй способ заключается в том, что мы компилируем программу так, будто она должна загружаться по фиксированному адресу 0x0 - то есть без PIC, однако просим линкер (--emit-relocs) создать информацию о всех обращениях к памяти в виде всё тех же релокаций. Вместо R_ARM_REL32, линкер создаёт релокации R_ARM_ABS32, которые можно разрешить обычным сложением.
    С таким подходом количество релокаций кратно увеличивается, однако из-за отсутствия GOT немного повышается быстродействие программы (вместо трёх LDR для загрузки слова из памяти нужно всего два: из Literal pool в регистр и затем из фактической памяти).

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Пример релокаций для эмулятора NES

Третий способ поддерживается не везде, но в ARM он является одним из самых распространенных в embedded-среде: код собирается с флагами /rwpi и /ropi полностью не зависит ни от GOT, ни имеет каких либо релокаций. Вместо этого, для адресации базового адреса программы он использует выделенный регистр R9, который загрузчик должен заполнить адресом, куда он загрузил программу (mov r9, textSectionBase). Такой подход теоретически чуточку быстрее, чем GOT, но медленнее второго подхода из-за необходимости добавлять сложение регистра с PC перед каждым фетчем из памяти.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Поскольку в телефонах MMU обычно не используется, эльфлоадеры загружают программы по тому адресу, что им выделяет системный аллокатор памяти и вынуждены использовать PIC. Чаще всего используются релокации (как минимум на Siemens и Motorola), на некоторых платформах используется второй подход с использованием регистра R9.

Для большей гибкости, я решил выбрать второй подход и построить свой эльфлоадер поверх уже существующих загрузчиков, обернув API прошивок в ряд собственных стандартизированных функций: работа с дисплеем, вводом, файлами, а также звуком. При этом эльфы должны собираться современным компилятором clang с поддержкой C99, чтобы была возможность легко портировать современные single-header программы по типу эмуляторов, да и в целом не писать код на манер Ansi C, когда переменную нигде нельзя объявить кроме начала блока.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Далее я сутками игрался с компиляторами и пытался заставить выдать их подходящий для моих целей код и по итогу написал скрипт для линкера, который для простоты загрузки файла объединяет все секции в один .text (таким образом остаётся всего один Program Header):

OUTPUT_FORMAT("elf32-littlearm")
SECTIONS
{
. = 0x0;
.text : {
*(.r9ptr)
*(.text*)
*(.data*)
*(.bss*)
*(.rodata*)
*(.functions)
}

.rel : {
*(.rel*)
}

/DISCARD/ : {
*(.ARM.*)
}

}

И следующий набор опций для компилятора, который устанавливает архитектуру и целевой процессор, ABI для FPU, включает генерацию релокаций и отключает выравнивание в линкере для выходного файла (иначе файлы забиты нулями и весят целых 64Кб:

CLANGFLAGS = -mno-unaligned-access -O3 -ffast-math -ffixed-r9 -T ld.script -target armv5e-none-eabi -nostartfiles -fno-exceptions -fno-rtti -mfloat-abi=soft -I$(ELFROOT) -Ilibnesemu/
LDDFLAGS = -Wl,-zmax-page-size=1,--emit-relocs

Когда компилятор наконец-то начал выдавать корректный код, я принялся писать сам эльфлоадер. За качество кода и отсутствие нормальной структуры не ругайте - это эмбеддед, тут можно ;))

На входе лоадеру поступает адрес загруженного в память эльфа и его длина. Задача эльфятника - верифицировать заголовок и убедится что он собран с подходящими параметрами:

// Read and verify ELF header
Elf32_Ehdr* hdr = (Elf32_Ehdr*)data;

PRINT("Loading ELF...");
if(hdr->e_machine != EM_ARM)
{
PRINT("Not an EM_ARM executable");

return 0;
}

if(hdr->e_ident[EI_DATA] != PLATFORM_ELF_ENDIANESS)
{
PRINT("Endianess mismatch");

return 0; // Wrong endianess
}

Проанализировать таблицу заголовков с служебной информацией о том, что находится по тому или иному смещению в файле: загружаемая секция, таблица символов или строк, а затем загрузить все секции в участок памяти, который нам выдал аллокатор. На MMU-системах адрес должен быть выровнен по размеру страницы, иначе система не даст выдать страницам флаг EXEC!

ret = (ExecInfo*)ExecAlloc(sizeof(ExecInfo));

sections = (Elf32_Phdr*)(&data[hdr->e_phoff]);
sh = (Elf32_Shdr*)&data[hdr->e_shoff];
symSectionIndex = hdr->e_shstrndx;
codeSize = 0x0;

PRINT("Processing program headers");
// Process program headers and determine total size
for(i = 0; i < hdr->e_phnum; i++) {
Elf32_Phdr hdr = sections[i];

if(hdr.p_type == PT_LOAD) {
if(hdr.p_offset == 0x0)
continue;

codeSize += hdr.p_memsz;
}
}

PRINT("Allocating memory for .text");

textSection = (char*)ExecAlloc(codeSize);
textOffset = textSection;

ret->CodeSection = textSection;

if(!textSection)
{
free(ret);
PRINT("Failed to allocate .text section");

return 0;
}

Далее найти секцию с таблицей символов и с строками, где содержатся имена символов:

PRINT("Analyzing section table");
for(i = 0; i < hdr->e_shnum; i++)
{
Elf32_Shdr sec = sh[i];

if(sec.sh_type == SHT_STRTAB && i != hdr->e_shstrndx && strTable == 0)
{
strTable = &data[sec.sh_offset];
PRINT("Found string table");
}

if(sec.sh_type == SHT_SYMTAB)
{
PRINT("Found symbol table");
symbols = (Elf32_Sym*)&data[sec.sh_offset];
symNum = sec.sh_size / sizeof(Elf32_Sym);
}

if(sec.sh_type == SHT_REL && relocs == 0)
{
UtilPrint("Found relocations");
relocs = (Elf32_Rel*)&data[sec.sh_offset];
relNum = sec.sh_size / sizeof(Elf32_Rel);
}

if(sec.sh_type == SHT_RELA)
{
PRINT("Found unsupported relocation types");
return 0;
}
}

if(!strTable || !symbols)
{
free(ret);
PRINT(".strtab or .symtab not found");

return 0;
}

А затем найти функцию ElfMain, которая служит точкой входа и пропатчить таблицу импортированных функций! На этом, загрузка эльфа завершена - можно устанавливать регистр R9 и вызывать Main!

PRINT("Relocation fix-up");
for(i = 0; i < relNum; i++)
{
Elf32_Rel rel = relocs[i];
int sym = ELF32_R_SYM(rel.r_info);

switch(ELF32_R_TYPE(rel.r_info))
{
case R_ARM_ABS32:
*((unsigned int*)&textSection[rel.r_offset]) += (unsigned int)textSection;
break;
case R_ARM_JUMP24:
break;
case R_ARM_CALL:
break;
default:
PRINT("Unsupported relocation type");
}
}

PRINT("Patching import table");

// Analyze symbol table and patch all imported function pointers to real counterparts
for(i = 0; i < symNum; i++)
{
Elf32_Sym sym = symbols[i];
uint8_t* symName = &strTable[sym.st_name];

int symType = ELF32_ST_TYPE(sym.st_info);

if(symType == STT_OBJECT && strstr((const char*)symName, "SYS_"))
{
int funcNumber = ExecFindFunction(symName);

if(funcNumber == -1)
{
PRINT("Failed to import function: ");
UtilPrint((char*)symName);
PRINT("");

continue;
}

//drawDebug(FuncExportTable[funcNumber].Pointer == 0 ? "Not OK" : "OK");

*((unsigned int*)&textSection[sym.st_value]) = (unsigned int)FuncExportTable[funcNumber].Pointer;
}

if(symType == STT_FUNC && strstr((const char*)symName, "ElfMain"))
{
PRINT("ElfMain function is found");

ret->Main = (ExecMainFunction)&textSection[sym.st_value];
}

В Elf уже есть механизм импорта функций из сторонних библиотек, называется Platform Linkage Table. Для импорта функций прошивки, эльфлоадер Siemens использует SWI (сисколлы, что-то типа программных прерываний в x86 - int 10h и т.п.), Motorola же патчит thunk-функции на лету, которые сами вызывают настоящую функцию:

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

А я решил поступить несколько изящнее. В моем эльфятнике, функции импортируются с помощью специального макроса, который создаёт переменную-указатель на функцию, который изначально располагается в секции .functions. При этом с помощью ключевого слова asm, символу присваивается иное имя - с префиксом SYS_, которое означает то, что загрузчик эльфа должен пропатчить адреса функций на реальные (которые предварительно зарегистрированы в рантайме) в процессе загрузки программ и таким образом, избежать thunk-функций и позволить оптимизатору легко выкидывать указатели на неиспользуемые функции:

#ifndef LOADER
#define IMPORT(name, ret, ...) __attribute__ ((section(".functions"))) ret (* name )( __VA_ARGS__ ) asm( "SYS_" #name )
#define IMPORTNOARGS(name, ret) __attribute__ ((section(".functions"))) ret (* name )() asm( "SYS_" #name )
#else
#define IMPORT(name, ret, ...) ret name( __VA_ARGS__ )
#define IMPORTNOARGS(name, ret) ret name()
#endif

Что самое забавное, лучший способ отладить эльфлоадер - в QEMU с GDB под Linux. Однако я решил время не терять и отлаживал его сразу на смартфоне с Windows Mobile. А раз WM стал первой поддерживаемой платформой - на нем мы с вами и реализуем рантайм.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

❯ Портируем на Windows Mobile (CE)

Поскольку всю жизнь я сижу в основном на Windows, а WinAPI в CE практически полностью копирует десктопную версию, никаких проблем с портированием рантайма не возникло. Единственный выбор который передо мной встал: стоит ли прокидывать stdlib из хост-системы в "эльфятник", или же воспользоваться реализацией newlib в clang/gcc. В процессе портирования на другие платформы выяснилось, что нормально libc реализован, по сути, только на Windows, во все остальных реализациях были лишь самые основные функции по типу malloc, free, memcpy, strcmp и т.п. Поэтому я решил не городить велосипеды и прокинул из хост-системы лишь аллокатор - т.е malloc и free:

// stdlib
IMPORT(elf_malloc, void*, int size);
IMPORT(elf_free, void, void* ptr);
/*IMPORT(elf_strcmp, int, char* str1, char* str2);
IMPORT(elf_strcpy, char*, char* dst, char* src);
IMPORT(elf_strlen, int, char* str);
IMPORT(elf_strstr, char*, char* string, char* substring);
IMPORTNOARGS(elf_rand, int);
IMPORT(elf_memcpy, void*, void* dst, const void* src, uint32_t length);
IMPORT(elf_memset, void*, void* dst, int what, uint32_t length);
IMPORT(elf_memmove, void*, void* dst, void* src, uint32_t length);*/

Далее я сразу решил, что платформозависимые функции для работы с дисплеем использовать не буду и из хост-системы мне нужен будет лишь указатель на фреймбуфер, а блиттинг, рисование текста и прочие операции я реализую сам. На первый взгляд может показаться что это единственное верное решение, однако на практике в некоторых телефонах (Motorola E398, Razr V3) активно использовались 2D GPU от ATI и Nvidia, которые рисуют (BitBLT) изображение значительно быстрее любой программной реализации.

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

for(i = 0; i < bitmap->Height; i++)
{
for(j = 0; j < bitmap->Width; j++)
{
LCD_PLOT_565(clamp(x + j, 0, lcd->Width), clamp(y + i, 0, lcd->Height), bmp[i * bitmap->Width + j]);
}
}

С точки зрения отрисовки текста, нативные функции платформ тоже предоставляют крутые фичи по типу сглаживания, поддержки не-моноширинных шрифтов, множества кодировок, а также различные типы выравнивания. Но здесь встаёт вопрос с портативностью таких решений: разные рендеры шрифтов оперируют по разному и не все из них используют в качестве системы координат пиксели. Соответственно, я пошёл по олдовому "эмбеддерскому" пути и сделал обычные битмапные шрифты, которые (пока) статически слинкованы с самим эльфятником.

__inline int LcdDrawChar(LcdInfo* lcd, char chr, uint32_t x, uint32_t y, uint16_t color)
{
if(x >= 0 && y >= 0 && x + FONT_WIDTH < lcd->Width && y + FONT_HEIGHT < lcd->Height)
{
int i, j;
unsigned char* glyph = &embedded_font[chr * 8];

for(i = 0; i < FONT_HEIGHT; i++)
{
short* fb = &((short*)lcd->Pixels)[(y + i) * lcd->Width + x];

for(j = 0; j < FONT_WIDTH; j++)
{
if((*glyph >> (FONT_WIDTH - j)) & 0x1)
*fb = color;

fb++;
}

glyph++;
}

return true;
}

return false;
}

void LcdDrawString(LcdInfo* lcd, char* str, uint32_t x, uint32_t y, uint16_t color)
{
SWITCH_CONTEXT;
if(lcd && x >= 0 && y >= 0)
{
unsigned int i;

for(i = 0; i < strlen(str); i++)
{
if(!LcdDrawChar(lcd, str[i], x, y, color))
return; // Out of screen

x += FONT_WIDTH;
}
}
END_CONTEXT;
}

Отладив эльфлоадер, я написал небольшую тестовую программу для вывода картинки и текста:

#include <system.h>

int ElfMain(void* ptr)
{
LcdInfo* lcd = lcdInit();

lcdDrawBitmap(lcd, bitmap, 0, 0);
lcdDrawString(lcd, "Test", 0, 0, COLOR_BLUE)

return 100;
}

И получил следующий результат:

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Вот теперь всё работает! Пришло время портировать эльфятник на весьма необычную платформу, о потенциалах моддинга которой знают единицы...

❯ Портируем на MRP/MRE

И имя этой платформе, вернее даже двумя платформам - MRP и WRE. Эти платформы использовались на бюджетных китайских телефонах с 2007 по 2016 год. Встретить их можно было везде: легендарная Nokla TV E71/E72, клоны 6700, бюджетные телефоны Fly/Explay/DEXP и даже в оригинальных телефонах Nokia на платформе S30+ (например 230)!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Легендарная "нокла"!

И хотя люди часто считали такие устройства бесполезными в плане установки сторонних приложений, многие ранние "нонейм"-телефоны поддерживали запуск нативных программ через небольшой костыль - установку специального "загрузчика" dsm_gm.mrp и ввод комбинации *#220807# в номеронабиратель. Конечно, знали об этом костыле единицы и в 2010 году MediaTek решила сделать свою платформу под названием MRE (MAUI Runtime Environment), приложения для которой можно было запускать прямо из проводника без установки! SDK для обеих платформ сейчас свободно лежит в сети.

Обе платформы, по сути, занимаются тем же самым, что и мой эльфятник - прокидывают нативные функции MMI (оболочка телефона) в приложения и для загрузки позиционно-независимых программ используют третий подход с регистром R9, который обязательно необходимо где-то хранить и восстанавливать. Изначально мой эльфятник использовал такой же подход, из-за чего я написал отдельный костыль для "свичнга" контекстов, причем восстановление R9 я делал в отдельной функции из-за бага ассемблера в ADS:

#define SWITCH_CONTEXT unsigned int staticBase; __asm { MOV staticBase, sb;
LDR r0, [sb];
MOV sb, r0 }

#define ELF_CONTEXT(ptr) unsigned int staticBase; void* elfStaticBase = ptr; __asm { MOV staticBase, sb; \
MOV r9, elfStaticBase }

#define END_CONTEXT RestoreSB(staticBase);

Но я не учел то, что MMI хоть и построены по event-based принципу, в них нельзя так просто взять и сделать while(true) {}, а необходимо использовать таймеры, что влечет за собой постоянные костыли с свичингом контекстов что по итогу только снижает производительность. По итогу я перешел на релокации и реализовал проброс таймеров.

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

Никаких отладчиков, программа что-то записала не туда? Ребут и сиди, отлаживай с printf!

Во всем остальном, MRP и MRE простые как табуретка, никаких проблем с пробросом ввода и графики не возникло:

LcdInfo* LcdInit()
{
LcdInfo* ret;
ret = (LcdInfo*)malloc(sizeof(LcdInfo));
ret->Width = screenInfo.width;
ret->Height = screenInfo.height;
ret->Pixels = (void*)w_getScreenBuffer();

return ret;
}

void LcdFree()
{

}

void LcdLock(LcdInfo* info)
{

}

void LcdFlush(LcdInfo* info)
{
mrc_refreshScreen(0, 0, 240, 320);
}

И вот, наша программа уже запускается на двух совершенно разных ОС без каких либо проблем!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

❯ А если что-то посложнее Hello, world?

Наверняка у читателя возникнет вопрос мол "окей, твой эльфятник может и способен запускать простые программы, но как насчет чего-то посложнее?". И конечно-же, для тестов я решил портировать не абы что, а целый эмулятор NES! В конце-концов, одна из целей разработки такого эльфятника - возможность запускать Java-игр и эмуляторов на многих кнопочных телефонах из нулевых.

Какое то время назад, я обнаружил весьма шустрый эмулятор NES от неизвестного разработчика из Китая. Код был неважного качества, никаких копирайтов в нём не было. Но поскольку сам эмулятор был быстрый (быстрее, наверное, только vNesC, который является прямым source-портом Java-эмулятора vNes на C), я отвязал его от целевой платформы и превратил в небольшую библиотеку для легкого портирования на любые платформы путем вызова всего нескольких функций:

typedef struct {
uint16_t* FrameBuffer;
uint8_t* JoyState;
} emuContext;

emuContext* emuInitialize();
uint8_t emuLoadROM(void* rom, int length);
void emuReset();
void emuDoFrame();
void emuShutdown();

И, соответственно, базовый порт на наш эльфятник выглядит примерно так:

#include <string.h>

#define FUNC_PROTOTYPES
#include <system.h>

#include <nes.h>
#include "nes_rom.h"

emu_context* ctx;
LcdInfo* lcdInfo;

void EmuTick()
{
emuDoFrame();

LcdLock(lcdInfo);
short* pixels = (short*)lcdInfo->Pixels;

for(int i = 0; i < EMU_FRAMEBUFFER_HEIGHT; i++)
{
memcpy(&pixels[i * lcdInfo->Width], &ctx->FrameBuffer[i * EMU_FRAMEBUFFER_WIDTH], lcdInfo->Width * 2);
}

LcdFlush(lcdInfo);

}

void EmuSetupTimer()
{
TimerAttach(1, EmuTick); // As fast as possible
}

void EmuSetupRegularLoop()
{
while(true)
EmuTick(); // TODO: If elfloader port will be usable on Android, add FPS limit :)
}

int ElfMain(unsigned int* basePtr, void* test)
{
lcdInfo = LcdInit();

ctx = emuInitialize();
if(!emuLoadROM(nes_rom, sizeof(nes_rom)))
{
UtilPrint("Failed to load ROM");
return 100;
}

emuReset();

switch(GetMainLoopType())
{
case PLATFORM_LOOP_MMI_TIMER:
EmuSetupTimer();
break;
case PLATFORM_LOOP_REGULAR:
EmuSetupRegularLoop();
break;
}

return 100;
}

А вот и результат:

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост
Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост
Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

❯ Заключение

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

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статью) можно найти на моём YouTube канале.

Очень важно! Разыскиваются девайсы для будущих статей!

Друзья! Если вам понравилась сегодняшняя статья про разработку эльфов, то спешу объявить: для подготовки будущих материалов с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я сейчас занимаюсь, а затем написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост

А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны на Linux (например Motorola EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E5, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!). Всем большое спасибо за донаты!

Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост
Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции Смартфон, Телефон, Покупка, Гаджеты, Программирование, Моддинг, Эльфы, Linux, Unix, Операционная система, Реверс-инжиниринг, Siemens, Моторола, Ностальгия, Длиннопост
Показать полностью 25
[моё] Смартфон Телефон Покупка Гаджеты Программирование Моддинг Эльфы Linux Unix Операционная система Реверс-инжиниринг Siemens Моторола Ностальгия Длиннопост
135
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии