Показаны сообщения с ярлыком hacking. Показать все сообщения
Показаны сообщения с ярлыком hacking. Показать все сообщения

суббота, 14 марта 2009 г.

Ядро linux для Loox N560/C550 с рабочим CPLD и светодиодами

Добавил поддержку CPLD и светодиодов. Для CPLD был заюзан драйвер htc-gpio с перечислением адресов регистров CPLD на Fujitsu-Siemens Loox 5XX (N560/C550). Теперь CPLD доступен для других драйверов.

Примечательно, как в Linux'е реализована работа с CPLD. По сути, CPLD это чип, содержащий очень простую логику (за счет чего он очень быстр по сравнению с CPU), имеющий входные и выходные "ножки" (pins). Входные и выходные ножки - регистры - проецируются на определенную область памяти CPU. С логической точки зрения работа с CPLD заключается в переключении битов в регистрах CPLD в 0 или 1 (можно еще и читать оттуда, но я об этом тут не буду рассказывать..). Таким же образом выглядит работа с GPIO - общим вводом/выводом CPU: биты регистров CPU таким же образом принимают значение 0 или 1. В ядре Linux уже имеется драйвер GPIO, предоставляющий функции для работы с GPIO разработчикам платформенных драйверов. Также драйвер GPIO имеет механизм расширения, позволяющий другим драйверам/модулям проецировать заданные интервалы портов GPIO таким образом, что при обращении к такому порту произойдет вызов указанных при проецировании функций. Этот механизм используется CPLD драйвером htc-egpio для проецирования CPLD регистров на GPIO порты. Таким образом работа с CPLD идет через обыкновенные методы типа gpio_set_value.
На основе работающиго CPLD драйвера для Loox N560/C550 реализовал драйвер управления светодиодами КПК. Драйвер экспортирует методы и константы которые другие драйвера (wifi, gps, bluetooth, pm, ...) должны использовать для управления светодиодами. Также драйвер позволяет контролировать светодиоды из userspace пространства путем манипуляций с файлами sysfs.

Ниже перечисленны файлы и значения которые могут находиться:
/sys/devices/platform/loox5xx-leds.1/keyboard: on, off, any
- подсветка клавиатуры

/sys/devices/platform/loox5xx-leds.1/left_green: on, off, any
- зеленый светодиод с левой стороны. WM5 использует для индикации активности WiFi

/sys/devices/platform/loox5xx-leds.1/left_blue: on, off, any
- голубой светодиод с левой стороны. WM5 использует для индикации активности Bluetooth

/sys/devices/platform/loox5xx-leds.1/left_orange: on, off, any
- оранжевый светодиод с левой стороны. WM5 использует для индикации активности GPS на Loox N560

/sys/devices/platform/loox5xx-leds.1/right_green: on, off, any
- зеленый светодиод на правой стороне КПК. WM5 использует как светодиод доступный приложениям (нотификации и т.д.)

/sys/devices/platform/loox5xx-leds.1/right_orange: on, off, blink, any
- оранжевый светодиод с правой стороны КПК. WM5 использует для индикации процесса зарядки

Где:
on - светодиод включен независимо от желаний ядра,
off - светодиод выключен независимо от желаний ядра,
blink - светодиод мигает независимо от желаний ядра,
any - светодиод контролируется ядром.

Например, если установить right_orange в состояние on, то светодиод зарядки будет гореть независимо от того, заряжается КПК или нет. Это будет продолжаться до тех пор, пока в файл right_orange не будет записано значение any. После чего, первое же событие (установка КПК в крэдл и т.д.) переключит светодиод в соответствующее состояние. Sysfs интерфейс для светодиодов позволяет использовать светодиоды из программ для нотификации о событиях (пришла почта, кончается заряд и т.д.) с помощью всех доступных на устройстве светодиодов - насколько хватит фантазии. Например следующий shell код мигает подсветкой клавиатуры:

while true;
do echo on > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
echo off > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
# Condition for break...
done
echo any > /sys/devices/platform/loox5xx-leds.1/keyboard;


Актуальный патч на cupcake ядро андройда качать здесь.

суббота, 7 марта 2009 г.

Ядро linux для Loox N560/C550 с рабочим usbnet'ом

После 3х дней мучений все-таки собрал ядро linux для Fujitsu-Siemens Loox N560/C550. Ядро брал с http://www.asm32.ru. Потратив еще несколько часов разобрался как запустить usbnet (сеть через обычный usb шнурок). Для этого пришлось дополнительно пропатчить pxa27x_udc.c. Сделал diff между текущей версией ядра андройда и теми исходниками (за 02-03-09), что выложены на asm32. В дальнейшем при обновлении ядра в cupcake'овской ветке можно будет просто накладывать этот патч сверху имея в результате и изменения под c550/n560 и исправления/дополнения внесенные в cupcake ветку. Вот итоговый патч в который также включены изменения для работы usbnet. В патче уже имеется .config, но там не включена поддержка usbnet. Вот другой config, он отличается от того, что в патче (а там тот, что выложен на asm32) поддержкой usbnet, выключенной power management (зачем не знаю, потом надо будет включить обратно), и настройкой для более крупного шрифта в консоли.. может еще чем-то.

Собирать ядро можно с помощью любого toolchain'а. Я пробовал собирать с помощью: crosstool-ng, emdebian, а также того, что идет вместе с ядром андройда. Остановился на emdebian'е. Для сборки ядра emdebian'ом необходимо выполнить:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Предварительно emdebian конечно же нужно установить, например так:

apt-get install emdebian-tool
emsetup --arch arm
Добавить:

deb http://www.emdebian.org/debian/ unstable main

в /etc/apt/sources.list и выполнить:
apt-get install linux-kernel-headers-arm-cross gcc-4.2-arm-linux-gnu


Готовое ядро запускается haret'ом с конфигом:

set MTYPE 1454
set KERNEL zImage
set CMDLINE "root=179:2 mem=60M rootdelay=3 boot_delay=0 init=/init console=tty0 fbcon=rotate:0 androidboot.console=tty0 android.checkjni=1"
set RAMADDR 0xA0200000
bootlinux

И самое главное! После того, как ядро закинуто на sd карточку, эту sd карточку нужно вставить в КПК и ребутнуть КПК. А уже только после этого грузить haret'ом ядро! Ибо ядро не грузится (либо грузится с вероятностью 10%), если:
1. КПК заснула, а потом ее разбудили.
2. Вы только что вставили в КПК карточку.
Наверное это бага драйвера wince...

P.S. Cupcake на который накладывается выложенный патч качается отсюда http://source.android.com/download

P.P.S. При сборке с поддержкой usbnet опцию CONFIG_USB_ETH_RNDIS
включать не следует! Ибо в этом случае ПК не может нормально соеденится с КПК.. ни cdc_ether ни cdc_subset не видят usb устройство.

понедельник, 21 января 2008 г.

WayBack

Иногда возникает необходимость запустить приложение не в настоящем времени, а в прошлом или будущем. Обычно это нужно для тестирования приложения или для обхода устаревания evaluation license. Достигается это переводом системных часов, либо запуском приложения в vmware - оба этих метода имеют свои очевидные недостатки. К счастью в linux есть такая замечательная вещь как LD_PRELOAD, позволяющяя "переопределить" импортируемые функции приложения. Так, например, если подменить time, gettimeofday и clock_gettime - то программа с большой долей вероятности будет жить в том времени который нам нужен, в то время как вся остальная система будет жить в обычном временном русле. Для этих целей я написал небольшую C'ную библиотеку. Устанавливается библиотека как обычно make install.

Для примера, небольшое тестовое приложение на C:

void main () {
printf ("%lu\n", time(0));
}

Запускаем:

akshaal@...:/tmp% ./test
1200947571

akshaal@...:/tmp% WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test
63225

akshaal@...:/tmp% WAYBACK_LOG_LEVEL=3 WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test
Delta time: 3094082896
time modified
63257


Библиотека libwayback не возвращает константу. После запуска, она определяет разницу между текущим временем и желаемым и запоминает ее как delta. В дальнейшем все вызовы к функция возвращающим время перехватываются и delta прибваляется к результату. Таким образом время не стоит на месте и в то же время она очень близко к желаемому.

Например приложение на Java и стандартная утилита date:

import java.util.Date;

public class test {
public static void main (String[] args) {
System.out.println (new Date());
}
}

akshaal@...:/tmp% java test
Mon Jan 21 22:39:26 EET 2008

akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 java test
Sat Nov 27 20:40:39 EET 2010

akshaal@...:/tmp% date
Mon Jan 21 22:41:20 EET 2008

akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 date
Sat Nov 27 20:41:50 EET 2010


К сожалению данный способ может быть использован для обхода устаревания лицензии :) у программ к которым есть evaluation license ограниченная на определенный срок (например JProfiler 5, YourKit Profiler 7, InteliJ Idea и еще много). Я не проверял работает ли (но уверен, что да :) ) ибо предпочитаю опенсоурс софт и вообще это плохо и я против использования библиотеки для этих целей :).

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

Библиотека написана за час и не является Абсолютным Решением. Кому надо - юзают на свой страх и риск, а с меня никакого спросу.

P.S. Больше всего напарился с одной вещью. Запускаю свинговое приложение, а оно виснет. Думаю че за нахрен. Копался-копался... оказывается java юзает pthread_condwait и ей в качестве параметра передается не относительное время (время когда ожидание прекращается), а абсолютное! Пришлось и эту функцию переопределить и вычитать дельту. Но как я искал.. strace говорит, что нить висит на futex каком-то.. и только чудом догадался, что futex может быть более нижним лаером под pthread'ом, а там уже полез смотреть как работа с X'ами идет в libawt.

суббота, 10 июня 2006 г.

Joyemu v3. Пишим сложный патч для телефона на C. Информация должна быть свободной.

Еще одной записью в TODO сегодня стало меньше, после новой версии патча, выпустить которую у меня наконец-то дошли руки. Что изменилось:
1. Теперь при включении режима эмуляции джойстика светодиоды в верхней части телефона горят и горят до выхода из эмуляции. Благодаря этому всегда понятно в каком мы сейчас режиме.
2. Нажатие на софт кнопки ничего не эмулирует. Иногда их надо нажимать, не выходя из эмуляции.
3. Блокировка клавиатуры эмуляцию выключает.

Новая версия патча в формате vkp.

Вопреки сложившейся традиции с форума сайта http://allsiemens.com я выложу и исходники патча, и все функции прошивки Siemens CX65 sw50, которые мне удалось найти (более 400), расскажу как писать патчи на C. Я не придерживаюсь мнения, что каждый новичок должен найти все эти функции сам - этот подход мне кажется бесполезной тратой времени, которое человек мог бы направить на что-то полезное, а не изобретать велосипед. Я также не сторонник подхода, когда создается элитарный клуб, между людьми которого передается информация - мне это несколько противно. Информация должна быть свободной.

Тем не менее, эта информация не освобождает от необходимости знать Assembler ARM.

Пишем патч на C на примере Joyemu.
При написании сложнофункциональных патчей некоторая логика может быть написана на C.
Так, например, при эмуляции джойстика (я рассказывал в первом посте на эту тему) телефона мы имеем множество ветвлений в алгоритме, реализовать которые можно и на ассемблере, но проще и чище это сделать на C.

Первое, что делает joyemu - перехватывает нажатие на клавишу. Для этого мы ищем в прошивке тот участок кода, который обрабатывает это событие. Нашли, допустим, по адресу ORIGINAL_KEY_HANDLER. Теперь надо найти свободное место в прошивке под наш код, который будет обрабатывать это нажатие (ищем в прошивке длинную последовательность FF). Пускай наш обработчик должен быть по адресу OUR_KEY_HANDLER. Передать управление на наш обработчик при нажатии на клавишу можно двумя способами. Найти все места из которых происходит переход в ORIGINAL_KEY_HANDLER. И заменить на переходы на OUR_KEY_HANDLER. Так обычно никто никогда не делает, ибо мест таких может быть много. Мы же вставляем по адресу ORIGINAL_KEY_HANDLER инструкцию для загрузки в регистр PC адрес OUR_KEY_HANDLER. То, что мы затерли этими инструкциями запоминаем, оно нам пригодится, когда мы захотим вызвать оригинальный обработчик. А код, который находится за нашей инструкцией перехода на OUR_KEY_HANDLER, будет иметь адрес ORIGINAL_KEY_HANDLER_CHUNK.
Получается вот что:

ROM:A121D4BC ORIGINAL_KEY_HANDLER:
ROM:A121D4BC 04 F0 1F E5 LDR PC, =OUR_KEY_HANDLER
ROM:A121D4C0 10 F3 65 A1 DCD OUR_KEY_HANDLER
ROM:A121D4C4 ORIGINAL_KEY_HANDLER_CHUNK:


А так как в алгоритме эмуляции нам понадобится вызов оригинального обработчика нажатия, то для этого надо где-то разместить тот самый затертый код, после которого вставить переход к ORIGINAL_KEY_HANDLER_CHUNK. Разместим этот код сразу перед
OUR_KEY_HANDLER по адресу MOVED_ORIGINAL_KEY_HANDLER. Выглядит это вот так (сначала идут 8 оригинальных байт, потом 4 байта инструкции перехода, после 8 байт данных для инструкций):

ROM:A165F2FC MOVED_ORIGINAL_KEY_HANDLER:
ROM:A165F2FC 70 40 2D E9 STMFD SP!, {R4-R6,LR}
ROM:A165F300 04 10 9F E5 LDR R1, =off_A8663120
ROM:A165F304 04 F0 1F E5 LDR PC, =ORIGINAL_KEY_HANDLER_CHUNK
ROM:A165F308 C4 D4 21 A1 DCD ORIGINAL_KEY_HANDLER_CHUNK
ROM:A165F30C 20 31 66 A8 DCD off_A8663120
ROM:A165F310 OUR_KEY_HANDLER:


Сохраняем изменения как vkp patch. Для этого в интернете валяется IDC скрипт для IDA, а также инструкции.

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

Теперь осталось только наш обработчик написать. Работа с ассемблером на этом заканчивается, на сцену выходит C. Для компиляции я использовал пакет gcc-4.1-arm для Debian. Начну с описания опций необходимых для компиляции под телефон:
-c -- делает объектный файл.
-mcpu=arm926ej-s -- компилировать под указанный процессор. Именно эти процы стоят в Siemens x65.
-mthumb-interwork -- компилировать инструкции дальнего перехода с учетом бита отвечающего за ARM/THUMB режим работы процессора. Короче вместо B и BL будет BX и BLX.
-fomit-frame-pointer -- а нафик он нужен?
-fno-unit-at-a-time -- это чтобы откомпилированные функции в объектном файле были в том же порядке, в котором они были в исходниках.
-mlong-calls -- ну длинные переходы типа.
Прочие опции типа -Wall -Os или -O3 - это на усмотрение.

Допустим мы написали C файл. Скомпилировали его с вышеперечисленными опциями в объектный файл. Теперь его надо слинковать в исполняемый файл elf. Это маленькое извращение нужно для того, чтобы линкер привел все relocation'ы в норму и разместил все по тем адресам, которые мы ему скажем. Нет, конечно можно при компиляции указать -fPIC и получить оверхеадный код, но мы пойдем другим путем. Опции линкера:
-s -- удаляет всю символьную информацию. А нафик она?
-nostdlib -- Не прилинковывать никаких левых библиотек.
-Bstatic -- Эта опция говорит о том, что все релокейшены будут жестко забиты. Никаких динамически подгружаемых библиотек. Статическая компиляция.
-X -- Забыл уже зачем добавил. Но наверное надо. Пусть будет.
-entry 0 -- стартовый адрес. 0 - адрес первой функции первого объектного файла.
-R local.symbols -- Файл, откуда будут подгружаться определения локальных символов.
-R ../CX65sw50dev/firmware.symbols -- определение символов прошивки.
--section-start .text=A165F310 -- адрес, по которому размещать код. Как раз тот самый адрес OUR_KEY_HANDLER.
--section-start .data=A80C8FFC -- адрес, по которому размещать данные (переменные).

Среди опций мелькнули два файла. Первый файл local.symbols:
my_original_press_key = 0xA165F2FC;
-- тут сказано, что C'ная функция с именем 'my_original_press_key' расположена по адресу '0xA165F2FC', а это тот самый адрес MOVED_ORIGINAL_KEY_HANDLER. Тоесть, чтобы вызвать из C оригинальный обработчик, я должен воспользоваться функцией void my_original_press_key (int keycode);

Файл ../CX65sw50dev/firmware.symbols, аналогичен, сюда я внес немного функций и переменных, которые всегда есть в прошивке sw50 у cx65, например кусок:

[...]
switch_phone_off = 0xA1240EF0;
dynamic_light_mode = 0xA863E6E0;

set_dynamic_light_mode = 0xA0B1ECDD;
locked = 0xA8656060;
[...]

Замечу, что если функция прошивки написана THUMB инструкциями, то к адресу нужно прибавить единичку, то есть адрес должен быть нечетным (младший бит включен).
Также напомню, что если мы хотим использовать внешние функции, то их прототипы где-то надо описать. Локальную в рамках патча функцию my_original_press_key я описал прям в .c файле, а функции и переменные прошивки в файле cx65sw50.h:

[...]
void switch_phone_off ();
void set_dynamic_light_mode (unsigned mode);

extern unsigned dynamic_light_mode;
extern unsigned locked;
[...]


Теперь все вспомогательные вещи описаны. Можно приступать к написанию самого патча.
Нужно помнить, что первая функция в объектном файле будет той функцией, что ляжет по адресу OUR_KEY_HANDLER. Еще нужно указывать глобальным переменным секцию .data, чтобы они вдруг не оказались в секции кода .text (как любит делать последний gcc), нужно это из-за того, что в телефоне есть флэш память (под код), а есть RAM (под переменные). Если попытаться изменить с помощью STR что-то, что лежит во флэше, то телефон пискнет и выключится.

К нашим баранам. Первой функцией будет pressKeyChunk, которая и будет эмулировать нажатия на джойстик путем хранения состояния, вызова к оригинальному коду и т.д. Все, что нужно этой функции объявлено перед ней прототипами. Чтобы отслеживать изменение состояния светодиодов и реагировать на блокировку клавиатуры, при первом нажатии на клавишу, будет запущен таймер с частотой вызова обработчика ~0.4с. Как это все сделано можно увидеть скачав исходный код (5kb).
Для компиляции патча необходим мой Набор-Разработчика-Патчей-Для-CX65-SW50 (6.5kb). Этот архив включает в себя:
Makefile.inc в котором прописаны правила сборки,
cx65sw50.h прототипы некоторых функций прошивки,
firmware.symbols адреса некоторых функций прошивки,
fw50.map адреса всех функций, что мне удалось найти в прошивке, пока не надоело,
mk_patch.pl скрипт для создания vkp патча на основе elf файла, использует в свой работе программу elfsh.

Конечный vkp файл создается на основе elf файла скриптом mk_patch.pl и добавлением заголовка - файла, который мы сделали из IDA с помощью IDC скрипта.

Вот и все. Может быть все это выглядит запутанно и сложно, но на самом деле большая часть этих функций выполняется Makefile'ом и, чтобы создать патч, надо только написать make. Общие механизмы сборки вынесены в файл Makefile.inc, а в Makefile патча остались только настройки типа адреса данных, адреса кода, опций оптимизации и т.д.

Немного слов о функциях прошивки которые я нашел (из них более 250 nucleus os).
Как я уже говорил, адреса этих функций находятся в файле fw50.map архива (6.5kb). Если первой цифрой адреса не является 'A', то значит это смещение функции внутри секции и надо перед использованием к адресу прибавить A0000000. Какое-то количество этих функций удалось насобирать по форуму. Немного - из других патчей. Из туториалов. Что-то нашел сам. Небольшое число функций nucleus os удалось получить по сигнатурам, остальные - мой кропотливый труд.

Перед использованием какой-то функции ее желательно проверить. Не гарантирую, что идентифицировал правильно и правильно интерпретировал.

Для использования функций операционной системы Nucleus PLUS достаточно посмотреть на nucleus.h который есть в демоверсии этого продукта, а также можно поискать документацию по этим функциям. Самое полное, что удалось найти - это pdf под названием 'Nucleus Plus Internals'.

P.S. Спасибо авторам программ IDA, ArmDebugger и V_klay, а также другим, кто писал софт для работы с Siemens x65. Без этих программ телефон скорее всего пришлось бы править паяльником или покупать новый.
P.S. Все это является художественным вымыслом. Совпадение с реальностью случайны. Слышал, что обезьяны в состоянии случайно Войну и Мир написать, чем я хуже?

среда, 22 февраля 2006 г.

Как я правил прошивку своего сотового телефона

В общем решил я тут починить джойстик у своего Siemens CX65 (ношу телефон в кармане джинс вот выпирающая часть джойстика и отломилась еще месяц назад). Взял телефон, снял панель съемную, достал клей моментальный, взял хреновину одну, чтобы приклеить её к остаткам джойстика, намазал джойстик, приставил хреновину, подождал - хреновина прилипла к рукам, а не куда надо. Проделал еще пару попыток, поматерился своей лени на тему зачистить, обезжирить и тд, одел съемную панель обратно, включил телефон и заметил, что джойстик теперь совсем перестал работать, наверное капелька клея скатилась по остаткам джойстика к контактам и изолировала их. Если раньше остатки джойстика можно было как-то ногтем или вспомогательным предметом двигать, чтобы добиться нажатия в нужном направлении, то теперь это стало бесполезно.

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

Первым делом требовалось вытащить эту самую прошивку из телефона, а для этого необходим шнур и програмное обеспечение. За четыре дня до прошлого нового года я купил шнур "телефон<->usb" за 1000 рублей, после чего, буквально в тот же день улетел на родину в Омск (из Москвы) на неделю, а потом в Киев еще недели на две. Когда же я вернулся в Москву и попробовал тот шнур, что купил вскрылись две детали: для телефонов сименс существует множество шнуров различающихся как по моделям телефонов, так и по функциональности. Мой шнур тогда не завелся ни в винде (с родными и не родным дровами), ни в линухе. А гарантия на обмен (15 дней) истекла, пока я мотался Москва->Омск->Москва->Киев->Москва. Но теперь, начитавшись форумов, я твердо решил взять этот шнур и переделать его из нерабочего в рабочий. Подключив его для верности в linux 2.6.15, дабы убедится, что он таки не работает, но по dmesg я увидел обратное:
drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
pl2303 3-1:1.0: pl2303 converter detected
usb 3-1: pl2303 converter now attached to ttyUSB0

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

Когда телефон подружился с компьютером, настало время сделать backup этого телефона: рассчитать все коды (HASH, SKEY, IMEI, BKEY, ESN) и записав их в файлик, сделать дампы фулфлэша, буткора (на всякий), лэнгпака (на всякий), еелайта и еефула. Теперь душа спокойна, шансы окончатильно убить тело уменьшились. Для того, чтобы не патчить старую прошивку, я заодно поставил sw50 взамен стоявшей 12 версии (обновил фуллфлэш, обновил файловую систему и мэппинг). На всякий случай снова сделал бэкапы всего подрят.

Бэкапы сделаны, прошивка лежит на винте, самое время поставить IDA, изучить ассемблер ARM710, найти в прошивке нужный код и наконец сделать патч. Для верности и на всякий случай (вдруг пригодится), собрал и поставил на свой debian binutils-arm-linux и компилятор gcc-arm-linux. Изучать набор инструкций ARM было достаточно необычно, интересно и приятно, все-таки набор отличается от x86 в лучшую сторону.

А дальше началось изучение прошивки. Процесс надо сказать неоднозначный.. то ты начинаешь впадать в уныние не знаешь с какой стороны подойти и понять какой вызов был для чего сделан, а то вдруг неожиданно находишь интересные куски кода. Процесс изучения прошивки напоминает следующую ситуацию: вас помещают в произвольное место гиганского лабиринта из которого вам надо найти выход, у вас есть возможность телепортироваться в случайное место лабиринта по желанию, в лабиринте темно, а на полу начерчена замкнутая схема, которую можно использовать на ощупь. Сравнение может быть не очень корректное, но процесс перемещения по функциям немного напоминает.. Радостными моментами в таком деле стали: распознавание стандартных функций типа memset, strcpy, strchr, strlen, printf и т.д., обнаружении функции вызываемой в случае ошибки (не понятно правда куда она ошибку девает, толи в лог, толи еще куда, но это и не важно, а важно, что она вызывается с текстовым описанием ошибки), функции isKeyGood и наконец функции KeyPress!!! А я ведь все время был рядом с этой заветной функцией... всего-то надо было внимательнее смотреть на BFC, хотя наверное эта внимательность пришла как раз в процессе разгребания прочих участков.

Теперь появилось чувство определенности. Самое главное - это найти где править, а это я уже сделал. Дело за малым - найти свободные участки прошвки, озу и написать патч. К сожалению скачать keil arm не получается - траффик на интернет аккаунте кончился, а keil весит под 50м, поэтому решаю покомпилировать с помощью arm-linux-as.

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

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




1, left-up 2, up 3, right-up
4, left 5, click 6, right
7, left-down 8, down 9, right-down

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

Алгоритм при любом подходе получается немного сложноватый, чтобы тратить время на его реализацию на ассемблере, поэтому я набросал его на C и скомпилировал с помощью arm-linux-gcc в объектный файл. Но не все так просто, как хотелось бы. Замечательный GCC сгенерировал код использующий не хилую таблицу абсолютных адресов (для switch'а), а так как этот код будет располагаться в совершенно другом участке памяти, то надо либо править адреса руками, либо думать как объяснить gcc/as, что я хочу код для определенного участка памяти. Как объяснить GCC/AS я не нашел :(. Но зато разобрался с ld, которым слинковал объектный файл, указав, что хочу секцию .text расположить строго по такому-то адресу. Получилось! Для того, чтобы получить vkp патч на основе elf файла, пишу скрипт на perl'е, на выходе которого получаю заветный патч.

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

Немного волнуясь, загружаю v_klay, заливаю патч в телефон.

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

Даже не ожидал, что патч получится с первой попытки! Какой я молодец! :)))

А вот и сам патч.

четверг, 15 декабря 2005 г.

Продолжаю добывать прошивку своего сименса

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

Слегка продвинуться на пути получения прошивки удалось найдя утилиту для выковыривания xbz файла из файлов вида CX65250300.xbz_update.exe. Заметьте, найдя - а не написав, я очень законопослушный гражданин (это могут подтвердить все, кто меня хорошо знает) и если в лицензионном соглашении исполняемого файла с зашифрованной прошивкой написано, что программу нельзя дизассемблировать и модифицировать - то я этого конечно же не буду делать! *невин *миг :)

Итак с помощью этой утилиты, исходный код которой я разместил, на сайте, чтобы другим не пришлось искать как мне (полтора дня убил на поиск в самых закромах), мне удалось вытащить и разшифровать xbz файл.

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

Дизассемблировать код сименовской программы нельзя, поэтому ограничусь изучением кода найденной утилиты :). Судя по-всему *xbz_update.exe файлы состоят из четырех частей:
1. Собтсвенно сама программа обновления телефона прошивкой приложенной к файлу.
2. Информация для расшифровки файла и контроля целостности. Это версия формата, таймстамп используемый как одна из составляющих IV и 128 байт сигнатуры с которой скорее всего для контроля целостности необходимо сверить хэш разшифрованного файла.
3. Зашифрованный с помощью Rijndael-128 (AES) файл с прошивкой в формате xbz.
4. Блок данных в конце exe файла в котором указано с какого смещения в exe файле начинается зашифрованная часть. Это блок данных тоже хитрым способом организован, что должно прятать смещение от посторонних глаз.
128 битный ключ, судя по коментарию в исходнике утилиты (кусок асеблерного кода) :), был выдран прям из exe файла, как и 128 битный IV (но первые его 4 байта это timestamp). Полагаю, что вполне вероятна ситуация в которой ключ не подойдет и надо будет его искать заново... (а приведенный кусок асм кода должен в этом помочь) кто их этих сименцев знает.. может у них на каждый апдейт свой ключ...
Более подробно можно узнать посмотрев исходник утилиты, или дизассемблировать программу обновления прошивки (только это запрещено лицензионным соглашением).

К слову о... Вообще, из собственного опыта изучения программ, чье лицензионное соглашение не запрещает этого делать могу сказать, что начинать надо с сообщений (например об ошибках)!
Загружаем файл в какой-нибудь интерактивный дизассемблер (под unix и win32 есть бесплатный и замечательный hte), находим интересное сообщение, такое, которое вполне вероятно используется в том коде, который мы хотим найти (например password check failure) и просим интерактивный дизассеблер дать нам все места с которых есть ссылки на это сообщения... Ну, а дальше дело техники, знания ассеблера и того языка на котором написана подобытная программа.

На самом деле, получить прошивку можно еще и:
1. Скачав ее из интернета. Самый простой вариант. Но если ты на GPRS (как я сейчас временно) - то он не подходит, прошивка не маленькая.
2. Вытащить из телефона. Для этого нужен шнурок. Я за 3000км от своего шнурка, а брать новый (400р) жаба душит.
3. Попробовать вытащить прошивку через irda с телефона. Помучив телефон по протоколу BFC через IRDA и увидев как на все мои корректные запросы телефон реагирует только эхом.. а на некорректные не реагирует вообще я понял, что занятие бесполезное или у меня лапы кривые. Хотя выключение телефона BFC командой работает... забавно ).
4. Загрузить программу обновления в vmware, сделать виртуальный порт который будет обслуживать программа имитатор моблиьного телефона. Программу я эту написал, но далеко дело не пошло, я не знаю как должен реагировать телефон на те или иные команды и поэтому дописать эмулятор телефона не смог.
5. Загрузить программу обновления прошивки в vmware и сделать suspend. Открыть файл памяти виртуально машины и выдрать оттуда прошивку. Самый просто вариант, но нужно знать какой последовательностью начинается прошивка (теперь я знаю, что она начинается Siemens Mobile Phones:SIGNATURE...) и какую длинну она имеет.