DI-604 Flash Reverse Engineering

    技术2022-05-11  66

    DI-604 Flash Reverse Engineering

    硬件:D-Link DI-604 (兩年前的塑膠殼新機) CPU: Conexant CX84200-11 的網路處理器 (ARM 9 CPU + 整合式網路晶片), RAM: Hynix HY57V643220, flash

    ROM: MX 29LV800BTC

    Flash image with firmaware version 2.10 flash.bin

    Encoding: little

    Flash memory map:

    0x0000.0000 - 0x0002.0000 - bootloader (permanent) (used up to 0x1.39e0) 0x0000.0000 - 0x0000.1800 - initialisation code 0x0000.1800 - 0x0000.3000 - uncompression code (ARJ), copied to the 0x2030.0000 prior to execution 0x0000.3000 - 0x0001.0000 - ARJ compressed "factory setting" restoration image 0x0001.0000 - 0x0001.39e0 - text strings/ configuration data ??? 0x0001.39e0 - 0x0002.0000 - empty space ?? 0x0002.0000 - 0x0010.0000 - ARJ compressed firmware image - upgradable via HTTP or TFTP (current version is 2.10) 0x2000.0000 - SDRAM start 0x2038.0000 - 0x2039.477b 2038.3884 - ?? 2038.3964 - ??

    Firmware Format

    Info from Chris Windibank, 01/Mar/04

    The firmware file is always 917,504 (0xe0000) bytes in length, presumably because it's a 1MB flash and the bootloader, backup firmware and settings area is 131,072 (0x20000) which leaves exacly that amount!

    It is checksummed by the attached code. They decided to xor all bytes together and check it against a know value. I'm not really an expert in checksums so I can't say if this is unusual or not but it's certainly not a mainstream algorithm.

    The first part of the file is the actual firmware in ARJ format using the -m1 compression mode and the archive consists of a single file named NML.MEM. The unused area after the firmware is zeroed and finally a signature and checksum is attached at the end. The signature is constant and the checksum can be calculated by xoring all the bytes in the file minus the checksum area and then xoring the result with 0xaabbbbaa.

    The attached file can be used to generate a valid flash binary. I am a WindowsXP user and it was tested with Visual Studio 6.0 but it only contains C standard library calls so it should compile fine with GCC. It's usage is as follows:

    mkflash outfile - where outfile is the name of the output file (I use di604_firmware_ucl.bin)

    It expects to find a file name NML.ARJ in the current directory (the first version took and input file but I got tired of typing it). I have been renaming zImage NML.MEM and then using the following to make the archive for mkflash.

    arj32 a -m1 NML.ARJ NML.MEM

    I'm not sure if the firmware checks to see if the arjed file in the archive is actually name NML.MEM but that is the way DLink does it so I did the same.

    The bootloader expands the archived firmware sitting at 0x20000 in flash ROM to 0x20000000 in RAM. It then flips the RAM/ROM address spaces and jumps to address 0 which is the begginning of RAM after the flip.

    At this point the router will start to execute zImage which is a compressed kernal and ramdisk. It should decompress the kernal and ramdisk and then jump to the entry point of the decompressed kernal. I chose to go with the compressed kernal because it's an easy way to get the ramdisk into memory from a single arjed archive. It may be better to try something different later when the kernal is actually working!

    Bootloader decoding

    AddressDescriptionCalls Called by 0x0000Exceptions vectors.Reset/IRQ-0x0048 - 0x007cSwitch between 0 address from Flash mem to SDRAM.-0x2E00x0080 - 0x0254Initialisation: SDRAM memory controller Flash memory contorller GPIO Pass contorol to 0x500 0x5000x00000x0268 - 0x0268Endless loop-0x3240x026C - 0x028Cread input value of the GPIO[6] (CONFIG RESET TO FACTORY). return 1 if input 0; -0x3240x0290 - 0x02DCXOR starting from start_addr(r0) for bytes(r1) lengthReturn 0 if ==0xaabbbbaa else return -1 -0x324 0x02E0 - 0x320memcpy(src,dst,len)-0x324 0x0324 - 0x03D0 check SRC of the main firware (0x2000) check reset buttom load uncompression code to SDRAM if RESET load from 0x03000 if no RESET load from 0x20000 if uncompression return 1 - then switch memory and start from 0 -0x08740x03D4 - 0x042cUART-0x46C0x0430 - 0x043cRead UART0 flag register for "receive FIFO full"-0x46C0x0440 - 0x0468--0x46C0x046c - 0x04dcno direct call-call itself ??0x04E0 - 0x04fcno direct call!!--0x0500 - 0x0870Calculates relocated addreses Clean mem region 0x20380000(0x1477B bytes) memcpy(0x11a9,0x1145,0x24) copy to flash???? call 0x0874indirect 0x08740x800x0874 - 0x09c0do nothing;call 0x324;call 0xA08;0x09c4 0x0e20 0x0db0 0x0324 0x0a08 indirect call 0x0500 0x09C4 - 0x09E0 void f_0x9c4() { f_0xebc(16,-1); return; } -0x08740x09E4 - 0x0A04---0x0A08 - 0x0AC8---0xacc - 0xae4--no direct call0xae8 - 0xd24memcpy(src,dst,len)-indirect call 0x500 0xd28 - 0xdacmemset(addres, char , len) - set memory region with a specific byte-indirect call0x500 0x0db0 - return 20383884;-indirect call0xEDC 0x0ebc - 0x0ed8 *20383884 = r0; return -1; -0x09c40x0edc - 0x0f20 if(!f_0x00db0) return 20383964; else return f_0x0db0(); // 20383884 -0x0f240x0f24 - 0x0f44 void f_0x0f24(word val){ { word *addr; addr = f_0x0edc(); if(addr!=0) *addr = val; return; } -0x0ebc0x0f48 - ---0x1134indirect function call (call addr in IP registerIP defined addressmultiple0x1138function to do nothing???? OR first parameter to itself and exit. What the big deal??-0x0ebc----0x29C4 - 0x2F9Clast function--

    indirectly called functions 0x4e0 0xacc - 0xae4 0xae8 - 0xd24 0xd28 - 0xdac


    $Id: flash_mem.html,v 1.5 2004/03/14 11:07:16 bcabral Exp $  

    最新回复(0)