firmex/python/matcher/zip.py

47 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)
as_num = lambda x: int.from_bytes(x, 'little')
file_name_length = as_num(file_name_length)
extra_field_length = as_num(extra_field_length)
compressed_size = as_num(compressed_size)
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