Skip to content

Commit

Permalink
added bneg unpacker
Browse files Browse the repository at this point in the history
  • Loading branch information
jstucke committed Nov 15, 2024
1 parent f01521c commit 15d8347
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 0 deletions.
Empty file.
Empty file.
44 changes: 44 additions & 0 deletions fact_extractor/plugins/unpacking/bneg/code/bneg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
import struct
from pathlib import Path

NAME = 'Instar BNEG'
MIME_PATTERNS = ['firmware/bneg']
VERSION = '0.1.0'
HEADER_SIZE = 20


class BnegHeader:
def __init__(self, data: bytes):
(
self.magic,
self.major_version,
self.minor_version,
*self.partitions,
) = struct.unpack('<4sIIII', data)

def to_dict(self):
return self.__dict__


def unpack_function(file_path: str, tmp_dir: str) -> dict:
input_file = Path(file_path)
output_dir = Path(tmp_dir)
with input_file.open('rb') as fp:
header = BnegHeader(fp.read(HEADER_SIZE))
output = [f'Found BNEG v{header.major_version}.{header.minor_version}']
offset = HEADER_SIZE
for idx, partition in enumerate(header.partitions, start=1):
if partition:
with (output_dir / f'partition_{idx}.bin').open('wb') as fp_out:
os.sendfile(fp_out.fileno(), fp.fileno(), offset, partition)
output.append(f'Unpacked partition {idx} at offset {offset} to partition_{idx}.bin (size {partition})')
offset += partition

return {'output': '\n'.join(output)}


# ----> Do not edit below this line <----
def setup(unpack_tool):
for item in MIME_PATTERNS:
unpack_tool.register_plugin(item, (unpack_function, NAME, VERSION))
Empty file.
Binary file not shown.
27 changes: 27 additions & 0 deletions fact_extractor/plugins/unpacking/bneg/test/test_bneg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path

from test.unit.unpacker.test_unpacker import TestUnpackerBase

TEST_DATA_DIR = Path(__file__).parent / 'data'


class TestInstarBnegUnpacker(TestUnpackerBase):

def test_unpacker_selection_generic(self):
self.check_unpacker_selection('firmware/bneg', 'Instar BNEG')

def test_extraction_bneg(self):
in_file = TEST_DATA_DIR / 'test.bneg'
assert in_file.is_file(), 'test file is missing'
files, meta = self.unpacker.extract_files_from_file(str(in_file), self.tmp_dir.name)
assert len(files) == 2 # noqa: PLR2004
assert 'output' in meta
assert 'size 7' in meta['output']
assert 'size 8' in meta['output']

file1 = Path(self.tmp_dir.name) / 'partition_1.bin'
assert file1.is_file()
assert file1.read_bytes() == b'foobar\n'
file2 = Path(self.tmp_dir.name) / 'partition_2.bin'
assert file2.is_file()
assert file2.read_bytes() == b'test123\n'

0 comments on commit 15d8347

Please sign in to comment.