Commit 787f0d6d by devttys0

Added tar plugin for better handling of tar files

parent 32289e35
import time
import math
import binwalk.core.plugin
class Plugin(binwalk.core.plugin.Plugin):
MODULES = ['Signature']
# "borrowed from pythons tarfile module"
TAR_BLOCKSIZE = 512
def nts(self, s):
"""
Convert a null-terminated string field to a python string.
"""
# Use the string up to the first null char.
p = s.find("\0")
if p == -1:
return s
return s[:p]
def nti(self, s):
"""
Convert a number field to a python number.
"""
# There are two possible encodings for a number field, see
# itn() below.
if s[0] != chr(0200):
try:
n = int(self.nts(s) or "0", 8)
except ValueError:
raise ValueError("invalid tar header")
else:
n = 0L
for i in xrange(len(s) - 1):
n <<= 8
n += ord(s[i + 1])
return n
def scan(self, result):
if result.description.lower().startswith('posix tar archive'):
is_tar = True
file_offset = result.offset
fd = self.module.config.open_file(result.file.name, offset=result.offset)
while is_tar:
# read in the tar header struct
buf = fd.read(self.TAR_BLOCKSIZE)
# check to see if we are still in a tarball
if buf[257:262] == 'ustar':
# get size of tarred file convert to blocks (plus 1 to include header)
try:
size = self.nti(buf[124:136])
blocks = math.ceil(size/float(self.TAR_BLOCKSIZE)) + 1
except ValueError as e:
is_tar = False
break
# update file offset for next file in tarball
file_offset += int(self.TAR_BLOCKSIZE*blocks)
if file_offset >= result.file.size:
# we hit the end of the file
is_tar = False
else:
fd.seek(file_offset)
else:
is_tar = False
result.jump = file_offset
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment