NETGEAR unsquashfs.c version 1.3

Last month I posted a portion of a ridiculous conversation with NETGEAR over source code it withheld to unpack the filesystem on one of its routers.  I would like to announce that against all expectations, NETGEAR actually pulled through and sent me the source code I was looking for!

As mentioned previously, I posted a detailed explanation of my situation over on the OpenWRT forum.  To avoid any unnecessary re-explaining of background information, I’ll copy/paste it here:


Hey guys,

I’m trying to unpack SquashFS on the WNR1000v3 1.0.2.26 but have been running into lots of issues.

The firmware image is available here: http://www.downloads.netgear.com/files/WNR1000v3-V1.0.2.26_51.0.59NA.chk

The source for it is available here: http://www.downloads.netgear.com/files/GPL/WNR1000v3-V1.0.2.26_51.0.59NAWW_src.tar.zip

binwalk 0.4.2 provides the following output:

DECIMAL   	HEX       	DESCRIPTION
-------------------------------------------------------------------------------------------------------
58        	0x3A      	TRX firmware header, little endian, header size: 28 bytes,  image size: 2584576 bytes, CRC32: 0x9861D9FF flags/version: 0x10000
86        	0x56      	LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 1634304 bytes
592666    	0x90B1A   	Squashfs filesystem, little endian, non-standard signature,  version 3.0, size: 1988809 bytes, 421 inodes, blocksize: 65536 bytes, created: Fri Jul 16 06:30:19 2010

Extract the filesystem at offset 592666:

$ dd if=WNR1000v3-V1.0.2.26_51.0.59NA.chk of=filesystem.bin bs=592666 skip=1
3+1 records in
3+1 records out
1991968 bytes (2.0 MB) copied, 0.0391462 s, 50.9 MB/s

As noted by binwalk, the filesystem has a non-standard magic number:

$ hexdump -C filesystem.bin | head -n2
00000000  73 68 73 71 a5 01 00 00  84 7a 00 37 dc 7c 00 de  |shsq.....z.7.|..|
00000010  8a 04 08 40 06 01 40 02  00 63 00 09 03 00 00 00  |...@..@..c......|

Trying to unpackage it immediately returns the following error:

$ unsquashfs filesystem.bin
Can't find a SQUASHFS superblock on filesystem.bin

…which is to be expected. Correct the magic number to “hsqs” and now:

$ unsquashfs filesystem.bin
Parallel unsquashfs: Using 2 processors
gzip uncompress failed with error code -3
read_block: failed to read block @0x1e547f
read_fragment_table: failed to read fragment table block
FATAL ERROR aborting: failed to read fragment table

A little sleuthing returns that the filesystem is actually compressed using lzma, not gzip, so try a different compilation:

$ ../../../firmware-mod-kit-read-only/trunk/src/others/squashfs-4.0-lzma/unsquashfs-lzma filesystem.bin
Parallel unsquashfs: Using 2 processors
uncompress failed, unknown error -3
read_block: failed to read block @0x1e547f
read_fragment_table: failed to read fragment table block
FATAL ERROR aborting: failed to read fragment table

I can confirm that none of the publicly available unsquashfs utilities I can find are able to unpackage the file. I’ve tried using every version of unsquashfs, every variant of it, in every package that incorporates it (e.g., firmware-mod-kit). firmware-mod-kit’s scripts are unsuccessful as well.

Looking through the firmware source code, I see:

$ find . -name *squash*
./src/router/mipsel-uclibc/target.squashfs
./src/router/squashfs
./src/router/squashfs/mksquashfs.c
./src/router/squashfs/mksquashfs.h
./src/linux/linux/scripts/squashfs
./src/linux/linux/scripts/squashfs/mksquashfs
./src/linux/linux/scripts/squashfs/mksquashfs.c
./src/linux/linux/scripts/squashfs/mksquashfs.h
./src/linux/linux/scripts/squashfs/squashfs_fs.h
./src/linux/linux/fs/squashfs
./src/linux/linux/fs/squashfs/.squashfs2_0.o.flags
./src/linux/linux/fs/squashfs/squashfs2_0.o
./src/linux/linux/fs/squashfs/squashfs.o
./src/linux/linux/fs/squashfs/squashfs.h
./src/linux/linux/fs/squashfs/squashfs2_0.c
./src/linux/linux/fs/squashfs/.squashfs.o.flags
./src/linux/linux/include/linux/squashfs_fs_i.h
./src/linux/linux/include/linux/squashfs_fs.h
./src/linux/linux/include/linux/squashfs_fs_sb.h
./src/linux/linux/include/config/squashfs.h
./src/linux/linux/include/config/squashfs

…and unfortunately no unsquashfs.c code. In the meantime, I’ve contacted Netgear asking if they have it available.

The exact version they’re using is a bit confusing:

$ grep "mksquashfs version" -r .
./src/router/mipsel-uclibc/target/lib/modules/2.4.20/build/scripts/squashfs/mksquashfs.c:	printf("mksquashfs version 2.2-r2n");
./src/router/squashfs/mksquashfs.c:	printf("mksquashfs version 3.2-r2 (2007/01/15)n");
./src/linux/linux/scripts/squashfs/mksquashfs.c:	printf("mksquashfs version 2.2-r2n");

Grepping for our non-standard magic number reveals:

$ grep 0x73687371 -r .
./src/router/mipsel-uclibc/target/lib/modules/2.4.20/build/include/linux/squashfs_fs.h:#define SQUASHFS_MAGIC_LZMA_SWAP	0x73687371
./src/linux/linux/include/linux/squashfs_fs.h:#define SQUASHFS_MAGIC_LZMA_SWAP	0x73687371

Okay, great. Some Googling and it seems that this patch should do the trick: https://dev.openwrt.org/browser/trunk/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch?rev=28489
Patch unsquashfs, rebuild, and:

$ ./unsquashfs ../../filesystem.bin
Parallel unsquashfs: Using 2 processors
lzma uncompress failed with error code 1
read_block: failed to read block @0x1e547f
read_fragment_table: failed to read fragment table block
FATAL ERROR aborting: failed to read fragment table

Would anyone have any advice to offer, or mind lending a hand trying to get this filesystem unpackaged? Thank you in advance.


After about a month of back and forth conversation with their technical support team, I finally received a message linking me to the unsquashfs.c file I was looking for (download link is at the end of this post).

The following steps outline how to compile:

  1. Download and extract http://www.downloads.netgear.com/files/GPL/WNR1000v3-V1.0.2.26_51.0.59NAWW_src.tar.zip
  2. Copy unsquashfs.c into bcm5356/src/router/squashfs
  3. `cd bcm5356/src/router/squashfs; make`
sh-4.1$ ./unsquashfs
SYNTAX: ./unsquashfs [options] filesystem [directory or file to extract]
	-v[ersion]		print version, licence and copyright information
	-i[nfo]			print files as they are unsquashed
	-l[s]			list filesystem only
	-d[est] 	unsquash to , default "squashfs-root"
	-f[orce]		if file already exists then overwrite
sh-4.1$ ./unsquashfs -version
unsquashfs version 1.3 (2007/01/02)
copyright (C) 2007 Phillip Lougher 

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
sh-4.1$

And to demonstrate its functionality:

sh-4.1$ dd if=WNR1000v3-V1.0.2.26_51.0.59NA.chk of=filesystem.bin bs=592666 skip=1
3+1 records in
3+1 records out
1991968 bytes (2.0 MB) copied, 0.0060848 s, 327 MB/s
sh-4.1$ ./unsquashfs filesystem.bin 

created 327 files
created 35 directories
created 59 symlinks
created 0 devices
created 0 fifos
sh-4.1$ ls -R squashfs-root/
squashfs-root/:
bin  dev  etc  lib  media  mnt	proc  sbin  sys  tmp  usr  var	www

squashfs-root/bin:
busybox  cp    gunzip  ls     mount  ps   rmdir   wps_ap
cat	 eapd  gzip    mkdir  msh    pwd  sh	  wps_monitor
chmod	 echo  kill    mknod  ping   rm   umount  zcat

squashfs-root/dev:

squashfs-root/etc:
icon.ico  large.ico    ld.so.conf  ppp		small.ico
iproute2  ld.so.cache  lld2d.conf  resolv.conf

squashfs-root/etc/iproute2:

squashfs-root/etc/ppp:

squashfs-root/lib:
ld-uClibc.so.0	libc.so.0   libgcc_s.so.1  libpthread.so.0  libutil.so.0
libcrypt.so.0	libdl.so.0  libm.so.0	   libresolv.so.0   modules

squashfs-root/lib/modules:
2.4.20

squashfs-root/lib/modules/2.4.20:
build  kernel  pcmcia

squashfs-root/lib/modules/2.4.20/kernel:
drivers  net

squashfs-root/lib/modules/2.4.20/kernel/drivers:
net

squashfs-root/lib/modules/2.4.20/kernel/drivers/net:
emf  et  igs  wl

squashfs-root/lib/modules/2.4.20/kernel/drivers/net/emf:
emf.o

squashfs-root/lib/modules/2.4.20/kernel/drivers/net/et:
et.o

squashfs-root/lib/modules/2.4.20/kernel/drivers/net/igs:
igs.o

squashfs-root/lib/modules/2.4.20/kernel/drivers/net/wl:
wl.o

squashfs-root/lib/modules/2.4.20/kernel/net:
ipv4

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4:
acos_nat  l7_filter  multissidcontrol  opendns	ubd

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4/acos_nat:
acos_nat.o

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4/l7_filter:
l7_filter.o

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4/multissidcontrol:
MultiSsidControl.o

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4/opendns:
openDNS_hijack.o

squashfs-root/lib/modules/2.4.20/kernel/net/ipv4/ubd:
ubd.o

squashfs-root/lib/modules/2.4.20/pcmcia:

squashfs-root/mnt:

squashfs-root/proc:

squashfs-root/sbin:
acos_init     burnrf	 ifconfig  ntpclient  reset_no_reboot	     version
acos_service  burnsn	 init	   pppd       restart_all_processes  write
bd	      erase	 insmod    preinit    rmmod
burnboardid   getchksum  leddown   rc	      routerinfo
burnethermac  gpio	 ledup	   read_bd    ubdcmd
burnpin       hotplug	 lsmod	   reboot     uptime

squashfs-root/sys:

squashfs-root/tmp:

squashfs-root/usr:
bin  lib  sbin	tmp

squashfs-root/usr/bin:
free  killall  route  telnetd  tftp  wget

squashfs-root/usr/lib:
libacos_shared.so  libbcm.so  libnvram.so   libwpscom.so
libbcmcrypto.so    libnat.so  libshared.so  tc

squashfs-root/usr/lib/tc:
q_netem.so

squashfs-root/usr/sbin:
acl_logd	   email      lld2d	   swresetd	  upnpd        wlconf
bpalogin	   emf	      nas	   tc		  upnpnat      wpsd
bpa_monitor	   epi_ttcp   nvram	   telnetenabled  vconfig      zebra
brctl		   et	      outputimage  tfmeter	  wan_debug
cli		   ftpc       pot	   timesync	  wandetect
ddnsd		   heartbeat  pppoecd	   udhcpc	  wanled
dnsmasq		   httpd      pptp	   udhcpd	  wl
dnsRedirectReplyd  igs	      ripd	   upnp		  wlanconfigd

squashfs-root/www:
Add_WPS_Client.htm		 PWD_password.htm
backpage2.htm			 QOS_check_uplink_band_width.htm
backpage.htm			 QOS_main_h.htm
BAK_backup_h.htm		 QOS_main.htm
BAK_backup.htm			 QOS_ruletab.htm
BAK_cfm.htm			 QOS_service.htm
BAS_basic.htm			 redbull.gif
BAS_basictop.htm		 router-info.htm
BAS_bpa_h.htm			 RST_interval.htm
BAS_bpa.htm			 RST_statistics.htm
BAS_ether_h.htm			 RST_stattbl.htm
BAS_ether.htm			 RST_status_h.htm
BAS_pppoe_basic.htm		 RST_status.htm
BAS_pppoe_basictop.htm		 RST_st_bpa.htm
BAS_pppoe_flet2.htm		 RST_st_dhcp.htm
BAS_pppoe_flet.htm		 RST_st_fix.htm
BAS_pppoe_h.htm			 RST_st_poe.htm
BAS_pppoe.htm			 RST_st_pptp.htm
BAS_pppoe_other.htm		 RST_wanstat.htm
BAS_pptp_h.htm			 settings_wnr1000v3.jpg
BAS_pptp.htm			 spacer.gif
BAS_wtest_d.htm			 SRV_response.htm
BAS_wtest_l.htm			 start.htm
BAS_wtest_ppp2.htm		 start_update.htm
BKS_err.htm			 STR_add.htm
BKS_keyword_h.htm		 StringTableUpload.html
BKS_keyword.htm			 string_table_wnr1000v3
BKS_keyword_ppp2.htm		 STR_routes_h.htm
BKS_service_add_h.htm		 STR_routes.htm
BKS_service_add.htm		 style.css
BKS_service_edit.htm		 traffic_important_update.htm
BKS_service_h.htm		 traffic_interval.htm
BKS_service.htm			 traffic_meter_h.htm
BKS_service_ppp2.htm		 traffic_meter.htm
browser.js			 traffic_start_update.htm
CheckNewFW.html			 traffic_stattbl.htm
currentsetting.htm		 traffic_status.htm
darkblue.gif			 traffic_warning.htm
debuginfo.htm			 UPG_fw_check.htm
DEV_device_h.htm		 UPG_upgrade_h.htm
DEV_device.htm			 UPG_upgrade.htm
DIG_reboot2.htm			 upload.gif
DIG_reboot3.htm			 UPNP_upnp_h.htm
DIG_reboot4.htm			 UPNP_upnp.htm
DIG_reboot.htm			 utility.js
DIG_update.htm			 VER_check_h.htm
DNS_ddns_h.htm			 VER_check.htm
DNS_ddns.htm			 VER_download_h.htm
DNS_ddns_st.htm			 VER_download.htm
form.css			 VER_fw_found.htm
func.js				 VER_fwlang_found.htm
FW_check.htm			 VER_fw_not_found.htm
FW_email_h.htm			 VER_result_h.htm
FW_email.htm			 VER_sel_h.htm
FW_forward_h.htm		 VER_sel.htm
FW_forward.htm			 VER_write2.htm
FW_forward_service_h.htm	 VER_write_h.htm
FW_forward_service.htm		 VER_write.htm
FW_log_h.htm			 WAN_wan_h.htm
FW_log.htm			 WAN_wan.htm
FW_pt_h.htm			 WiFi_HiddenPage.htm
FW_pt.htm			 WIZ_bpa_h.htm
FW_pt_service.htm		 WIZ_bpa.htm
FW_remote_h.htm			 WIZ_cfm_h.htm
FW_remote.htm			 WIZ_cfm.htm
FW_schedule_h.htm		 WIZ_det_fix_h.htm
FW_schedule.htm			 WIZ_det_fix.htm
FW_schedule_ppp2.htm		 WIZ_detwan.htm
help.css			 WIZ_dyn_h.htm
IA_IP_SUBNET.htm		 WIZ_dyn.htm
important_update.htm		 WIZ_fix_h.htm
index.htm			 WIZ_fix.htm
LANG_brs_conflict_h.htm		 WIZ_ph_fail_h.htm
LANG_brs_conflict.htm		 WIZ_ph_fail.htm
LANG_check_brslang.htm		 WIZ_pppoe_fleteast.htm
LANG_check.htm			 WIZ_pppoe_fletother.htm
LANG_check_top.htm		 WIZ_pppoe_fletwest.htm
LANG_download.htm		 WIZ_pppoe_h.htm
LANG_failed.htm			 WIZ_pppoe.htm
LANG_found.htm			 WIZ_pptp_h.htm
LANG_lang_h.htm			 WIZ_pptp.htm
LANG_lang.htm			 WIZ_result.htm
LANG_no_connection.htm		 WIZ_sel_h.htm
LANG_not_found.htm		 WIZ_sel.htm
LANG_upgrade.htm		 WLG_acl_add_h.htm
LANG_write.htm			 WLG_acl_add.htm
LAN_lan_h.htm			 WLG_acl_edit.htm
LAN_lan.htm			 WLG_acl_h.htm
LAN_reserv_add_h.htm		 WLG_acl.htm
LAN_reserv_add.htm		 WLG_adv_h.htm
LAN_reserv_edit_h.htm		 WLG_adv.htm
LAN_reserv_edit.htm		 WLG_wds_h.htm
LGO_logout.htm			 WLG_wds.htm
liteblue.gif			 WLG_wireless1_2.htm
md5.js				 WLG_wireless1.htm
menublue.gif			 WLG_wireless2_2.htm
mimo_logo_wnr1000v3.jpg		 WLG_wireless_2_h.htm
MNU_access_failure.htm		 WLG_wireless_2.htm
MNU_access_unauthorized.htm	 WLG_wireless2.htm
MNU_blank.htm			 WLG_wireless3_2.htm
MNU_login.htm			 WLG_wireless3.htm
MNU_menu.htm			 WLG_wireless4_2.htm
MNU_menu_no_link.htm		 WLG_wireless_h.htm
MNU_top.htm			 WLG_wireless.htm
msg.js				 WPS_Add_Client_FAIL_Cancel_Change.htm
NoInternetConn.html		 WPS_Add_Client_FAIL_Cancel.htm
NoInternet.html			 WPS_Add_Client_FAIL_ErrorPIN.htm
POT.htm				 WPS_Add_Client_FAIL_PBC_Conflict_Change.htm
pppoe2_domain_add.htm		 WPS_Add_Client_FAIL_PBC_Conflict.htm
pppoe2_domain_edit.htm		 WPS_Add_Client_FAIL_PIN_Change.htm
pppoe2_ip_add.htm		 WPS_Add_Client_FAIL_PIN.htm
pppoe2_ip_edit.htm		 WPS_Add_Client_FAIL_Timeout_Change.htm
pppoe2_port_add.htm		 WPS_Add_Client_FAIL_Timeout.htm
pppoe2_port_edit.htm		 WPS_Add_Client_OK_Change.htm
Public_UPNP_gatedesc.xml	 WPS_Add_Client_OK.htm
Public_UPNP_LANHostCfgMag.xml	 WPS_Add_Client_PBC.htm
Public_UPNP_Layer3F.xml		 WPS_Add_Client_PIN.htm
Public_UPNP_WAND.xml		 WPS_h.htm
Public_UPNP_WANEtherLinkCfg.xml  WPS.htm
Public_UPNP_WANIPConn.xml	 wps_icon_off.bmp
Public_UPNP_WANPPPConn.xml	 wps_icon_on.bmp
PWD_passwd_h.htm		 WPS_PIN.htm
sh-4.1$

In summary, the following code has been verified to unpack SquashFS filesystems on the following NETGEAR devices:

  • WNR1000v3 1.0.26NA
  • WGR614v10 1.0.26NA

The unsquashfs code may be downloaded here: unsquashfs-1.3.c

If there is one lesson to be learned from this experience, it’s amazing what you can receive if you are polite and simply choose to ask.

10 responses to “NETGEAR unsquashfs.c version 1.3”

  1. […] Extracting out the individual parts (like the router file system: Coppola has a good story about getting unsquash.fs out of Netgear) […]

  2. Thanks sir,

    this article helped me a lot!
    I tried to unsquash a version 2.0 FS which I copied from a Siemens S1621-z220-A (Alice Modem Wlan 1121). It always failed with a Zlib error -3 (corrupted data). I’ve tried unsquash >= 2.0 but all failed. The version you posted worked for me. I’ve had to add a break in the switch statement of the main function which they seemed to forgot but then it just worked fine.

    Thank you very much!

    1. Glad to hear it!

  3. Does this help us with putting DD-WRT on the WNR1000v3?

    1. I’m not a regular in the DD-WRT community, so I’m not sure what challenges are stopping progress on the WNR1000v3. Though, someone else did ask the exact same question:

      http://www.dd-wrt.com/phpBB2/viewtopic.php?t=65317&postdays=0&postorder=asc&start=30

  4. digitaladdictions Avatar
    digitaladdictions

    I had to set a couple of the variables used in the Makefile before I could build.

    export LINUXDIR=~/bcm5356/src/linux/linux/
    export SRCBASE=~/bcm5356/src/

    Just wanted to note it here in case it helps others. This assumes the bcm5356 directory is in your home folder. I would imagine these variables normally would be set by the ./configure step which we do not have here.

  5. digitaladdictions That’s true, this solved my problem while compiling. Thanks.

    Also I have a problem when I try to execute unsquashfs with my firmware.bin (Homestation ADB A4001N), the header is shsq, and the error output is:

    “Major/Minor mismatch, filesystem on data.squashfs is (4:0)
    I support Squashfs 2.x and 3.0 filesystems!”

    I also tried modifying the header and while file command understand it as squashfs I cannot decompress it neither with firmware-mod-kit nor unsquashfs from this post.

    Any suggestion? Regards.

    1. There are many un/squashfs tools out there, each targeting a different version or range of versions.
      You should try the other ones available in rpef: http://redmine.poppopret.org/projects/rpef/repository/show/utilities
      Additionally, firmware-mod-kit includes many of its own: https://code.google.com/p/firmware-mod-kit/

      1. Thank you mncoppola, I will give a try to your tool. Actually yesterday I saw your presentation at DefCon and wanted to try your tool.

  6. Today i tried to extract a DG834G img. After the squashfs was extracted with binwalk i tryed to unsquash it and I’ve found a little bug in this implementation! At line 1256 is missing a break!
    I’ve successfully managed to unsquashfs with squashfs-3.2-r2-wnr1000 found in firmware-mod-kit that has this exact file and works after this litthe mod!
    Just to let know to all the reader ;)