Прошивка для домашних роутеров на примере wrt610N

Здравствуйте, уважаемые читатели.

Данная статья познакомит вас с прошивками для домашних роутеров на примере wrt610N.
В этой статье соберем gpl-версию прошивки и модифицируем оригинальную прошивку, запустив на ней utelnetd.
 

Итак, первая часть.
GPL-версия.

Я рассматриваю GPL-версию как источник знаний, не более.
Скачиваем gpl-версию прошивки с сайта linksys (в нашем случае это wrt610n_v2.00.00.05_us.tar.gz).
Заинтересовавшиеся могут скачать gpl-версии и для других девайсов, в итоге можно получить более полную информацию о прошивке, хотя, конечно же, не всю. По наблюдениям полугодовой давности у них там минимум две команды разработчиков, что касается рассматриваемого примера – это CyberTan.

Настроим среду работы:

Предлагаю следующую структуру на файловой системе:

$ pwd
/home/sergz/Projects/Linksys/wrt610n
$ find
.
./my
./my/gpl
./my/gpl/fresh // тут будет лежать свежая (без изменений) разархивированная версия
./my/gpl/testing // тут будут наши эксперименты
./downloads
./downloads/wrt610n_v2.00.00.05_us.tar.gz // только что скаченный архивчик

*sergz здесь и далее замените на %username%

– Разархивируем:

$ tar xzpf downloads/wrt610n_v2.00.00.05_us.tar.gz -C my/gpl/fresh
$ tar xzpf downloads/wrt610n_v2.00.00.05_us.tar.gz -C my/gpl/testing
$ cd my/gpl/testing/wrt610n_v2.00.00.05_us/

– Настройка окружения:
Следуем инструкциям, находящимся в файле wrt610n_v2.00.00.05_us_readme.txt
Возможно небольшие отклонения, но суть не меняется.
Копируем toolchain в /opt

$ sudo cp -a tools/brcm /opt/
$ sudo mkdir /opt/wrt
$ sudo chown sergz:sergz /opt/wrt
$ cp -a release/tools /opt/wrt/ // понадобится позже, для trx, addpattern

Выставляем пути в окружении:

$ vim ~/.bashrc

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

PATH=$PATH:/opt/brcm/hndtools-mipsel-linux/bin:/opt/brcm/hndtools-mipsel-uclibc/bin/:/opt/wrt/tools/
export PATH

# don't put duplicate lines in the history. See bash(1) for more options
export HISTCONTROL=ignoredups
# ... and ignore same sucessive entries.
export HISTCONTROL=ignoreboth
...

 

Сохраняем файл и перезапускаем терминал.
– Проверяем:

$ mipsel-linux-g++ --version
mipsel-linux-g++ (GCC) 3.2.3 with Broadcom modifications
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Сборка:

Дальше предлагают запустить ./make.sh
Запускаем. Возможно, у вас не хватает каких-то пакетов, доставьте и перезапустите компиляцию (перед этим советую взять свежие исходники).
Вообще, это достаточно долгий процесс, компилить, доустанавливать, освежать сорцы (make clean пока рано делать, т.к. вдруг там что-то не очищается, нас интересует чистота эксперимента) и все заново.
Так что пока ознакомимся с тем, что происходит.
make.sh запускает make_all.sh, который в свою очередь запускает make с действием по умолчанию из директории release/src, что в итоге сводится к запуску make для release/src/router/Makefile с действиями all и install.
В директории release/src/router/ лежат компоненты (как с исходными кодами, так и без), которые будут составлять программное обеспечение нашей прошивки.

Итак, получаем ошибочку (может у вас её и не будет):

mipsel-linux-gcc -o vsftpd main.o utility.o prelogin.o ftpcmdio.o postlogin.o privsock.o tunables.o ftpdataio.o secbuf.o ls.o postprivparent.o logging.o str.o netstr.o sysstr.o strlist.o banner.o filestr.o parseconf.o secutil.o ascii.o oneprocess.o twoprocess.o privops.o standalone.o hash.o tcpwrap.o ipaddrparse.o access.o features.o readwrite.o ssl.o sysutil.o sysdeputil.o -Wl,-s `./vsf_findlibs.sh`
/opt/brcm/hndtools-mipsel-linux/bin/../lib/gcc-lib/mipsel-linux/3.2.3/../../../../mipsel-linux/bin/ld: cannot find -lcap
collect2: ld returned 1 exit status
make[2]: *** [vsftpd] Error 1
make[2]: Leaving directory `/home/sergz/Projects/Linksys/wrt610n/my/gpl/testing/wrt610n_v2.00.00.05_us/release/src/router/vsftpd'
make[1]: *** [vsftpd] Error 2
make[1]: Leaving directory `/home/sergz/Projects/Linksys/wrt610n/my/gpl/testing/wrt610n_v2.00.00.05_us/release/src/router'
make: *** [all] Error 2
cp: cannot stat `release/image/code.bin': No such file or directory

 

Надо же, когда еще была первая версия, я постил об этом на форуме линксис, они проигнорили…
Скачиваем, например, libcap-dev_1.10-14+b1_mips.deb, берем оттуда lib/libcap.a и редактируем release/src/router/vsftpd/vsf_findlibs.sh (название говорит само за себя), прописав путь к libcap.a (например, так echo -L/home/sergz/Projects/Linksys/wrt610n/my/gpl/addons/libcap/lib/ -lcap).

Перезапускаем, все собралось.

---------- add code pattern --------
input file is [/home/sergz/Projects/Linksys/wrt610n/my/gpl/testing/wrt610n_v2.00.00.05_us/release/image/linux.trx]
output file is [/home/sergz/Projects/Linksys/wrt610n/my/gpl/testing/wrt610n_v2.00.00.05_us/release/image/code.bin]

Make date==>Year:9,Month:7,Day:10
Firmware version =>v2.00.00
Add 992 bytes garbage

 

Сравнивать собраный code.bin с FW_WRT610N_2.00.00.05_20090710_code.bin (оригинальная прошивка) нет смысла, т.к. бинарники будут очень сильно отличаться по многим причинам. После прочтения до конца вы сможете сами сравнить gpl-версию с оригинальной.
Итак, зальем получившийся бинарь (/home/sergz/Projects/Linksys/wrt610n/my/gpl/testing/wrt610n_v2.00.00.05_us/Result/code.bin), посмотрим, как оно 🙂
Надо заметить, что в принципе все работает, в отличие от первых версий gpl-ной прошивки.

С первой частью можно закончить.

Вторая часть.
Изменение оригинальной прошивки.

 

Для начала, ознакомимся со структурой файла прошивки.
Воспользовавшись “источником знаний”, заметим, что последним шагом является команда addpattern.
В нашем случае эта утилита добавляет в начало файла некую структуру.
Описание этой структуры хранится не в code_pattern.h (как можно подумать), а в release/src/include/cyutils.h
Берем описание структуры и любимый hex-редактор:

struct code_header {
char magic[4]; // Code Pattern // 610N // char
char res1[4]; // for extra magic // 00 00 00 00 // hex
char fwdate[3]; // Firmware build date // 09 07 0A // hex == // 09 07 10 //dec
// year month day
// что мы и видим, когда собираем gpl версию
// "Make date==>Year:9,Month:7,Day:10"
// единственное, что непонятно, это было 29 января 2010 года... но сейчас не до этого
char fwvern[3]; // Firmware version // 02 00 00 // hex
char id[4]; // U2ND // U2ND // char
char hw_ver; // 0) for 4702, 1) for 4712, 2) for 4712L, 3) for 4704, 4) for 5352E
// 00 //hex
// for 4702
unsigned char sn; // Serial Number // 05 //hex
unsigned short flags; // 1F 00 //hex
unsigned char stable[2]; // The image is stable (for dual image) // 00 00
unsigned char try1[2]; // Try to boot image first time (for dual image) // 00 00
unsigned char try2[2]; // Try to boot image second time (for dual image) // 00 00
unsigned char try3[2]; // Try to boot image third time (for dual_image) // 00 00
unsigned char res3[2]; // 00 00
} ;

Далее видим HDR0 – это начало trx-файла.
Вырежем trx-файл.

$ dd if=..../FW_WRT610N_2.00.00.05_20090710_code.bin of=original.trx skip=32 bs=1

В файле release/src/include/trxhdr.h хранится описание структуры заголовка trx файла.
Возвращаемся к hex-редактору, учитывая, что у нас little-endian.

struct trx_header {
uint32 magic; /* "HDR0" */ // "HDR0"
uint32 len; /* Length of file including header */ // 00 77 70 00 //hex == 7827456 // dec
// размер файла, включая заголовок
// этот размер нам нужен, т.к. в конец нашего файла addpattern что-то записал
uint32 crc32; /* 32-bit CRC from flag_version to end of file */
// 13 94 D2 2F
uint32 flag_version; /* 0:15 flags, 16:31 version */ // 00 00 01 00
uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
// 00 00 00 1С //hex == 28 // dec
// 00 00 08 A4 //hex == 2212 // dec
// 00 0B 3A 48 //hex == 735816 // dec
// это отступы от начала файла
// соответственно:
// ./release/tools/lzma-loader/loader.gz
// в trx файле к нему добавлено еще 3 байта до 2184
// сжатый vmlinux // размер 733604
// файловая система - сжатая squashfs // размер 7827456 - 735816 = 7091640
};

Т.е. файл состоит из трех «подфайлов»:
– декомпрессор (loader.gz)
– ядро
– файловая система.

Извлекаем:

$ dd if=original.trx of=loader.gz skip=28 count=2184 bs=1
$ dd if=original.trx of=vmlinuz skip=2212 count=733604 bs=1
$ dd if=original.trx of=hsqs skip=735816 count=7091640 bs=1

Небольшое замечание:
Это же самое можно было проделать с помощью firmware-mod-kit.
$ svn checkout http://firmware-mod-kit.googlecode.com/svn/trunk/ firmware-mod-kit-read-only
В результате файлы будут одинаковые, за исключением того, untrx почему-то не учел len в структуре trx_header и вырезал ФС вместе с мусором в конце.
В данной статье не преследуется цель дать набор шагов, проделав которые вы получите результат, а дать набор шагов, показывая, что каждый из них представляет.

Распакуем файловую систему:

$ ../firmware-mod-kit-read-only/trunk/src/squashfs-3.0/unsquashfs-lzma -dest fresh-root hsqs
$ ../firmware-mod-kit-read-only/trunk/src/squashfs-3.0/unsquashfs-lzma -dest working-root hsqs

Вот она файловая система роутера. А вот теперь сравнивайте gpl и оригинальную версии сколько влезет. Но это лучше отложить на потом. Пойдем дальше.

Напишем свой traceroute, который запускает utelnetd.

$ vim fake_traceroute.c

#include
int main()
{
system("/usr/sbin/utelnetd & > /dev/null");
return 0;
}

компилируем

$ mipsel-linux-gcc fake_traceroute.c -o fake_traceroute
$ mipsel-linux-strip fake_traceroute
$ file fake_traceroute
fake_traceroute: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.15, stripped

и кладем на нашу ФС:

$ cp ../programming/fake_traceroute/fake_traceroute working-root/usr/sbin/traceroute
cp: overwrite `working-root/usr/sbin/traceroute'? y

Скачиваем utelnetd с сайта sourceforge.
Правим для utelnetd Makefile:

# GNU target string
CROSS :=mipsel-linux-

Сохраняем Makefile и компилируем utelnetd командой make.
Копируем utelnetd:

$ cp ...../utelnetd/utelnetd-0.1.9/utelnetd working-root/usr/sbin/

Теперь собираем бинарник прошивки:
создаем ФС:

$ ../firmware-mod-kit-read-only/trunk/src/squashfs-3.0/mksquashfs-lzma working-root hsqs-w-fake_traceroute -info -le -noappend

теперь нужно собрать trx:
(в первой статье мы копировали release/tools в /opt и проставляли пути, вот тут нам это и пригодится)

$ trx -o my.trx loader.gz vmlinuz hsqs-w-fake_traceroute

осталось только

$ addpattern -i my.trx -o my_code.bin -g -s

---------- add code pattern --------
input file is [my.trx]
output file is [my_code.bin]

Make date==>Year:9,Month:7,Day:10
Firmware version =>v2.00.00
Add 992 bytes garbage
Fill null
$ ls -l my_code.bin
-rw------- 1 sergz sergz 7820288 2010-01-30 19:53 my_code.bin

Итак, зальем нашу прошивку.
Пытаемся подконнектится по телнету, ничего не получается, лезем в Administration->Diagnostics
вбиваем любой адрес, жмем “Start to traceroute”, теперь заходим на роутер по telnet:

$ telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.

WRT610N login:

Вводим логин и пароль – admin

$ cat /proc/cpuinfo
system type : Broadcom BCM4785 chip rev 2
processor : 0
cpu model : BCM3302 V1.10
BogoMIPS : 299.82
wait instruction : no
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : no
hardware watchpoint : no
VCED exceptions : not available
VCEI exceptions : not available
unaligned_instructions : 0
System clocks
(cpu/mem/si/xtal) : 300/150/150/20 Mhz.
dcache hits : 0
dcache misses : 0
icache hits : 0
icache misses : 0
instructions : 0

 

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

Спасибо за внимание.

Читайте также:

  • Ничего не найдено