Skip to content

Commit

Permalink
Merge pull request #780 from ReFirmLabs/linux_arm_zimage
Browse files Browse the repository at this point in the history
Added Linux ARM zImage signature
  • Loading branch information
devttys0 authored Nov 29, 2024
2 parents 95cd870 + 298d802 commit e99250e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/magic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,17 @@ pub fn patterns() -> Vec<signatures::common::Signature> {
description: signatures::linux::LINUX_BOOT_IMAGE_DESCRIPTION.to_string(),
extractor: None,
},
// linux arm zimage
signatures::common::Signature {
name: "linux_arm_zimage".to_string(),
short: false,
magic_offset: 0,
always_display: false,
magic: signatures::linux::linux_arm_zimage_magic(),
parser: signatures::linux::linux_arm_zimage_parser,
description: signatures::linux::LINUX_ARM_ZIMAGE_DESCRIPTION.to_string(),
extractor: None,
},
// zstd
signatures::common::Signature {
name: "zstd".to_string(),
Expand Down
40 changes: 39 additions & 1 deletion src/signatures/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use crate::common::get_cstring;
use crate::signatures::common::{
SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM,
};
use crate::structures::linux::parse_linux_arm64_boot_image_header;
use crate::structures::linux::{
parse_linux_arm64_boot_image_header, parse_linux_arm_zimage_header,
};
use aho_corasick::AhoCorasick;

/// Human readable descriptions
pub const LINUX_ARM_ZIMAGE_DESCRIPTION: &str = "Linux ARM boot executable zImage";
pub const LINUX_BOOT_IMAGE_DESCRIPTION: &str = "Linux kernel boot image";
pub const LINUX_KERNEL_VERSION_DESCRIPTION: &str = "Linux kernel version";
pub const LINUX_ARM64_BOOT_IMAGE_DESCRIPTION: &str = "Linux kernel ARM64 boot image";
Expand All @@ -25,6 +28,41 @@ pub fn linux_arm64_boot_image_magic() -> Vec<Vec<u8>> {
vec![b"\x00\x00\x00\x00\x00\x00\x00\x00ARMd".to_vec()]
}

/// Magic bytes for Linux ARM zImage
pub fn linux_arm_zimage_magic() -> Vec<Vec<u8>> {
vec![b"\x18\x28\x6F\x01".to_vec(), b"\x01\x6F\x28\x18".to_vec()]
}

/// Validate a Linux ARM zImage
pub fn linux_arm_zimage_parser(
file_data: &[u8],
offset: usize,
) -> Result<SignatureResult, SignatureError> {
const MAGIC_OFFSET: usize = 36;

let mut result = SignatureResult {
confidence: CONFIDENCE_MEDIUM,
description: LINUX_ARM_ZIMAGE_DESCRIPTION.to_string(),
..Default::default()
};

if offset >= MAGIC_OFFSET {
result.offset = offset - MAGIC_OFFSET;

if let Some(zimage_data) = file_data.get(result.offset..) {
if let Ok(zimage_header) = parse_linux_arm_zimage_header(zimage_data) {
result.description = format!(
"{}, {} endian",
result.description, zimage_header.endianness
);
return Ok(result);
}
}
}

Err(SignatureError)
}

/// Validate a linux ARM64 boot image signature
pub fn linux_arm64_boot_image_parser(
file_data: &[u8],
Expand Down
50 changes: 50 additions & 0 deletions src/structures/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,56 @@ pub struct LinuxARM64BootHeader {
pub endianness: String,
}

/// Struct to store Linux ARM zImage info
#[derive(Debug, Default, Clone)]
pub struct LinuxARMzImageHeader {
pub endianness: String,
}

/// Parses a Linux ARM zImage header
pub fn parse_linux_arm_zimage_header(
zimage_data: &[u8],
) -> Result<LinuxARMzImageHeader, StructureError> {
const NOP_LE: usize = 0xE1A00000;
const NOP_BE: usize = 0x0000A0E1;

let zimage_structure = vec![
("nop1", "u32"),
("nop2", "u32"),
("nop3", "u32"),
("nop4", "u32"),
("nop5", "u32"),
("nop6", "u32"),
("nop7", "u32"),
("nop8", "u32"),
];

if let Ok(zimage_nops) = common::parse(zimage_data, &zimage_structure, "little") {
if zimage_nops["nop1"] == zimage_nops["nop2"]
&& zimage_nops["nop1"] == zimage_nops["nop3"]
&& zimage_nops["nop1"] == zimage_nops["nop4"]
&& zimage_nops["nop1"] == zimage_nops["nop5"]
&& zimage_nops["nop1"] == zimage_nops["nop6"]
&& zimage_nops["nop1"] == zimage_nops["nop7"]
&& zimage_nops["nop1"] == zimage_nops["nop8"]
{
if zimage_nops["nop1"] == NOP_LE {
return Ok(LinuxARMzImageHeader {
endianness: "little".to_string(),
});
}

if zimage_nops["nop1"] == NOP_BE {
return Ok(LinuxARMzImageHeader {
endianness: "big".to_string(),
});
}
}
}

Err(StructureError)
}

/// Parses a linux ARM64 boot header
pub fn parse_linux_arm64_boot_image_header(
img_data: &[u8],
Expand Down

0 comments on commit e99250e

Please sign in to comment.