CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Новогоднее исследование ADSL-роутера на базе Linux - 0x4 - модифицируем файловую систему


0x0 — введение
0x1 — разбираем :)
0x2 — знакомимся с программной частью
0x3 — формат прошивки
0x4 — модифицируем файловую систему

Вчера мы узнали, что файл прошивки нашего модема имеет следующую структуру:

1. 256-байтный заголовок (bcmtag)
2. CFE (Bootloader)
3. образ корневой файловой системы (тип файловой системы: SquashFs)
4. сжатый образ ядра Linux

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

В принципе, можно было воспользоваться существующими утилитами, но для более близкого знакомства с данным вопросом — я написал свою собственную :)

ParseImage.zip

Это проект под VC2008, который можно скомпилировать в виде консольных утилит:

ParseImage.exe — принимает на вход единственный параметр — название файла прошивки, выводит информацию из заголовка и выдаёт 4/5 файлов, содержимого прошивки:
bcm.bin — заголовок (256 байт)
cfe.bin — CFE
sqsh.bin — корневая файловая система
kernel.bin — образ ядра
(для прошивки D-link-ов появляется ещё пятый файл — name.bin)

crc.exe — принимает на вход название файла и выдаёт его контрольную CRC-сумму

packImage.exe — принимает на вход 4/5 параметров — файлы, которые нужно склеить в прошивку.
пример:
packImage.exe bcm.bin cfe.bin sqsh.bin kernel.bin
для D-link-ов можно задать пятый параметр — 32-байтный файл с названием
packImage.exe bcm.bin cfe.bin sqsh.bin kernel.bin name.bin


Т.о. берём утилиту ParseImage.exe и натравим её на файл прошивки:
C:\temp\ParseImage\Release> ParseImage.exe zxdsl.bin

[i] Simple Firmware Parser.
[i] file: zxdsl.bin
[i] Open file...
[i] file size: 1889022
[i] bcmtag:
tagVersion: 		6
signature_1: 		ZXDSL831AIIE09
signature_2: 		BOTH
chipId: 		6338
boardId: 		96338L-2M-8M
bigEndian: 		1
totalImageLen: 		1888766
cfeAddress: 		3217031168
cfeLen: 		63324
rootfsAddress: 		3217096960
rootfsLen: 		1273856
kernelAddress: 		3218370816
kernelLen: 		551586
dualImage: 		0
inactiveLen: 		0
reserved: 		
imageValidationToken: 	DB 8D 04 D5 22 D2 E8 4D 0B E6 B8 F4 00 00 00 00 00 00 00 00 
tagValidationToken: 	4F BA 75 F1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

[i] Ok. Size good for: Broadcom!
[i] CRC file		: 0x47FC88F0
[i] CRC bcmtag		: 0x4FBA75F1
[i] CRC image		: 0xDB8D04D5
[i] CRC sqsh		: 0x22D2E84D
[i] CRC kernel		: 0x0BE6B8F4
[i] Close file.
[i] Done.

http://robocraft.ru


Итак, прошивку распаковали :)

самый простой вариант внедрения своего кода в систему — это модификация файловой системы, которая находится в sqsh.bin

посмотрим начало файла:

$ hexdump -n 256 -C sqsh.bin 
00000000  73 71 73 68 00 00 01 53  00 13 65 51 00 13 65 4d  |sqsh...S..eQ..eM|
00000010  00 00 00 00 00 13 36 98  00 13 54 0e 00 02 00 00  |......6...T.....|
00000020  b3 e0 00 10 51 01 00 47  a5 21 66 00 00 00 00 00  |....Q..G.!f.....|
00000030  00 1d 65 00 01 00 00 00  00 00 00 00 13 65 4d 5d  |..e..........eM]|
00000040  00 00 08 00 00 11 88 06  e7 b9 9d e4 b6 a2 ce 06  |................|
00000050  a0 8c f4 e8 56 5c e8 6a  f7 da 91 85 01 bb 66 ec  |....V\.j......f.|
00000060  5f 8c a5 ec e9 63 a8 2b  3a be 86 b8 a2 ec 12 72  |_....c.+:......r|
00000070  ac 6e 3f e0 ed 21 72 85  70 9e bc a1 7e a2 cf 58  |.n?..!r.p...~..X|
00000080  a9 94 99 72 41 07 45 0f  6c 30 7b f2 57 d4 0a 45  |...rA.E.l0{.W..E|
00000090  09 54 b4 0c 7e 0e 92 0e  00 5d 00 00 08 00 00 11  |.T..~....]......|
000000a0  88 06 e7 b9 9d e4 b6 a2  ce 06 a0 8c f4 e8 56 5c  |..............V\|
000000b0  e8 6a f7 da 91 85 01 bb  66 ec 5f 8c a5 ec e9 63  |.j......f._....c|
000000c0  a8 2b 3c 2a cb d4 e3 37  ae 08 ed 25 0e 32 7f 25  |.+<*...7...%.2.%|
000000d0  ae f0 fb ac 84 8c a5 4e  3e 0f d5 ea cd 5a 70 70  |.......N>....Zpp|
000000e0  41 b3 3a 58 eb f1 cc fc  df 5d b2 0e 67 a1 58 bb  |A.:X.....]..g.X.|
000000f0  64 c8 00 5d 00 00 08 00  00 11 88 42 46 3d f4 18  |d..].......BF=..|


Как видите — в самом начале файла находится строчка sqsh, которая обозначает, что перед нами раздел в файловой системе Squashfs

Squashfs (.sfs) — сжимающая файловая система для Линукс, предоставляющая доступ к данным в режиме «только для чтения». Squashfs сжимает файлы, индексные дескрипторы и каталоги, а также поддерживает блоки размером до 1024 Кбайт для лучшего сжатия.

Squashfs предназначена для широкого использования файловых систем «только для чтения», а также в ограниченных по размеру блочных устройствах/системах хранения (во встраиваемых системах), где необходимы низкие затраты на производство. Стандартная версия Squashfs использует алгоритм сжатия gzip, но существует проект, позволяющий использовать алгоритм сжатия LZMA.

Ссылки:
squashfs.sourceforge.net
www.squashfs-lzma.org
www.elinux.org/Squash_FS_Howto
en.wikipedia.org/wiki/SquashFS


Распаковка файловой системы

распаковать файловую систему получится только под Linux-ом, просто же получить информацию можно и под виндой — для этого можно использовать squashfs-tools-win32.

для получения информации нужно запустить утилиту unsquashfs с параметром -s
C:\utils\squashfs-tools> unsquashfs.exe -s sqsh.bin

Found a valid big endian SQUASHFS 2:0 superblock on sqsh.bin.
Creation or last append time Sun Feb  3 05:05:26 2008
Filesystem is not exportable via NFS
Inodes are uncompressed
Data is compressed
Check data is not present in the filesystem
Fragments are not present in the filesystem
Always_use_fragments option is not specified
Duplicates are removed
Filesystem size 1241.33 Kbytes (1.21 Mbytes)
Block size 65536
Number of fragments 0
Number of inodes 339
Number of uids 1
Number of gids 0


под Ubuntu сначала нужно установить squashfs-tools:
sudo apt-get install squashfs-tools


$ unsquashfs -s sqsh.bin 
Reading a different endian SQUASHFS filesystem on sqsh.bin
Found a valid big endian SQUASHFS 2:0 superblock on sqsh.bin.
Creation or last append time Sun Feb  3 05:05:26 2008
Filesystem is not exportable via NFS
Inodes are uncompressed
Data is compressed
Check data is not present in the filesystem
Fragments are not present in the filesystem
Always_use_fragments option is not specified
Duplicates are removed
Filesystem size 1241.33 Kbytes (1.21 Mbytes)
Block size 65536
Number of fragments 0
Number of inodes 339
Number of uids 1
Number of gids 0


распаковку необходимо осуществлять под root-ом:
# unsquashfs sqsh.bin 
Reading a different endian SQUASHFS filesystem on sqsh.bin

затем будет множество сообщений об ошибках распаковки:
zlib::uncompress failed, unknown error -3

и в самом конце
created 202 files
created 26 directories
created 60 symlinks
created 50 devices
created 1 fifos


В общем, последняя версия squashfs-tools (4.0) не работает.
Справедливости ради, нужно отметить, что все версии squashfs-tools представленные на странице squashfs.sourceforge.net не могут распаковать файловую систему. Дело в том, что для сжатия, в данном случае, используется LZMA.

LZMA (Lempel-Ziv-Markov chain-Algorithm) — алгоритм сжатия данных, разрабатываемый с 2001 года. Этот алгоритм, используется в архиваторе 7-Zip для создания сжатых архивов в формате 7z. Алгоритм основан на схеме сжатия данных по словарю, и обеспечивает высокий коэффициент сжатия (превышающий коэффициент, получаемый при сжатии с использованием bzip2), а также позволяет использовать словари различного размера.

Ссылки:
LZMA SDK
PyLZMA — библиотека для Python


Я перепробовал массу вариантов распаковки. Пытался накладывать LZMA-патчи.
Пробовал другие варианты пропатченых утилит из
Firmware Modification Kit
Оказывается — я повторил попытки французской команды neufbox4.org

Но, в итоге, только два варианта оказались рабочими:
1. использовать утилиту unsquashfs (для SqashFS v. 2.0 ), которую выложил Michael V. Pudeev
2. использовать скрипт на питоне unsquash35.py
от neufbox4.org
в данном случае, придётся установить сам питон и библиотеку pylzma:
python
python-dev
python-setuptools
устновка библиотеки:
easy_install pylzma


Итак, используем unsquashfs версии 1.5 с поддержкой LZMA:
# ./unsquashfs sqsh.bin 
Reading a different endian SQUASHFS filesystem on sqsh.bin

created 202 files
created 26 directories
created 60 symlinks
created 50 devices
created 1 fifos

ошибок распаковки нет. Корневая файловая система распаковалась и находится в директории
squashfs-root

Раз мы распаковали корневую директорию, то самое время попробовать внести в неё какие-нибудь изменения :)
первым делом отредактируем
webs/main.html
находим заголовок в теге
<title>
и добавляем " — RoboCraft"
тээкс — теперь напишем простенький скрипт и поместим в
usr/bin/
назовём его mytest:
touch mytest

сделаем исполняемым
chmod 755 mytest

и вставим пару строчек:
#!/bin/sh

echo "RoboCraft is cool!"

для начала — достаточно :)

Упаковка файловой системы

Теперь необходимо запаковать изменённую систему обратно :)

С запаковкой ситуация абсолютно такая же, как и с распаковкой.
В общем, чтобы запаковать нужно воспользоваться утилитой mksquashfs версии 2.0 с поддержкой LZMA.
Скачать её (в комплекте с unsquashfs) можно здесь:
sqsh-tools-dlink2500.tar.gz

сразу она у вас, скорее всего не запустится, т.к. ей для работы требуется пятая версия стандартной библиотеки.
Посмотреть какие библиотеки требуются для работы программы можно с помощью команды ldd:
# ldd ./mksquashfs
	linux-gate.so.1 =>  (0x00ed8000)
	libz.so.1 => /lib/libz.so.1 (0x00451000)
	libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00742000)
	libm.so.6 => /lib/libm.so.6 (0x00a27000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00110000)
	libc.so.6 => /lib/libc.so.6 (0x00890000)
	/lib/ld-linux.so.2 (0x0081e000)

так что сначала придётся установить эту библиотеку:
$ sudo apt-get install libstdc++5


Затем нужно передать утилите mksquashfs целый ряд параметров :)
# ./mksquashfs squashfs-root/ sq3.bin -be  -no-fragments -noI -all-root -noappend -lzma -b 65536

и… у нас появляется новый файл корневой файловой системы:
sq3.bin

Остальные части прошивки не трогали, так что остаётся просто собрать прошивку с обновлённой файловой системой :)

Для этого использую свою утилиту packImage.exe:

C:\temp\ParseImage\Release> packImage.exe bcm.bin cfe.bin sq3.bin kernel.bin 
[i] Make fimware.
[i] bcm file: bcm.bin
[i] file size: 256
[i] cfe file: cfe.bin
[i] file size: 63324
[i] sqsh file: sq3.bin
[i] file size: 1273856
[i] kernel file: kernel.bin
[i] file size: 551586
[i] result size: 1889022
[i] CRC image		: 0x36491756
[i] CRC sqsh		: 0x901858BB
[i] CRC kernel		: 0x0BE6B8F4
[i] update size...
[i] update image CRC...
[i] update sqsh CRC...
[i] update kernel CRC...
[i] CRC header		: 0xF5B4BD5D
[i] update header CRC...
[i] write file: result.bin
[i] Done.

http://robocraft.ru


на выходе получаем файл result.bin того же размера, что и исходная прошивка (1 889 022 байт)

при сборке своей прошивки необходимо:
1. объединить bcm, cfe, rootFS и Kernel в один файл.
2. записать в bcm данные о длинах составляющих: totalImageLen, cfe, rootFS, Kernel
3. рассчитать и записать в bcm CRC-суммы составляющих: Image, rootFS, Kernel
4. рассчитать и записать в bcm CRC-сумму самого заголовка (т.е. первых 236 байт получившегося файла)

моя утилита просто считывает в общий буфер содержимое задаваемых в виде параметров файлов.
да-да — я не стал париться и не генерирую bcm самостоятельно, а тоже его считываю (первый параметр программы)
далее, делаю все нужные изменения в этом буфере (записываю по нужным смещениям bce длины и CRC-суммы).
И всё :) Остаётся всего-лишь сохранить буфер в файл result.bin ;)


Остаётся загрузить её в модем :) Идём в веб-интерфейс и щёлкаем на обновление прошивки.
Выбираем наш файл. И ждём. Прошивка грузится, модем перезагружается…
Обновляем страничку веб-интерфейса:

заголовок есть!

теперь посмотрим скрипт. Подключаемся телнетом:

# cd /usr/bin
# ls -l
lrwxrwxrwx    1 0        0              17 logger -> ../../bin/busybox
-rwxrwxrwx    1 0        0              37 mytest
lrwxrwxrwx    1 0        0              17 tftp -> ../../bin/busybox
lrwxrwxrwx    1 0        0              17 tty -> ../../bin/busybox
lrwxrwxrwx    1 0        0              17 ftpget -> ../../bin/busybox
lrwxrwxrwx    1 0        0              17 [ -> ../../bin/busybox
lrwxrwxrwx    1 0        0              17 expr -> ../../bin/busybox
lrwxrwxrwx    1 0        0              17 test -> ../../bin/busybox

# cat mytest
#!/bin/sh

echo "RoboCraft is cool!"

# mytest
RoboCraft is cool!


ураааааааааа! победа :)

далее: 0x5 — пишем первую программу

Ссылки:
squashfs.sourceforge.net
www.neufbox4.org
pudeev.livejournal.com/31111.html

Программы:
ParseImage.zip
squashfs-tools-win32
sqsh-tools-dlink2500.tar.gz
  • +2
  • 4 января 2011, 22:24
  • noonv

Комментарии (20)

RSS свернуть / развернуть
+
+1
Будучи линуксоидом, чрезвычайно рад видеть здесь такие статьи. С трудом удерживаю себя от насилия над старым D-Link 2500U (:
avatar

burjui

  • 5 января 2011, 11:02
+
0
А собственно какими стандартными средствами под Linux-ом можно распаковать/запаковать прошивку? Можно подробнее.
avatar

rammires

  • 6 января 2011, 06:45
+
0
как я понял — в любом случае, нужно скачивать squashfs-tools. В их составе идут патчи ядра, которые можно наложить на исходники ядра, пересобрать ядро и оно станет поддерживать Squashfs.
Т.е. можно будет просто монтировать файлы-образы Squashfs в свою файловую систему.

Как видите — намного проще использовать готовые утилиты из squashfs-tools:
unsquashfs — для распаковки и mksquashfs — для запаковки.

В данном случае трудность состояла именно в нахождении подходящих версий с поддержкой метода сжатия LZMA.
avatar

noonv

  • 6 января 2011, 11:30
+
0
По поводу unsquashfs/mksquashfs я понял, но было не понятно чем заменить ParseImage.exe, но к счастью она успешно скомпилилась под Linux-ом…
avatar

rammires

  • 7 января 2011, 16:40
+
0
аааа :) это хорошо — я Makefile не писал :) но проблем с компиляцией под линуксом и не предвиделось :)
avatar

noonv

  • 7 января 2011, 16:51
+
0
Здравствуйте, с вашей программой ParseImage.exe возникла проблема она запускается и сразу же закрывается при этом никаких ошибок не выскакивает.
avatar

himik

  • 9 января 2011, 18:33
+
0
может это из-за того, что она консольная? ;) и соответсвенно запускать её нужно в командной строке, передавая в качестве единственного параметра название файла прошивки :)
avatar

noonv

  • 9 января 2011, 18:37
+
0
Вопрос №2 как установить unsquashfs версии 1.5 с поддержкой LZMA. Я ее скачал распоковал а как установить и использовать непойму(Ubuntu 10.4).
avatar

himik

  • 9 января 2011, 20:22
+
0
Здравствуйте! Утилита ParseImage.exe распаковала предложенный файл прошивки (предварительно помещенный в директорию Release) только запуском unpack.bat. Из-под командной строки (C:\temp\ParseImage\Release\ParseImage.exe zxdsl.bin) не получилось <[i]Error: cant open file: zxdsl.bin!> Подскажите, плз, что не так. Пробовал разобрать файлы других прошивок (описанного модема у меня нет, и он мне не нужен есть устройство ASUS WMVN25E2+/ Asus дает для него урезанные исходники.) D-link-овские файлы .bin открывает, но в результате — пустые .bin файлы ( кроме bcm.bin) Что надо изменить командах? Или она открывает только описанную прошивку?
avatar

rusink

  • 5 февраля 2011, 12:28
+
0
утилита распаковывает только прошивку рассматриваемого модема (ZTE ZXDSL831AII) и схожих D-link-овских модемов (DSL-2500U).
avatar

noonv

  • 5 февраля 2011, 12:42
+
0
Спасибо за оперативный ответ. И огромнейший респект за статью. Удивляюсь, когда только успел и с модемом разобраться и отличную статью написать. С утилитой разобрался. Она прекрасно открыла прошивку ASUS WMVN25E2+.Файловую систему извлек, теперь пытаюсь найти настройки wimax (есть мысль заставить этот залоченный девайс работать с другим оператором. Прецедент с usb модемами (Samsung SWC-U200) — есть. Настройки оператора спрятаны где-то в прошивке лог их показывает. Если сможешь в этом помочь разобраться буду очень признателен. Еще раз спасибо за статью!!!
avatar

rusink

  • 5 февраля 2011, 17:20
+
0
Здравствуйте. Как можно распаковать прошивку для zte w300. ParseImage.exe кажется не справляется, только один файл созданный им имеет размер 1кб, все остальные три по 0кб. Оно имеет расширение release вот «w300.v803c12m.firmware.img.release». Может что-то надо модифицировать в вашем C/C++ коде?.. Спасибо.
avatar

vardan

  • 24 сентября 2011, 15:33
+
0
похоже, другой не только проц, но и совсем другой формат прошивки.
avatar

admin

  • 24 сентября 2011, 16:28
+
0
в коммандной строке набираю telnet 192.168.1.1, потом cat /proc/cpuinfo и вот что на экране:
processor: 0
cpu model: MIPS 4KEc V4.8
BogoMIPS: 211.35
wait instruction: no
microsecond timers: yes
extra interrupt vector: yes
hardware watchpoint: yes
VCED exceptions: not available
VCEI exceptions: not available
то есть процессор MIPS 4KEc V4.8. А что надо делать пожайлуста в каком направлении копать, очень хочу усвоить этот урок.Заранее спасибо.
avatar

vardan

  • 24 сентября 2011, 17:27
+
0
Спасибо за статью. А вы не подскажите как сделать обратное действие: снять думп с текущей прошивки? Чтобы потом можно было к ней вернуться
avatar

l0pan

  • 11 февраля 2012, 09:37
+
0
При упаковке файловой системы, sq3.bin весит не 1.4 МБ, а 3,6 МБ… :(
Прошивка для DSL-2500U
Упаковываю в fedora 16.1 x64
В чем может быть проблема?
avatar

degid

  • 23 сентября 2012, 11:38
+
0
народ. Столкнулся с траблой. При вбиве команды ./mksquashfs squashfs-root/ sq3.bin -be -no-fragments -noI -all-root -noappend -lzma -b 65536
Получаю на выходе ./mksquashfs squashfs-root/ sq3.bin -be -no-fragments -noI -all-root -noappend -lzma -b 65536
./mksquashfs: error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory

Либа libstdc++5 поставленна но при вбиве ldd ./mksquashfs вижу что ibstdc++.so.5 => not found. В чём трабла? ОС BT5r3
avatar

CryNet

  • 10 октября 2012, 18:59
+
0
Не знаю как у вас а у меня sqsh.bin открылся 7zip
avatar

mannaz

  • 23 мая 2014, 04:34
+
0
Тока посмотреть каталоги.
avatar

mannaz

  • 23 мая 2014, 04:43

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.