objects.file module

class objects.file.FileObject(*, uid, sha256, size, file_name, files_included=<factory>, list_of_all_included_files=None, parents=<factory>, root_uid=None, depth=0, scheduled_analysis=<factory>, comments=<factory>, parent_firmware_uids=<factory>, temporary_data=<factory>, analysis_tags=<factory>, processed_analysis=<factory>, analysis_exception=None, callback=None, virtual_file_path=<factory>)

Bases: object

FileObject is the primary data structure in FACT. It holds all meta information of a file along with analysis results and some internal values for scheduling.

Parameters:
  • uid (str) –

  • sha256 (str) –

  • size (int) –

  • file_name (str) –

  • files_included (set[str]) –

  • list_of_all_included_files (set[str] | None) –

  • parents (set[str]) –

  • root_uid (str | None) –

  • depth (int) –

  • scheduled_analysis (list[str]) –

  • comments (list[dict]) –

  • parent_firmware_uids (set[str]) –

  • temporary_data (dict[str, Any]) –

  • analysis_tags (dict[str, list[dict]]) –

  • processed_analysis (dict) –

  • analysis_exception (tuple[str, str] | None) –

  • callback (Callable | None) –

  • virtual_file_path (dict[str, list[str]]) –

add_included_file(file_object)

This functions adds a file to this object’s list of included files. The function also takes care of a number of fields for the child object:

  • parents: Adds the uid of this file to the parent’s field of the child.

  • root_uid: Sets the root uid of the child as this files uid.

  • depth: The child inherits the unpacking depth from this file, incremented by one.

  • scheduled_analysis: The child inherits this file’s scheduled analysis.

  • virtual_file_path: Sets a new virtual_file_path for the child, being <this_files_current_vfp|child_path>.

Parameters:

file_object (FileObject) – File that was extracted from the current file

Return type:

None

analysis_exception: tuple[str, str] | None = None

If an exception occurred during analysis, this fields stores a tuple (<plugin name>, <error message>) for debugging purposes and as placeholder in UI.

analysis_tags: dict[str, list[dict]]

Analysis tags for this file. An analysis tag has the structure {tag_name: {'value': value, 'color': color, 'propagate': propagate,}, 'root_uid': root uid} while the first layer of this dict is a key for each plugin. So in total you have a dict {plugin: [tags, of, plugin], ..}. Only set when retrieving the object from the DB. During analysis, tags are part of processed_analysis.

callback: Callable | None = None

Optional callback method called after the analysis finished in the analysis scheduler

comments: list[dict]

List of comments that have been made on this file. Comments are dicts with the keys time (float), author (str) and comment (str). They are not created during unpacking or analysis, so are only available when loading the object from the DB.

depth: int = 0

Extraction depth of this object. If outer firmware file, this is 0. Every extraction increments this by one. For a file inside a squashfs, that is contained inside a tar archive this would be 1 (tar) + 1 (fs) = 2.

file_name: str

The file’s name.

property file_path: Path

The file’s path in the file system of the backend (not in the firmware!).

files_included: set[str]

The set of files included in (i.e. extracted from) this file. This is usually true for archives. Only lists the next layer, not recursively included files on lower extraction layers. Is set during extraction and when loading from the DB. Analogous to FileObject.parents.

classmethod from_file(file_contents, file_name, scheduled_analysis=None, root_uid=None)
Parameters:
  • file_contents (bytes) –

  • file_name (str) –

  • scheduled_analysis (list[str] | None) –

  • root_uid (str | None) –

Return type:

Self

classmethod from_json(json_dict, root_uid=None)
Parameters:
  • json_dict (dict) –

  • root_uid (str | None) –

Return type:

Self

classmethod from_path(file_path)

Only for use in tests!

Parameters:

file_path (Path) –

Return type:

Self

classmethod from_uid(uid, file_name, scheduled_analysis=None, root_uid=None)
Parameters:
  • uid (str) –

  • file_name (str) –

  • scheduled_analysis (list[str] | None) –

  • root_uid (str | None) –

Return type:

Self

get_hid()

Get a human-readable identifier for the given file. This usually is the file name for extracted files. :return: String representing a human-readable identifier for this file.

Return type:

str

get_virtual_paths_for_all_uids()

Get all virtual file paths (VFPs) of the file in all firmware containers.

Returns:

List of virtual paths.

Return type:

list[str]

list_of_all_included_files: set[str] | None = None

The list of all recursively included files in this file. That means files are included that are themselves included in files contained in this file, and so on. This value is not set by default as it’s expensive to aggregate and takes up a lot of memory.

parent_firmware_uids: set[str]

Set of parent firmware uids. UIDs from the root objects, this file belongs to (usually not its direct predecessor). One file can belong to multiple root objects if it was recursively extracted from them. Usually set during unpacking and when the object is loaded from the DB.

parents: set[str]

List of parent uids. Usually set during extraction. A parent in this context is a file from which this file was unpacked from. One file can have multiple parents (i.e. the same file was extracted from multiple files). Analogous to FileObject.files_included.

processed_analysis: dict

Analysis results for this file.

Structure of results: The first level of this dict is a pair of 'plugin_name': <result_dict> pairs. The contents are set during analysis in the backend and when loading the object from the DB. The result dict can have any content, but always has at least the fields:

  • analysis_date - float representing the time of analysis in unix time.

  • plugin_version - str defining the version of each plugin at time of analysis.

  • summary - list holding a summary of each file’s result, that can be aggregated.

root_uid: str | None = None

UID of the root object (in the tree of recursive extraction) for the given file (i.e. the firmware image). Useful to associate results of children with firmware. Is only set during unpacking / analysis in the backend and not if you load the object from the DB!

scheduled_analysis: list[str]

A list of analysis plugins that should be run on this file. Usually set during upload and propagated during unpacking to extracted files.

sha256: str

SHA256 hash of this file’s contents.

size: int

Size of this file in bytes.

temporary_data: dict[str, Any]

This field can be used for arbitrary temporary storage. It will not be persisted to the database, so it dies after the analysis cycle.

to_json(vfp_parent_filter=None)

Get a FileObject as JSON. vfp_parent_filter can be used to filter the entries with a UID whitelist.

Parameters:

vfp_parent_filter (set[str] | None) –

Return type:

dict

uid: str

Unique identifier of this file. Consisting of the file’s sha256 hash, and it’s size in the form hash_size.

virtual_file_path: dict[str, list[str]]

The virtual file path (VFP) is not a path on the analysis machine, but rather the file path in the file (container, file system, etc.) it was unpacked from during recursive extraction of a firmware image. The keys are parent UIDs (see FileObject.parents) and the values are lists of file paths as strings. The reason that the paths are represented by a list is that the same file may be extracted from the same parent multiple times.