From 1716f2ffc82fa448f5102f77f0bed455a3fa3e0f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 17:59:19 -0500 Subject: [PATCH] Added logfs signature --- src/magic.rs | 11 +++++++++ src/signatures.rs | 1 + src/signatures/logfs.rs | 35 +++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/logfs.rs | 50 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/signatures/logfs.rs create mode 100644 src/structures/logfs.rs diff --git a/src/magic.rs b/src/magic.rs index 11a225f32..88819b7ac 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1031,6 +1031,17 @@ pub fn patterns() -> Vec { description: signatures::pkcs_der::DESCRIPTION.to_string(), extractor: None, }, + // LogFS + signatures::common::Signature { + name: "logfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::logfs::logfs_magic(), + parser: signatures::logfs::logfs_parser, + description: signatures::logfs::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 663c781ef..131518616 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -144,6 +144,7 @@ pub mod jboot; pub mod jffs2; pub mod jpeg; pub mod linux; +pub mod logfs; pub mod luks; pub mod lz4; pub mod lzfse; diff --git a/src/signatures/logfs.rs b/src/signatures/logfs.rs new file mode 100644 index 000000000..8e45f6e25 --- /dev/null +++ b/src/signatures/logfs.rs @@ -0,0 +1,35 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::logfs::{parse_logfs_super_block, LOGFS_MAGIC_OFFSET}; + +/// Human readable description +pub const DESCRIPTION: &str = "LogFS file system"; + +/// LogFS magic bytes +pub fn logfs_magic() -> Vec> { + vec![b"\x7A\x3A\x8E\x5C\xB9\xD5\xBF\x67".to_vec()] +} + +/// Validates the LogFS super block +pub fn logfs_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if offset >= LOGFS_MAGIC_OFFSET { + result.offset = offset - LOGFS_MAGIC_OFFSET; + + if let Some(logfs_sb_data) = file_data.get(result.offset..) { + if let Ok(logfs_super_block) = parse_logfs_super_block(logfs_sb_data) { + result.size = logfs_super_block.total_size; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index d75074c05..bfc00aaa7 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -123,6 +123,7 @@ pub mod iso9660; pub mod jboot; pub mod jffs2; pub mod linux; +pub mod logfs; pub mod luks; pub mod lz4; pub mod lzfse; diff --git a/src/structures/logfs.rs b/src/structures/logfs.rs new file mode 100644 index 000000000..84545c933 --- /dev/null +++ b/src/structures/logfs.rs @@ -0,0 +1,50 @@ +use crate::structures::common::{self, StructureError}; + +/// Offset of the LogFS magic bytes from the start of the file system +pub const LOGFS_MAGIC_OFFSET: usize = 0x18; + +/// Struct to store LogFS info +#[derive(Debug, Default, Clone)] +pub struct LogFSSuperBlock { + pub total_size: usize, +} + +/// Parses a LogFS superblock +pub fn parse_logfs_super_block(logfs_data: &[u8]) -> Result { + //const LOGFS_CRC_START: usize = LOGFS_MAGIC_OFFSET + 12; + //const LOGFS_CRC_END: usize = 256; + + let logfs_sb_structure = vec![ + ("magic", "u64"), + ("crc32", "u32"), + ("ifile_levels", "u8"), + ("iblock_levels", "u8"), + ("data_levels", "u8"), + ("segment_shift", "u8"), + ("block_shift", "u8"), + ("write_shift", "u8"), + ("pad0", "u32"), + ("pad1", "u16"), + ("filesystem_size", "u64"), + ("segment_size", "u32"), + ("bad_seg_reserved", "u32"), + ("feature_incompat", "u64"), + ("feature_ro_compat", "u64"), + ("feature_compat", "u64"), + ("feature_flags", "u64"), + ("root_reserve", "u64"), + ("speed_reserve", "u64"), + ]; + + if let Some(sb_struct_data) = logfs_data.get(LOGFS_MAGIC_OFFSET..) { + if let Ok(super_block) = common::parse(sb_struct_data, &logfs_sb_structure, "big") { + if super_block["pad0"] == 0 && super_block["pad1"] == 0 { + return Ok(LogFSSuperBlock { + total_size: super_block["filesystem_size"], + }); + } + } + } + + Err(StructureError) +}