OpenWrt Based TalkTalk Sagemcom FAST 5364 Tinkering

I managed to brick my TTB router in an attempt to work around the port forwarding bug. This post helped enormously. For anyone else who may stray this way, here's how I managed to recover. BTW: I happen to have two routers without which this can't be done (without images).

Restore through TFTP

  • Configure tftp server at serverip (192.168.1.10)
  • Place the .gsdf file to /srv/tftp/ (used: Linux - Ubuntu - tftpd-hpa)
    • I initially used this image (doesn't connect to TTB though)
      • SG4K10002816t-sagemcom-5364-talktalk-6.72.44.14_Prod-combined-squashfs.img.gsdf to sc_f5364v3.scos.resc.gsdf
    • The destination filename is important
  • Connect console to TTB (see roboconnells post above)
  • Switch on TTB router
  • Wait for
    CPU: BCM63xx
    Model: Sagemcom F5364v3
    DRAM: 512 MiB
    NAND: 512 MiB
    
    Press bar
  • Issue command run upgrade_oper

This may be possible without opening the router (i.e. when it fails to boot it may resort to TFTP) - I didn't check.

Extract Firmware

To get the OEM images from a pristine TTB router.

Connect to the TTB (e.g. Linux - Ubuntu - minicom):

minicom -D /dev/ttyUSB0 -b 115200

Configure a capture log:

^AZ
L
firmware.txt

On the TTB minicom session after interrupting boot:

run _select_main
ubi info l
# used_bytes 22474752 for OEM
ubi read 0x01000000 operational 22474752
md 0x01000000 #objects = 22474752 / 4 + 100 for safety

Wait an hour or so for the dump to complete.

Remove any extraneous lines from the start of the dump:

vi firmware.txt
# md 0x01000000 0x55BC64
# 01000000: 46445347 00303120 00205101 00100000    GSDF 10..Q .....
# :

# remove up to the first memory dump line

Convert the hex to binary with `python3 hex2bin.py firmware.txt firmware.bin:

hex2bin.py:

import argparse
import sys


def hex2bin(textfile, binfile):
    print(f'Txt: {textfile} Bin: {binfile}')

    with open(textfile) as txtFd:
        with open(binfile, 'wb') as binFd:
            for line in txtFd:
                if line[0] != '0':
                    if binFd.tell() != 0:
                        print(f'Format error at {line}')
                        sys.exit(1)
                    continue
                data = line.split()[1:5]
                for quad in data:
                    for idx in range(3, -1, -1):
                        char = quad[idx * 2:idx * 2 + 2]
                        byte = bytes([int(char, 16)])
                        binFd.write(byte)


def main():
    parser = argparse.ArgumentParser(description='hex2bin tool')
    parser.add_argument('textfile')
    parser.add_argument('binfile')

    opts = parser.parse_args()

    hex2bin(opts.textfile, opts.binfile)


if __name__ == '__main__':
    main()

Truncate the file:

dd if=firmware.bin of=firmware.img.gsdf bs=4096 count=5487

As a test, comparing acquired image with uploaded image:

sha1sum firmware.img.gsdf SG4K10002816t-sagemcom-5364-talktalk-6.72.44.14_Prod-combined-squashfs.img.gsdf
13a32d276d8bbee16b6758b78cf537df3e640c39  firmware.img.gsdf
13a32d276d8bbee16b6758b78cf537df3e640c39  SG4K10002816t-sagemcom-5364-talktalk-6.72.44.14_Prod-combined-squashfs.img.gsdf

Repeat for gui volume:

Volume information dump:
        vol_id          1
        reserved_pebs   166
        alignment       1
        data_pad        0
        vol_type        4
        name_len        3
        usable_leb_size 126976
        used_ebs        0
        used_bytes      0
        last_eb_bytes   0
        corrupted       0
        upd_marker      0
        name            gui

Stop and restart the capture.

# 126976 / 8 = 15872
ubi read 0x01000000 gui 126976
md 0x01000000 ...
 dd if=gui of=gui.img.gsdf bs=4096 count=31
# 126976 bytes (127 kB, 124 KiB) copied, 0.000217451 s, 584 MB/s

Hope this helps someone. Apologies if it's a little terse.

2 Likes