From 1b1b28471e9546cbe263c4b3c568529499db2eb9 Mon Sep 17 00:00:00 2001 From: Marten Ringwelski Date: Thu, 6 Apr 2023 12:42:47 +0200 Subject: [PATCH] plugins/device_tree: Use `AnalysisPluginV0` Version bumped because unknown-model is now also part of the summary. --- .../architecture_detection/internal/dt.py | 6 +- .../analysis/device_tree/code/device_tree.py | 89 ++++++++++++------- .../device_tree/test/test_device_tree.py | 19 ++-- .../device_tree/view/device_tree.html | 15 +--- 4 files changed, 72 insertions(+), 57 deletions(-) diff --git a/src/plugins/analysis/architecture_detection/internal/dt.py b/src/plugins/analysis/architecture_detection/internal/dt.py index b234ad8252..81de3e698b 100644 --- a/src/plugins/analysis/architecture_detection/internal/dt.py +++ b/src/plugins/analysis/architecture_detection/internal/dt.py @@ -72,8 +72,12 @@ def _get_compatible_entry(dts: str) -> str | None: def construct_result(file_object): + device_tree_result = file_object.processed_analysis['device_tree'].get('result', {}) + if not device_tree_result: + return {} + result = {} - for dt_dict in file_object.processed_analysis['device_tree'].get('result', {}).get('device_trees', []): + for dt_dict in device_tree_result.get('device_trees', []): dt = dt_dict['device_tree'] compatible_entry = _get_compatible_entry(dt) diff --git a/src/plugins/analysis/device_tree/code/device_tree.py b/src/plugins/analysis/device_tree/code/device_tree.py index dc6bf47efd..937c44f573 100644 --- a/src/plugins/analysis/device_tree/code/device_tree.py +++ b/src/plugins/analysis/device_tree/code/device_tree.py @@ -1,38 +1,65 @@ -from analysis.PluginBase import AnalysisBasePlugin +import io + +import pydantic + from helperFunctions.tag import TagColor -from objects.file import FileObject from plugins.mime_blacklists import MIME_BLACKLIST_COMPRESSED +from analysis.plugin.compat import AnalysisBasePluginAdapterMixin +from analysis.plugin import AnalysisPluginV0, Tag +from typing import Optional, List, Dict from ..internal.device_tree_utils import dump_device_trees -class AnalysisPlugin(AnalysisBasePlugin): - """ - Device Tree Plug-in - """ - - NAME = 'device_tree' - DESCRIPTION = 'get the device tree in text from the device tree blob' - VERSION = '1.0.1' - MIME_BLACKLIST = [*MIME_BLACKLIST_COMPRESSED, 'audio', 'image', 'video'] # noqa: RUF012 - FILE = __file__ - - def process_object(self, file_object: FileObject): - file_object.processed_analysis[self.NAME] = {'summary': []} - - device_trees = dump_device_trees(file_object.binary) - if device_trees: - file_object.processed_analysis[self.NAME]['device_trees'] = device_trees - for result in device_trees: - model = result.get('model') - if model: - file_object.processed_analysis[self.NAME]['summary'].append(model) - self.add_analysis_tag( - file_object=file_object, - tag_name=self.NAME, - value=self.NAME.replace('_', ' '), - color=TagColor.ORANGE, - propagate=False, - ) +class AnalysisPlugin(AnalysisPluginV0, AnalysisBasePluginAdapterMixin): + class Schema(pydantic.BaseModel): + class DeviceTree(pydantic.BaseModel): + header: Optional[dict] + device_tree: Optional[str] + model: Optional[str] + description: Optional[str] + offset: int + + device_trees: List[DeviceTree] + + def __init__(self): + metadata = AnalysisPluginV0.MetaData( + name='device_tree', + description='get the device tree in text from the device tree blob', + version='1.1.0', + system_version=None, + mime_blacklist=[*MIME_BLACKLIST_COMPRESSED, 'audio', 'image', 'video'], + timeout=10, + Schema=AnalysisPlugin.Schema, + ) + super().__init__(metadata=metadata) - return file_object + def summarize(self, result: Schema) -> list[str]: + models = [device_tree.model for device_tree in result.device_trees if device_tree.model] + + if not models: + return ['unknown-model'] + + return models + + def analyze( + self, + file_handle: io.FileIO, + virtual_file_path: dict, + analyses: Dict[str, dict], + ) -> Optional[Schema]: + del virtual_file_path, analyses + device_trees = dump_device_trees(file_handle.readall()) + if len(device_trees) == 0: + return None + return AnalysisPlugin.Schema(device_trees=device_trees) + + def get_tags(self, result: Schema, summary: list[str]) -> list[Tag]: + del result, summary + return [ + Tag( + name=self.metadata.name, + value='device tree', + color=TagColor.ORANGE, + ), + ] diff --git a/src/plugins/analysis/device_tree/test/test_device_tree.py b/src/plugins/analysis/device_tree/test/test_device_tree.py index 6121ba4fb8..c5a594fece 100644 --- a/src/plugins/analysis/device_tree/test/test_device_tree.py +++ b/src/plugins/analysis/device_tree/test/test_device_tree.py @@ -1,8 +1,8 @@ +import io from pathlib import Path import pytest -from objects.file import FileObject from ..code.device_tree import AnalysisPlugin from ..internal.device_tree_utils import dump_device_trees @@ -16,16 +16,13 @@ @pytest.mark.AnalysisPluginTestConfig(plugin_class=AnalysisPlugin) -def test_process_object(analysis_plugin): - test_object = FileObject() - test_object.binary = TEST_FILE.read_bytes() - test_object.file_path = str(TEST_FILE) - processed_object = analysis_plugin.process_object(test_object) - result = processed_object.processed_analysis[analysis_plugin.NAME] - - assert len(result['device_trees']) == 1 - assert result['device_trees'][0]['model'] == 'Manufac XYZ1234ABC' - assert result['summary'] == ['Manufac XYZ1234ABC'] +def test_analyze(analysis_plugin): + result = analysis_plugin.analyze(io.FileIO(TEST_FILE), {}, {}) + summary = analysis_plugin.summarize(result) + + assert len(result.device_trees) == 1 + assert result.device_trees[0].model == 'Manufac XYZ1234ABC' + assert summary == ['Manufac XYZ1234ABC'] @pytest.mark.parametrize('file', [TEST_EMBEDDED, TEST_IMAGE]) diff --git a/src/plugins/analysis/device_tree/view/device_tree.html b/src/plugins/analysis/device_tree/view/device_tree.html index 34b8bab4e0..5f4759f7e6 100644 --- a/src/plugins/analysis/device_tree/view/device_tree.html +++ b/src/plugins/analysis/device_tree/view/device_tree.html @@ -40,20 +40,7 @@ {% block analysis_result_details %} - -{# Don't break on legacy result #} -{% if "device_tree" in analysis_result %} - - Deprecation Warning - Analysis version is deprecated, please update the analysis - - - Device Tree - {{ device_tree_table_cell(analysis_result.device_tree, "1") }} - -{% endif %} - -{% for dt_dict in analysis_result.get("device_trees", []) %} +{% for dt_dict in analysis_result["device_trees"] %}