For some time now I wanted to open up these magical files that are full of options and settings, making our modems, cameras and other peripherals able to work. This is my starting guide for someone that would like to have a start on firmware reverse engineering. The firmware of my choice is the firmware that is running on wireless Router Sagem F@st 1500WG/1540WG.
There are not many tools that we actually need for a start and for me there was only one not on my system, that tool is binwalk ( http://code.google.com/p/binwalk/ ). I read about binwalk first time on the blog of /dev/ttyS0 ( http://www.devttys0.com ).
So first things first, getting binwalk.tar.gz from http://binwalk.googlecode.com/files/binwalk-0.3.7.tar.gz , current version is 0.3.7 at the time of this writing and starting the compile I notice that my system was missing libcurl library. These days I run mostly ubuntu/debian based systems so if you run on the same problem the solution is the following:
After installing the missing library ./configure , make and make install on the binwalk package completed with no issue.
Searching on Google I found the firmware and downloaded it on my system. Initially the provided package is zip compressed with the name SAGEM_1500WG_ROHS_Firmware_3_0_6.zip.
“file” command identifies “1500WG_SP_FW3_0_6_c.bin” as zip compressed file. At this point my first action was just to try and unzip it,
So indeed, the file contains a compressed binary but there is also a warning saying that some extra bytes exist.
Another procedure to have a vague idea of the contents of the file can be achieved with the use of “strings” and “hexdump” commands.
My first choice here is always to have a look at strings' output first and at this time, interestingly there were the followings:
As we can see form the strings’ output we have some file names showing up, soho.bin, pfs.img, pfs-en.img, pfs-fr.img and ar0700mp.bin.
We can see that binwalk identified 5 different archives and we have from strings 5 different filenames. Proceeding with extracting the files, “dd” command to the rescue,
How to find how many bytes you actually need to extract each time? It’s easy, just subtract the decimal places of the starting positions from the sections, eg.
First position is until from 0 to 951296, the second file length exists between (third – second position) 977920 – 951296 = 26624 bytes.
Starting with the pfs files I went ahead identifying them with binwalk eg,
binwalk pfs.img gave the following results:
I had no prior knowledge of the PFS filesystem and I went ahead with Google search. Initial search results were no good, seems that “PFS filesystem” stands for many things like Professional File System, Playstation File system etc. Checking at the header of the file I notice the magic number
and I went ahead with a new search on PFS/0.9. The second result is for a file decoder from Domen Puncer ( http://cba.si/pfs/ ) for PFS/0.9 files and as described on README ( http://cba.si/pfs/_README ) “ Contents of those files are just HTML pages and images,
they also contain .EXE files, sized 0 bytes. “
I grabbed a copy of http://cba.si/pfs/pfs.c, and compiled the file using gcc –o pfs pfs.c, the result was the binary that I needed and as promised the contents of my pfs.img file were extracted.
As for the other 2 files, soho.bin and ar0700mp.bin, the first is the kernel of our system and the second is the ATM driver ( https://dev.openwrt.org/browser/trunk/package/ar7-atm/ ).