firmex/python/matcher/zip.py

45 lines
1.6 KiB
Python
Raw Normal View History

import io
from .matcher import SignatureMatcher, Match
class Zip(SignatureMatcher):
"""
Zip files are read from the bottom
The signature PK is the local file header
https://medium.com/@felixstridsberg/the-zip-file-format-6c8a160d1c34
"""
def __init__(self, file):
self.name = "Zip"
self.signature = b'PK\x03\x04'
super().__init__(file)
def is_valid(self):
for match in self.search():
start = match
header = io.BytesIO(self.file[start:start+4*4 + 2*7])
magic = header.read(4)
min_version = header.read(2)
bitflag = header.read(2)
compression_method = header.read(2)
last_modification_time = header.read(2)
last_modification_data = header.read(2)
crc = header.read(4)
compressed_size = header.read(4)
uncompressed_size = header.read(4)
file_name_length = header.read(2)
extra_field_length = header.read(2)
file_name_length = int.from_bytes(file_name_length, 'little')
extra_field_length = int.from_bytes(extra_field_length, 'little')
compressed_size = int.from_bytes(compressed_size, 'little')
header_size = 4*4 + 2*7
data = {
'name': self.file[start+header_size:start+header_size+file_name_length]
}
size = 4*4 + 2*7 + file_name_length + extra_field_length + compressed_size
self.matches += [Match(start, size, data)]
return len(self.matches) != 0