DI-604 Flash Reverse Engineering

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.
-0x2E0
0x0080 - 0x0254Initialisation:
  • SDRAM memory controller
  • Flash memory contorller
  • GPIO
    Pass contorol to 0x500
0x5000x0000
0x0268 - 0x0268Endless loop-0x324
0x026C - 0x028Cread input value of the GPIO[6] (CONFIG RESET TO FACTORY). return 1 if input 0;
-0x324
0x0290 - 0x02DCXOR starting from start_addr(r0) for bytes(r1) length
Return 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
	   
-0x0874
0x03D4 - 0x042cUART-0x46C
0x0430 - 0x043cRead UART0 flag register for "receive FIFO full"-0x46C
0x0440 - 0x0468--0x46C
0x046c - 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 0x0874
indirect 0x08740x80
0x0874 - 0x09c0do nothing;
call 0x324;
call 0xA08;
0x09c4 0x0e20 0x0db0 0x0324 0x0a08 indirect call
0x0500
0x09C4 - 0x09E0
void  f_0x9c4()
{
   f_0xebc(16,-1);
   return;
}	   
-0x0874
0x09E4 - 0x0A04---
0x0A08 - 0x0AC8---
0xacc - 0xae4--no direct call
0xae8 - 0xd24memcpy(src,dst,len)-indirect call
0x500
0xd28 - 0xdacmemset(addres, char , len) - set memory region with a specific byte-indirect call
0x500
0x0db0 - return 20383884;-indirect call
0xEDC
0x0ebc - 0x0ed8
*20383884 = r0;
return -1;
-0x09c4
0x0edc - 0x0f20
 if(!f_0x00db0)
       return 20383964;
 else
       return f_0x0db0(); // 20383884
	   
-0x0f24
0x0f24 - 0x0f44
void f_0x0f24(word val){
{
  word *addr;
  addr = f_0x0edc();
  if(addr!=0)
       *addr = val;
   return;
}
	  
-0x0ebc
0x0f48 - ---
0x1134indirect function call (call addr in IP registerIP defined addressmultiple
0x1138function 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 $  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值