poloniumv's

Сливание прошивки с древней железяки

1 февраля 2017 г. 15:37

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

RS-232 кабелем подсоединился к железке и начал подбирать нужный baud rate (прошивка, как и загрузчик, к слову, не оригинальные, которые идут в поставке). Подобрав, получил приветствие:

RedBoot(tm) bootstrap and debug environment [ROM]
Red Hat certified release, version 1.92 - built 10:44:29, Apr  9 2004

Platform: IXDP425 Development Platform (XScale) 
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x00000000-0x10000000, 0x0001f9b8-0x0ffd1000 available
FLASH: 0x50000000 - 0x50800000, 64 blocks of 0x00020000 bytes each.

Bootcode Version 1.9 2004/04/08
== Executing boot script in 2.000 seconds - enter ^C to abort

Естественно, сразу зажал ^C и получил приглашение:

RedBoot> help
Load RAM-Statup Redboot!
   ramstart 
Upgrade Redboot itself!
   upgradeBTLD 
Manage aliases kept in FLASH memory
   alias name [value]
Set/Query the system console baud rate
   baudrate [-b <rate>]
Manage machine caches
   cache [ON | OFF]
Display/switch console channel
   channel [-1|<channel number>]
Compute a 32bit checksum [POSIX algorithm] for a range of memory
   cksum -b <location> -l <length>
Display (hex dump) a range of memory
   dump -b <location> [-l <length>] [-s] [-1|2|4]
Execute an image - with MMU off
   exec [-w timeout] [-b <load addr> [-l <length>]]
        [-r <ramdisk addr> [-s <ramdisk length>]]
        [-c "kernel command line"] [<entry_point>]
Manage FLASH images
   fis {cmds}
Manage configuration kept in FLASH memory
   fconfig [-i] [-l] [-n] [-f] [-d] | [-d] nickname [value]
Execute code at a location
   go [-w <timeout>] [entry]
Help about help?
   help [<topic>]
Set/change IP addresses
   ip_address [-l <local_ip_address>] [-h <server_address>]
Load a file
   load [-r] [-v] [-d] [-h <host>] [-m <varies>] [-c <channel_number>] 
        [-b <base_address>] <file_name>
Compare two blocks of memory
   mcmp -s <location> -d <location> -l <length> [-1|-2|-4]
Fill a block of memory with a pattern
   mfill -b <location> -l <length> -p <pattern> [-1|-2|-4]
Network connectivity test
   ping [-v] [-n <count>] [-l <length>] [-t <timeout>] [-r <rate>]
        [-i <IP_addr>] -h <IP_addr>
Reset the system
   reset 
Set/Read MAC address for NPE ethernet ports
   set_npe_mac [-p <portnum>] [xx:xx:xx:xx:xx:xx]
Display RedBoot version information
   version 
Display (hex dump) a range of memory
   x -b <location> [-l <length>] [-s] [-1|2|4]
Boot in zcom's way!
   ixp425boot 
RedBoot>

Посмотрел где, что и по каким адресам лежит:

RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0x50000000  0x50000000  0x00060000  0x00000000
RedBoot config    0x507C0000  0x507C0000  0x00001000  0x00000000
Config backup     0x507C1000  0x507C1000  0x00001000  0x00000000
FIS directory     0x507E0000  0x507E0000  0x00020000  0x00000000
ixp425            0x50060000  0x50060000  0x00600000  0x01600000
RedBoot>

Отлично, ixp425, а это и есть прошивка, мне как раз и надо! Включил в PuTTY запись всего выхлопа в файл и запустил дамп:

RedBoot> dump -b 0x50060000 -l 0x00600000
50060000: 28 CD 3D 45 00 3C 80 00  00 00 04 03 00 00 00 00  |(.=E.<..........|
50060010: 43 6F 6D 70 72 65 73 73  65 64 20 52 4F 4D 46 53  |Compressed ROMFS|
50060020: 47 3C 20 1F 00 00 00 00  00 00 03 8A 00 00 00 20  |G< ............ |
50060030: 5A 57 4C 39 33 30 30 00  00 00 00 00 00 00 00 00  |ZWL9300.........|
50060040: 41 FF 00 00 00 02 88 00  00 08 4D 88 E1 0F 20 00  |A.........M... .|
50060050: E3 82 20 C0 E1 21 F0 02  E3 CF 20 1F E2 82 38 01  |.. ..!.... ...8.|

...

5065FFC0: BB 17 BA F7 3A 4B AA 16  A7 C9 CF 7F 88 C9 8A 45  |....:K.........E|
5065FFD0: BA 1D F8 F0 A7 7C 68 0D  F2 74 27 05 4B 55 9C 55  |.....|h..t'.KU.U|
5065FFE0: BA 5F EA 37 7C 57 22 C7  BB 74 A5 7D CB 03 A0 1F  |._.7|W"..t.}....|
5065FFF0: C8 D8 A2 55 2F 54 AA D5  0B 7B EA F5 62 83 AA 25  |...U/T...{..b..%|

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

# -*- coding: utf-8 -*-

import string

fd = open('firmware.dump', 'r')
raw_data = fd.read()
fd.close()

byte = 0
last_byte = 3964936
fd = open('firmware.rmt', 'w')
raw_data_arr = string.split(raw_data, '\r')
for line in raw_data_arr:
    item_arr = string.split(line, ' ')
    for i in range(1, 18):
	    if i != 9:
	        if byte < last_byte:
		        fd.write(chr(int(item_arr[i], 16)))
		        byte += 1
	        else:
		        break
fd.close()

3964936 -- последовательный номер последнего байта -- я получил отследив HEX-последовательность окончания прошивки "30 38 34 36" + еще 4 байта (контрольная сумма, насколько я понял).