Изменение прошивки вручную

 

Стандартная прошивка маршрутизаторов Asus SL500/1000 позволяет нам задавать через консоль arp-таблицу, однако эта таблица теряется при перезагрузке. В качестве операционной системы для SL выбран Linux, однако, в устройстве он расположен на read-only разделах, что несколько осложняет конфигурацию. Выходом из сложившейся ситуации является изменение официальной прошивки, которую можно взять на сайте производителя. Поскольку у меня для экспериментов был маршрутизатор SL500, то и изменять прошивку я буду для него, хотя для SL1000 всё аналогично. Для экспериментов была выбрана прошивка SL500_1_1_72A_410, находящаяся в одноимённом файле SL500_1_1_72A_410.bin. Посмотрим на структуру этого файла. В качестве программы для редактирования прошивки был использован WinHEX 12.85 SR-10.

big endian
000-001 - 0000
002-003 - 91CF (depends on the device and firmware version (proprietary CRC))
004-01F - BE73 1504 0000 0003 0002 0000 0000 0000 0000 0000 0040 0000 0100 0000
020-027 - 534C 3530 3000 0000 (device name SL500)
028-29F - 0000
2A0-2AB - 16 bit 3,2,3,0,0,B
2AC-309 - 0000
30A-329 - first file header
32A-349 - second file header
34A-369 - third file header
36A-487 - 0000
0488-...files

Слева указано смещение в шестнадцатеричной системе от начала файла, а справа – содержимое прошивки. Заголовок файла представляет собой структуру, содержащую информацию о файле (смещение начала файла, длина, номер файла).

u16 file number (1..3)
u32 displacement from the beginning of the file
u16 flag (00 for the first file, 01 for the second one and 3E for the third (last) one)
u16 0000
u32 file length or 0 for EOF
u144 18 zero-bytes;

Приведём заголовки трёх файлов в шестнадцатеричном виде.

0001 0000 0488 0000 0000 0000 F9A0 0000 0000 0000 0000 0000 0000 0000 0000 0000

0002 0000 FE28 0001 0000 003A 6000 0000 0000 0000 0000 0000 0000 0000 0000 0000

0003 003B 5E28 003E 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

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

Полученный файл представляет собой сжатый образ файловой системы устройства. Сначала требуется извлечь файлы из этого образа, то есть распаковать их из cramfs. Файловая система содержит жёсткие линки, поэтому извлечение образа под Windows невозможно. Было принято решение установить Linux в виртуальной машине для того, чтобы извлечь файлы, изменить их и собрать в образ обратно. В качестве программной виртуальной машины была установлена VMware Workstation (5.5.1 build 19175). В виртуальную машину была установлена операционная система Linux Fedora Core 5 (ядро 2.6.15).

Теперь требуется подготовить всё необходимое, чтобы собрать утилиту для извлечения. В качестве ПО для работы с файловой системой была взята реализация cramfs-1.1. Кроме этого в этот же каталог пришлось установить zlib-1.2.3. Сложность извлечения состояла в том, что ПК и маршрутизатор имеют различную эндианность. Для преодоления указанной трудности пришлось воспользоваться изменённым Игорем Нестеровым файлом cramfsck.c, с которым были собраны необходимые утилиты.

[root@localhost firmware]# pwd
/fox/firmware
[root@localhost firmware]# ls
2.bin cramfsck.c gzio.c inftrees.h projects zconf.in.h
adler32.c cramfsck.c~ image0 linux qnx zlib.3
algorithm.txt crc32.c INDEX Makefile README zlib.h
amiga crc32.h infback.c Makefile.in text zutil.c
as400 deflate.c inffast.c make_vms.com text~ zutil.h
ChangeLog deflate.h inffast.h minigzip.c trees.c
compress.c example.c inffixed.h mkcramfs.c trees.h
configure examples inflate.c msdos uncompr.c
contrib FAQ inflate.h NOTES win32
COPYING GNUmakefile inftrees.c old zconf.h
[root@localhost firmware]# ./configure
Checking for gcc...
Building static library libz.a version 1.2.3 with gcc.
Checking for unistd.h... Yes.
Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()
Checking for vsnprintf() in stdio.h... Yes.
Checking for return value of vsnprintf()... Yes.
Checking for errno.h... Yes.
Checking for mmap support... Yes.
[root@localhost firmware]# make
gcc -W -Wall -O2 -g -I. mkcramfs.c -lz -o mkcramfs
mkcramfs.c: In function ‘parse_directory’:
mkcramfs.c:287: warning: pointer targets in assignment differ in signedness
mkcramfs.c: In function ‘write_superblock’:
mkcramfs.c:399: warning: pointer targets in passing argument 1 of ‘__builtin_strncpy’ differ in signedness
mkcramfs.c:401: warning: pointer targets in passing argument 1 of ‘__builtin_strncpy’ differ in signedness
mkcramfs.c: In function ‘write_directory_structure’:
mkcramfs.c:480: warning: pointer targets in passing argument 1 of ‘strlen’ differ in signedness
mkcramfs.c: In function ‘do_compress’:
mkcramfs.c:598: warning: pointer targets in passing argument 1 of ‘compress2’ differ in signedness
mkcramfs.c:598: warning: pointer targets in passing argument 3 of ‘compress2’ differ in signedness
mkcramfs.c: In function ‘write_data’:
mkcramfs.c:647: warning: pointer targets in passing argument 3 of ‘do_compress’ differ in signedness
mkcramfs.c: In function ‘main’:
mkcramfs.c:825: warning: pointer targets in passing argument 2 of ‘crc32’ differ in signedness
gcc -W -Wall -O2 -g -I. cramfsck.c -lz -o cramfsck
[root@localhost firmware]# ls
2.bin cramfsck GNUmakefile inftrees.c NOTES win32
adler32.c cramfsck.c gzio.c inftrees.h old zconf.h
algorithm.txt cramfsck.c~ image0 linux projects zconf.in.h
amiga crc32.c INDEX Makefile qnx zlib.3
as400 crc32.h infback.c Makefile.in README zlib.h
ChangeLog deflate.c inffast.c make_vms.com text zutil.c
compress.c deflate.h inffast.h minigzip.c text~ zutil.h
configure example.c inffixed.h mkcramfs trees.c
contrib examples inflate.c mkcramfs.c trees.h
COPYING FAQ inflate.h msdos uncompr.c
[root@localhost firmware]#

Теперь нужно воспользоваться собранными утилитами для извлечения файлов из ободранной прошивки в каталог /fox/extraction. Лишнее перечисление извлечённых файлов здесь не приводится.

[root@localhost firmware]# ./cramfsck
usage: ./cramfsck [-hv] [-x dir] file
-h print this help
-x dir extract into dir
-v be more verbose
file file to test
[root@localhost firmware]# ./cramfsck -v -x /fox/extraction 2.bin
SS 13
warning: old cramfs format
d 0755 344 0:0 /fox/extraction
d 0755 392 0:0 /fox/extraction/bin
l 0777 8 0:0 /fox/extraction/bin/bash -> /bin/msh
f 0755 166484 1011:104 /fox/extraction/bin/busybox
l 0777 8 0:0 /fox/extraction/log -> /tmp/log
l 0777 17 0:0 /fox/extraction/firewall.cfg -> /tmp/firewall.cfg
f 0755 999060 0:0 /fox/extraction/cpu1
d 0755 0 0:0 /fox/extraction/ramfs
f 0755 1699436 0:0 /fox/extraction/vmlinux
2.bin: OK
[root@localhost firmware]# ls
2.bin cramfsck GNUmakefile inftrees.c NOTES win32
adler32.c cramfsck.c gzio.c inftrees.h old zconf.h
algorithm.txt cramfsck.c~ image0 linux projects zconf.in.h
amiga crc32.c INDEX Makefile qnx zlib.3
as400 crc32.h infback.c Makefile.in README zlib.h
ChangeLog deflate.c inffast.c make_vms.com text zutil.c
compress.c deflate.h inffast.h minigzip.c text~ zutil.h
configure example.c inffixed.h mkcramfs trees.c
contrib examples inflate.c mkcramfs.c trees.h
COPYING FAQ inflate.h msdos uncompr.c
[root@localhost firmware]# cd ..
[root@localhost fox]# ls
cramfs-1.1 extraction firmware zlib-1.2.3
[root@localhost fox]# cd extraction
[root@localhost extraction]# ls
bin dev firewall.cfg home lib mnt proc root tmp var
cpu1 etc flash0 jffs2 log opt ramfs sbin usr vmlinux
[root@localhost extraction]#

Автоматически запускаемым скриптом оказался файл GOCstartup из каталога /etc/init.d, поэтому всё необходимое для автозагрузки было размещено именно в этом файле. В его начало были вставлены строки об авторе изменений, а в конец добавлены необходимые команды для извлечения другого скрипта, изменения его параметров и запуска извлечённого.

echo "Start my part."
echo "Extracting file fox.script..."
rfcutil xtract /tmp/fox.script fox.script
echo "Changing script (fox.script) rights..."
chmod 777 /tmp/fox.script
echo "Runing script (fox.script)..."
/tmp/fox.script
echo "End my part."

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

Теперь необходимо собрать образ файловой системы, что можно осуществить с помощью уже собранной утилиты mkcramfs.

[root@localhost firmware]# ./mkcramfs --help
./mkcramfs: invalid option -- -
usage: ./mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile
-h print this help
-E make all warnings errors (non-zero exit status)
-e edition set edition number (part of fsid)
-i file insert a file image into the filesystem (requires >= 2.4.0)
-n name set name of cramfs filesystem
-p pad by 512 bytes for boot code
-s sort directory entries (old option, ignored)
-v be more verbose
-z make explicit holes (requires >= 2.3.39)
dirname root of the directory tree to be compressed
outfile output file
[root@localhost firmware]# ./mkcramfs /fox/extraction /fox/foxware.bin
Directory data: 9008 bytes
Everything: 3728 kilobytes
Super block: 76 bytes
CRC: ffadf25
[root@localhost firmware]# ls
2.bin cramfsck GNUmakefile inftrees.c NOTES win32
adler32.c cramfsck.c gzio.c inftrees.h old zconf.h
algorithm.txt cramfsck.c~ image0 linux projects zconf.in.h
amiga crc32.c INDEX Makefile qnx zlib.3
as400 crc32.h infback.c Makefile.in README zlib.h
ChangeLog deflate.c inffast.c make_vms.com text zutil.c
compress.c deflate.h inffast.h minigzip.c text~ zutil.h
configure example.c inffixed.h mkcramfs trees.c
contrib examples inflate.c mkcramfs.c trees.h
COPYING FAQ inflate.h msdos uncompr.c
[root@localhost firmware]# cd ..
[root@localhost fox]# ls
cramfs-1.1 extraction firmware foxware.bin zlib-1.2.3
[root@localhost fox]#

Так как модернизирована была лишь разбирающая утилита, то необходимо «перевернуть» собранный образ файловой системы. В стандартной поставке Fedora Core 5 не было обнаружено утилиты для преобразования cramfs, поэтому данная утилита была перенесена из системы Debian и носит название cramfsswap.

[root@localhost firmware]# ./cramfsswap
Usage: ./cramfsswap <in> <out>>
[root@localhost firmware]# ./cramfsswap /fox/foxware.bin /fox/foxware_swapped.bin
Filesystem is in hostorder.
Filesystem contains 392 files.
CRC: 0xa95c730f
[root@localhost firmware]# cd ..
[root@localhost fox]# ls
cramfs-1.1 extraction firmware foxware.bin foxware_swapped.bin zlib-1.2.3
[root@localhost fox]#

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

Однако простой замены блока данных с образом файловой системы недостаточно. Необходимо поправить также заголовки файлов. Как упоминалось ранее, в прошивке находятся заголовки трёх файлов, второй из которых и представляет файловую систему. Изменения в заголовках должны быть следующими: длина второго файла должна соответствовать действительности (вместо 3A6000 должно теперь быть 3A4000), смещение третьего файла должно также быть изменено со значения 3B5E28 на 3B3E28. Изменённые заголовки файлов приведены ниже.

0001 0000 0488 0000 0000 0000 F9A0 0000 0000 0000 0000 0000 0000 0000 0000 0000
0002 0000 FE28 0001 0000 003A 4000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0003 003B 3E28 003E 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

Остаются два не менее важных шага по подготовке самого файла прошивки. Как отмечалось ранее 3 и 4 байты прошивки содержат контрольную сумму всего файла, правда, понять, как именно она считается, не удалось. Однако выйти из сложившейся ситуации всё-таки можно. Для этого необходимо попытаться залить прошивку с использованием протоколов FTP или TFTP, а уже существующая версия прошивки подсчитает контрольную сумму и напишет её. Для этой операции был поднят TFTP-сервер от компании 3COM (3CServer 1.1.007). Это бесплатная утилита, которая элементарна в настройке. Ниже приводится лог команд и ответов устройства.

SL500(config)# upgrade tftp 192.168.1.3 foxware.bin
Shutting down Event-Manager and Syslogd [ OK ]
Successfully created and tested attach to shared memory block for software package
##Package Information:
CRC = 0x91cf
Magic No. = 0xbe731504
Min-Max Config. Size = 0x20000
noConfigBackup Flag = 0
Minimum Flash = 0x400000
Minimum RAM = 0x1000000
Version = LX_3.2.3_Comp_0_0_0_b
Components = IRB, QoS, FW
##Models Supported:
SL500
##
##Images:
BOOT: Offset [Package = 1160, Flash = 0x0], Size = 63904
CRAMFS: Offset [Package = 65064, Flash = 0x10000], Size = 3817472
CONFIG: Offset [Package = 3882536, Flash = 0x3e0000], Size = 0
##
##
Invalid package CRC. Expected 91cf, computed 68bc
% Package validation error
Restarting system.

Открываю снова файл прошивки и вижу, что 3 и 4 байты содержат 91CF, хотя в них должны содержаться 68BC. Заменяем значения указанных двух байт на 68BC (SL500_1_1_72A_410_final.bin), после чего прошивание можно производить любым доступным способом (TFTP, FTP, HTTP). Я вновь произвожу обновление через TFTP, полный лог данного обновления приведён ниже.

ASUS CLI User Access Verification
(none) login: admin
Password :
admin logged in
SL500> ena
SL500# conf t
SL500(config)# up t 192.168.1.3 foxware.bin
Shutting down Event-Manager and Syslogd [ OK ]
Successfully created and tested attach to shared memory block for software packa
ge
##Package Information:
CRC = 0x68bc
Magic No. = 0xbe731504
Min-Max Config. Size = 0x20000
noConfigBackup Flag = 0
Minimum Flash = 0x400000
Minimum RAM = 0x1000000
Version = LX_3.2.3_Comp_0_0_0_b
Components = IRB, QoS, FW
##Models Supported:
SL500
##
##Images:
BOOT: Offset [Package = 1160, Flash = 0x0], Size = 63904
CRAMFS: Offset [Package = 65064, Flash = 0x10000], Size = 3817472
CONFIG: Offset [Package = 3882536, Flash = 0x3e0000], Size = 0
##
##
Successfully uploaded new software image. System will now install the new softwa
re and reset automatically with the CURRENT SAVED CONFIGURATION.
Shutting down PPP Interfaces [ OK ]
Shutting down PPP task [ OK ]
Shutting down DB service 0:0:1:4: P
PP : Exceptional exit from ppp_eventTask
[ OK ]
##Package Information:
Magic No. = 0xbe731504
Min-Max Config. Size = 0x20000
noConfigBackup Flag = 0
Minimum Flash = 0x400000
Minimum RAM = 0x1000000
##Models Supported:
SL500
##
##Images:
BOOT: Offset [Package = 1160, Flash = 0x0], Size = 63904
CRAMFS: Offset [Package = 65064, Flash = 0x10000], Size = 3817472
CONFIG: Offset [Package = 3882536, Flash = 0x3e0000], Size = 0
##
##
nobkup is 0, and CONFIG offset + size is identical to current values, hence do
nothing for CONFIG partition
Upgrading bootloader .....
Bootloader successfully upgraded
Upgrading CRAMfs .....
3a0000 bytes
CRAMfs successfully upgraded
SDRAM self-test Pass.....
Hit Return to enter diagnostics
Type II memory configuration
Starting boot...
Power on
bss_start 8099DB40 bss_end 809A2270
Detected Memory: 16 MB
Calibrating delay loop... 132.71 BogoMIPS
Detected CFI Flash Chip
1 @0xBFC00000 Size(4 MB)
Flash self-test pass.
Boot: Detected cramfs filesystem
SecureLink Boot Loader Software
TYP_REL_BOOTSW.4.1.0, Mar 21 2006, 23:45:55
CPU ID 4 Revision 0
Loading CPU 0 .......
Loading CPU 1 ....
Booting up system,please wait...
Detected LX4189 (PRID: c401),
Revision: 0000001e, 16 entry TLB.
Board has been soft reset:0 times
9 MB SDRAM.
Enabling MMU .......done
Loading Lexra 4xxx/5xxx MMU routines.
Determined physical RAM map:
memory: 00988000 @ 00000000 (usable)
memory: 00638000 @ 00988000 (reserved)
memory: 00040000 @ 00fc0000 (usable)
On node 0 totalpages: 4096
zone(0): 4096 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Linux version 2.4.2_hhl20 (root@gdk) (gcc version 2.95.3 20010315 (release/Monta
Vista)) #1955 ¤G 3¤ë 21 23:46:00 CST 2006
rtsched version <20010618.0943.20>
New MIPS time_init() invoked.
Memory: 7640k/10016k available (1500k kernel code, 2376k reserved, 103k data, 44
k init)
Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 1024 (order: 1, 8192 bytes)
Checking for 'wait' instruction... unavailable.
POSIX conformance testing by UNIFIX
Initializing RT netlink socket
Starting kswapd v1.8
pty: 3 Unix98 ptys configured
RTC to Sysclk synchronize Started.
Amd/Fujitsu Extended Query Table v .166 at 0x0040ots per queue
number of CFI chips: 1
Manufacturer ID: c2, Device ID: a8
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 1024)
IP-Config: No network devices available.
Freeing unused kernel memory: 44k freedeadonly.
0:0:8:4: CPU 0 Software Reset
IramStart=80000640,IramSize=39c0
Initializing Crypt.....
Crypt Engine Initialized!
Mode is IRB
Initializing Database
iBE optimized for ALL_ROUTER mode
VPN Addfuncs2Iram
IBE initialization done
Kernel init for VPN successful
ipm_RxTask: Waiting for ICCD MSG
+³{6{s›{c«˜X›[dnÝعted: BusyBox v0.60.2 (2002.10.22-13:52+0000) multi-call bina
ry c›sÖLض›Û·
Starting pid 13, console /dev/console: '/etc/init.d/GOCstartup'
Algorithmics/MIPS FPU Emulator v1.5a
This firmware has been modified by Klimanov Maxim.
Starting modified firmware...
mounting /proc
mounting /dev/pts
setting system clock...
Bringing up loopback interface...done
Creating directories...done
starting user_mgr
starting fileconvertor
starting firewall
...done
bringing up the network
starting evtmgr (syslogd also started)
starting inetd
starting dns
starting ddns
starting sntp
starting l2f_server
starting goahead
Copyright (c) 2002 GoAhead Software Inc. All Rights Reserved
starting dhcpd
starting rip
starting VPN
starting igd
starting pptp
starting ppp
starting monitor
Start my part.
Extracting file fox.script...
assign_memory_buffer:0
rfc_lock:0
extract_file:0
xtract:0
rfc_unlock:0
Changing script (fox.script) rights...
Runing scripStarting pid 120, console /dev/console: '/sbin/getty -L ttyS2 9600 vt100'
ASUS CLI User Access Verification
(none) login: admin
Password :
admin logged in
SL500>

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

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

#!/bin/sh
rfcutil xtract /tmp/fox.console fox.console
/usr/bin/clcli < /tmp/fox.console

Файл дополнительного скрипта (fox.console) также привожу.

admin
admin
ena
conf t
ip arp 192.168.1.2 00:11:22:33:44:55

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

Автор благодарит Нестерова Игоря и Хомутова Владимира за неоценимую помощь в подготовке материала.

You have no rights to post comments

Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter