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