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:
- Download and extract http://www.downloads.netgear.com/files/GPL/WNR1000v3-V1.0.2.26_51.0.59NAWW_src.tar.zip
- Copy unsquashfs.c into bcm5356/src/router/squashfs
- `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.