unmk2 / firmware-mod-kit

Automatically exported from code.google.com/p/firmware-mod-kit
0 stars 0 forks source link

Not working for DLink DIR-645 f/w #85

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Goto tsd.dlink.com.tw and select router DIR and model 645 and d/l f/w 1.03
2. extract-ng and build-ng
3.

What is the expected output? What do you see instead?
New file about 300K larger, so used -min and that seemed to succeed.
The router accepted the new f/w, but it never came up again - it is bricked.

What version of the product are you using? On what operating system?
Latest svn rev 374 on Ubuntu 12.10 32-bit.

Please provide any additional information below.

Original issue reported on code.google.com by Anthony....@gmail.com on 25 Jan 2013 at 10:24

GoogleCodeExporter commented 9 years ago
What was the end filesize of the firmware? Did it cross a MB boundary? I would 
guess that it did, causing the failure. Most firmwares are 'full', meaning if 
you're going to add much to them, you're going to need to remove something. In 
some cases, the simple process of extraction and rebuilding can increase the 
filesize due to changes in the compression parameters and/or arrangement of 
data in the filesystem.

Original comment by jeremy.collake@gmail.com on 26 Jan 2013 at 4:48

GoogleCodeExporter commented 9 years ago
I only changed 2 files, increasing the size by about 100 bytes only. The new 
firmware was more than 200K larger:
  Original: 7614608
  Current: 7827600
So I added the -min option:
  Remaining free bytes: 315392
So I went ahead and flashed it. The router was happy with the format and CRC, 
etc. I expect it could not correctly mount the rootfs however and I can't find 
any way to restore the original f/w.

Original comment by Anthony....@gmail.com on 26 Jan 2013 at 5:49

GoogleCodeExporter commented 9 years ago
D-Link and Trednents (often near identical at the hardware level) usually have 
a router recovery mode that can accessed in one of the usual ways. Sometimes 
there is some software to make this easy. Other times, you may need to manually 
TFTP to the router during pre-boot initialization, or after a failed boot 
(depending on how the firmware fails). Sometimes this can be invoked by holding 
down the reset button during boot. In all cases, restoration should be 
completely do-able, if you give it some effort, as the bootloader is still 
there...

Original comment by jeremy.collake@gmail.com on 26 Jan 2013 at 5:57

GoogleCodeExporter commented 9 years ago
I tried holding in the reset button during power up and the router remained 
unpingable on rhe previous as well as default IP. So no chance of getting to a 
web f/w recovery page (assuming this model ever had one). I also tried to send 
the file via tftp but no luck. I entered a static ARP entry to tell the 
computer the routers MAC address on the LAN i/f. I also tried to look for any 
ARP requests coming in using tcpdump but only saw the outgoing ARPs for the 
computer. So I assumed this model does not support tftp, but maybe I missed 
something?

Original comment by Anthony....@gmail.com on 26 Jan 2013 at 6:16

GoogleCodeExporter commented 9 years ago
I don't know, check the vendor's documentation. I haven't checked out that 
particular device's firmware, but don't see how a failure could occur since the 
boot loader is not normally touched by firmwares. The noted exception was my 
old VxWorks Killer, which achieved dominance over VxWorks by using an 
undocumented feature of the firmware format that allowed the bootloader to be 
replaced. Anyway, the router should be recoverable from every perspective I 
see. Contact D-Link's support department if you have to.

I suppose it is possible that some vendors killed the recovery mode, opting 
instead for router replacement. This seems unlikely though.

As for the Firmware Mod Kit, it seems unlikely that anyone will closely 
investigate the cause of the failure here, though perhaps they will. I will 
leave this ticket for anyone who wants to jump in. There are so many routers 
out there, most people aren't concerned with those they don't own. This creates 
a highly fragmented market. Thankfully, the common use of linux, common 
filesystems, and identifiable, unsigned/unencrypted firmware formats allows 
existence of the firmware mod kit.

Original comment by jeremy.collake@gmail.com on 26 Jan 2013 at 6:28

GoogleCodeExporter commented 9 years ago
From what I've read, it seems tftp can be hardcoded to expect specific IPs for 
not only the router but the computer too. This router has a default IP of 
192.168.0.1. One article mentioned 192.168.1.1 and the router trying to arp 
192.168.1.113 if I remember right. Another mentions using 192.168.11.1 and 
192.168.11.2. I could not find a clear explanation anywhere? Do you have any 
more info on this?

Original comment by Anthony....@gmail.com on 26 Jan 2013 at 6:28

GoogleCodeExporter commented 9 years ago
Later in the week I'll have time to give it a closer look. I will check the 
exact parameters of unsquash/makesquash - this router seems to use 
squashfs-4.0-lzma.

Original comment by Anthony....@gmail.com on 26 Jan 2013 at 6:33

GoogleCodeExporter commented 9 years ago
I checked the binwalk log and I copied the block size there into the 
build-ng.sh script to force it to be the same as the original f/w. Now the 
spare bytes is exactly 0 and the new f/w is the exact same size as the old one. 
This seems a bit better to me, and perhaps it would be better if the script 
automatically set the block size to the same value from the extract?

Original comment by Anthony....@gmail.com on 27 Jan 2013 at 7:44

GoogleCodeExporter commented 9 years ago
Yes, that sounds appropriate. I will dive into this when I can and automate the 
process. Thanks!

Original comment by jeremy.collake@gmail.com on 27 Jan 2013 at 9:34

GoogleCodeExporter commented 9 years ago
Here is the noted information about this device at the OpenWrt wiki btw: 
http://wiki.openwrt.org/toh/d-link/dir-645 . Should have looked this up this 
before.

If you're going to play with these babies, you should order one of these and 
make your life fun: 
http://www.amazon.com/gp/product/B006JKNWLE/ref=oh_details_o03_s00_i00 .

Original comment by jeremy.collake@gmail.com on 29 Jan 2013 at 3:24

GoogleCodeExporter commented 9 years ago
I already read that. It does not really help, unless you are suggesting I use 
the tools from the GPL source to build the f/w instead of firmware-mod-kit? I 
can't see how it would help unless perhaps the mod kit is not correctly 
handling the headers? I'm hoping the problem was simply the incorrect block 
size. I'm assuming using a 1MB bs instead of the 262144 (0x40000) is what 
bricked the device. I am hoping to be able to test this by copying the 
rootfs.img part to the router and mounting it on ramdisk (/var/tmp). I expect 
the original to work and the bad one to fail. However I must look closer at the 
headers too.

I should still have a RS232C to TTL converter lying around, but to use that I 
need to break the seal and open the device which would void my warranty and it 
is brand new. I should receive a replacement by tomorrow.

As for tftp it really did not work - I tried it with a protocol analyser 
running and could see absolutely nothing from the LAN port. Interestingly, the 
WAN port still managed to acquire an IP via DHCP and I wonder if there is a 
chance they moved the tftp over to the WAN side for recovery? I did not have 
time to try it though as I had to drop it off at the supplier.

Original comment by Anthony....@gmail.com on 29 Jan 2013 at 6:33

GoogleCodeExporter commented 9 years ago
I inserted in extract-ng.sh:
  FS_BLOCKSIZE=$(echo ${LINE} | sed -e 's/.*blocksize: //' | cut -d' ' -f1)
  ...
  echo "FS_BLOCKSIZE='${FS_BLOCKSIZE}'" >> ${CONFLOG}

and to build-ng.sh:
        if [ "$NEXT_PARAM" == "-min" ]
        then
            BS="-b $((1024*1024))"
        else
            BS="-b $FS_BLOCKSIZE"
        fi

Original comment by Anthony....@gmail.com on 29 Jan 2013 at 4:07

GoogleCodeExporter commented 9 years ago
Thanks! I'll commit and test this ASAP. I am doing some embedded systems work 
(first time in a couple years), so it is good timing.

Original comment by jeremy.collake@gmail.com on 29 Jan 2013 at 7:42

GoogleCodeExporter commented 9 years ago
I got a replacement router and I dumped the bootloader. In it I see a web page 
which is the "emergency room" for reflashing the unit. I also see a menu driven 
interface to enable flashing via the serial console (kermit) or by connecting 
to a tftp server. However to get into this it seems the only way is via the 
internal serial interface. I'm puzzled therefore as to why I could not get into 
the web interface no matter what I tried. I'm wondering if on this model they 
moved the recovery interface from the LAN to WAN? During boot the WAN was still 
getting an IP via DHCP but I did not have a chance to try that before I had to 
swap out the unit for the new one.

Original comment by Anthony....@gmail.com on 31 Jan 2013 at 8:51

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I tried that and it did not work. However I used the MAC address of the LAN i/f 
and it looks like there will be absolutely no response from the router unless 
it sees a packet with the correct MAC which is not necessarily the usual MAC, 
but rather some fake MAC. I looked in the bootloader and see:

ethaddr="00:AA:BB:CC:DD:10"
ipaddr=10.10.10.123
serverip=10.10.10.3

which is different to what is in the article. However elsewhere in the 
bootloader I see the real MAC address and:
ipaddr=192.168.0.101
serverip=1.2.3.103

This is odd as they're not even in the same subnet.

I also suspect there is a chance they might have moved recovery from the LAN to 
the WAN interface, though I do see: ethact=Eth0 (10/100-M)

Last night I had the idea of trying to mount the rootfs.img on the ramdisk at 
/var/tmp to confirm that it can mount OK, but I ran into a problem. There is no 
loop device defined! I don't think it is enough to just mknod /dev/loop0 b 7 8. 
That did not help. Any ideas here how I might mount it without flashing the 
f/w? It seems the squashfs support is in the bootloader itself? So I was not 
able to test it this way. Maybe I need to build squashfs and losetup and load 
them? I've never tried this so not sure what is needed. I did just setup a VM 
with Fedora 10 which is the environment DLink require to build their f/w.

Original comment by Anthony....@gmail.com on 1 Feb 2013 at 5:29

GoogleCodeExporter commented 9 years ago
Is it possible that creating the squashfs on linux 3.x (ubuntu) will give 
problems when mounting it on linux 2.6 (the router)? For example the way the 
IDs for block and character nodes are packed differs between different flavors 
of linux.

Also, I wonder if it is better to replace sudo in your build-ng.sh with 
fakeroot?

Other than the above two points, I can think of no other reason the f/w would 
not work, other than using the wrong blocksize of 1MB (-min option) when the 
original used 256KB.

Original comment by Anthony....@gmail.com on 1 Feb 2013 at 5:37

GoogleCodeExporter commented 9 years ago
In the f/w the seama hdr indicates the size of the f/w that follows, which 
starts with the compressed kernal.img, which  is then padded with nulls to the 
next 64K boundary in the file, followed by a 32 byte header as follows:
--PaCkImGs-- (12 bytes)
00..00 (4 nulls)
size of roots.img (4 bytes)
00..00 (12 bytes)
rootfs.img

The rootfs.img is itself padded with nulls to the next 4K boundary.

build-ng.sh will append rootfs.img to the preceding data without updating any 
sizes - only the 16-byte checksum (md5), and then pad the rootfs.img with FF to 
the original size.

So using the -min option results in an img that is about 200K smaller, padded 
with FF. I wonder if the flasher just writes the extra data to the ROM or if it 
gets confused by the FFs and takes it as another file and overwrites another 
partition such as nvram? Or if the bootloader gets messed up by it?

I have now successfully built the f/w from scratch using the GPL source and 
will try to modify the f/w again but this time on linux 2.6 (Fedora 10) which 
is the correct build environment for this f/w rather than linux 3 (Ubuntu 12). 
Hopefully this will work.

The possible problems must have been one of:
Packing rootfs on linux 3 and mounting on the router running linux 2.6
Using a 1MB block size when the original uses 256K
Using sudo instead of fakeroot so perhaps a file was owned by me instead of 
root.
Padding the img with FF rather than 00 and having too much padding.
Will let you know if it succeeds once I get there :)

Original comment by Anthony....@gmail.com on 2 Feb 2013 at 11:00

GoogleCodeExporter commented 9 years ago
NEW F/W WORKING!

I extracted the latest f/w on Fedora 10 (linux 2.6.27) (router running 2.6.33).
However I changed sudo in extract-ng.sh to fakeroot.
I changed the files under rootfs that I needed to.
However to build the new f/w, just to be sure, I first extracted the kernel.img 
from header.img by stripping the first 32 bytes and also removed the null 
padding at the end and made sure that lzma could successfully decompress it.
Then I reassembled using the tools in the GPL source:
First:
fakeroot mksquashfs ~/dlink/fw103/image_parts/rootfs 
~/dlink/fw103/newrootfs.img -b 256k
Note the blocksize matches the original f/w.
Note also that I first did this (from their build script):
chmod 664 newrootfs.img
and also:
chmod 775 kernel.img
Then pack the two images together padding kernal to 64K boundary, adding 
packimgs header with fs filesize:
tools/building/packimgs -o raw.img -i kernel.img -i newrootfs.img
Then add the seema header and md5 checksum:
tools/seama/seama -i raw.img -m dev=/dev/mtdblock/2 -m type=firmware
And add the first seama header:
tools/seama/seama -s web.img -i raw.img.seama -m signature=wrgn39_dlob.hans_645
Finally rename the file:
mv web.img DIR645A1_FW103B11.bin

I believe build-ng.sh would have created the same file if sudo was replaced 
with fakeroot and the -b 256k was added. I can't check this since the 
rootfs.img is different (probably due to timestamps?).

Original comment by Anthony....@gmail.com on 2 Feb 2013 at 4:51

GoogleCodeExporter commented 9 years ago
Congratulations ;). I will review your steps and update the FMK when I can. 
Thanks for reporting those steps in detail, others may find that immediately 
useful.

Original comment by jeremy.collake@gmail.com on 2 Feb 2013 at 8:33

GoogleCodeExporter commented 9 years ago
I finally added support to preserve the block size. I had forgot about your 
patch here, and my code is actually not as pretty in the parsing of the block 
size in the build script, so I will likely replace it with yours! Sorry it took 
so long, I avoid thinking as long as possible.

Original comment by jeremy.collake@gmail.com on 10 Apr 2013 at 6:37

GoogleCodeExporter commented 9 years ago
err I mean extract script

Original comment by jeremy.collake@gmail.com on 10 Apr 2013 at 6:38