diff --git a/INSTALL.md b/INSTALL.md old mode 100644 new mode 100755 index 4bfbf09..3d60906 --- a/INSTALL.md +++ b/INSTALL.md @@ -81,6 +81,13 @@ $ (cd jefferson && sudo python setup.py install) ``` ```bash +# Install ubi_reader to extract UBIFS file systems +$ sudo apt-get install liblzo2-dev python-lzo +$ git clone https://github.com/jrspruitt/ubi_reader +$ (cd ubi_reader && sudo python setup.py install) +``` + +```bash # Install unstuff (closed source) to extract StuffIt archive files $ wget -O - http://my.smithmicro.com/downloads/files/stuffit520.611linux-i386.tar.gz | tar -zxv $ sudo cp bin/unstuff /usr/local/bin/ diff --git a/src/binwalk/config/extract.conf b/src/binwalk/config/extract.conf old mode 100644 new mode 100755 index 656a33c..9f9ccaa --- a/src/binwalk/config/extract.conf +++ b/src/binwalk/config/extract.conf @@ -60,12 +60,14 @@ # Use sviehb's jefferson.py tool for JFFS2 extraction ^jffs2 filesystem:jffs2:jefferson -d '%%jffs2-root%%' '%e':0:False +# Use ubi_reader tool for UBIFS extraction +^ubi erase count header:ubi:ubireader_extract_files -o '%%ubifs-root%%' '%e':0:False + # These were extractors used from FMK that still need suitable replacements. #^bff volume entry:bff:/opt/firmware-mod-kit/src/bff/bffxtractor.py '%e' #^wdk file system:wdk:/opt/firmware-mod-kit/src/firmware-tools/unwdk.py '%e' # Extract, but don't run anything -^ubifs filesystem:ubi ^elf,:elf private key:key certificate:crt diff --git a/src/binwalk/magic/filesystems b/src/binwalk/magic/filesystems old mode 100644 new mode 100755 index 70519ca..8a55453 --- a/src/binwalk/magic/filesystems +++ b/src/binwalk/magic/filesystems @@ -116,12 +116,14 @@ >28 string !\x00*12 {invalid} # http://lxr.free-electrons.com/source/fs/ubifs/ubifs-media.h -#0 string UBI\x23 UBI erase count header, -#>4 ubyte x version: %d, -#>5 string !\x00*3 {invalid} -#>8 ubequad x EC: 0x%lX, -#>16 ubelong x VID header offset: 0x%X, -#>20 ubelong x data offset: 0x%X +0 string UBI\x23 UBI erase count header, +>4 ubyte x version: %d, +>5 string !\x00*3 {invalid} +>8 ubequad x EC: 0x%lX, +>16 ubelong x VID header offset: 0x%X, +>20 ubelong x data offset: 0x%X +# dummy jump - actual jump value is determined in UBIValidPlugin +>20 ubyte x {jump:0} # http://lxr.free-electrons.com/source/fs/ubifs/ubifs-media.h 0 lelong 0x06101831 UBIFS diff --git a/src/binwalk/plugins/ubivalid.py b/src/binwalk/plugins/ubivalid.py new file mode 100755 index 0000000..98b5493 --- /dev/null +++ b/src/binwalk/plugins/ubivalid.py @@ -0,0 +1,67 @@ +import struct +import binascii +import binwalk.core.plugin + + +class UBIValidPlugin(binwalk.core.plugin.Plugin): + ''' + Helps validate UBI erase count signature results. + + Checks header CRC and calculates jump value + ''' + MODULES = ['Signature'] + current_file=None + last_ec_hdr_offset = None + peb_size = None + + def _check_crc(self, ec_header): + # Get the header's reported CRC value + header_crc = struct.unpack(">I", ec_header[60:64])[0] + + # Calculate the actual CRC + calculated_header_crc = ~binascii.crc32(ec_header[0:60]) & 0xffffffff + + # Make sure they match + return header_crc == calculated_header_crc + + def _process_result(self, result): + if self.current_file == result.file.name: + result.display=False + else: + # Reset everything in case new file is encountered + self.peb_size=None + self.last_ec_hdr_offset=None + self.peb_size=None + + # Display result and trigger extraction + result.display=True + + self.current_file = result.file.name + + if not self.peb_size and self.last_ec_hdr_offset: + # Calculate PEB size by subtracting last EC block offset + self.peb_size = result.offset - self.last_ec_hdr_offset + else: + # First time plugin is called on file, save EC block offset + self.last_ec_hdr_offset = result.offset + + if self.peb_size: + # If PEB size has been determined jump PEB size + result.jump = self.peb_size + else: + result.jump = 0 + + def scan(self, result): + if result.file and result.description.lower().startswith('ubi erase count header'): + # Seek to and read the suspected UBI erase count header + fd = self.module.config.open_file(result.file.name, offset=result.offset) + + ec_header = fd.read(1024) + fd.close() + + result.valid = self._check_crc(ec_header[0:64]) + if result.valid: + self._process_result(result) + + print result.jump + print result.valid