Skip to content

Commit

Permalink
feat: parsing code signature data + more load commands for mach-o (#78)
Browse files Browse the repository at this point in the history
* feat: implement code_signature_data parsing for mach-o

* feat: implement entitlement parsing for Mach-O from code_signature_data

* clippy fixes

* update tests for new tests

* feat: implement signing certificate parsing for mach-o

* feat: implement dyld_info load command parsing for mach-o

* feat: implement lc_symtab parsing for mach-o

* feat: implement lc_symtab table entries parsing for mach-o

* feat: implement LC_UUID parsing for mach-o

* feat: implement LC_BUILD_VERSION parsing for mach-o

* feat: implement LC_VERSION_MIN_* load command parsing for Mach-O

* feat: implement entitlement_present function for Mach-O

* fix: mach-o deps and comments

* fix: use device_type enum
  • Loading branch information
latonis authored Feb 23, 2024
1 parent ae55e89 commit 8550f8c
Show file tree
Hide file tree
Showing 23 changed files with 2,931 additions and 50 deletions.
654 changes: 654 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ chrono = "0.4.34"
clap = "4.4.8"
crc32fast = "1.3.2"
criterion = "0.5.1"
cryptographic-message-syntax = "0.26.0"
enable-ansi-support = "0.2.1"
env_logger = "0.11.1"
fmmap = "0.3.2"
Expand Down Expand Up @@ -76,6 +77,7 @@ protobuf-json-mapping = { git = "https://github.com/plusvic/rust-protobuf.git",
protobuf-parse = { git = "https://github.com/plusvic/rust-protobuf.git", rev="b484d8a7" }
regex-syntax = { git = "https://github.com/plusvic/regex.git", rev="423493d" }
regex-automata = { git = "https://github.com/plusvic/regex.git", rev="423493d" }
roxmltree = "0.19.0"
rustc-hash = "1.1.0"
smallvec = "1.10.0"
serde = "1.0"
Expand Down
8 changes: 6 additions & 2 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ lnk-module = [
# The `macho` module parses Mach-O files.
macho-module = [
"dep:nom",
"dep:cryptographic-message-syntax",
"dep:roxmltree",
]

# The `math` module.
Expand Down Expand Up @@ -155,6 +157,7 @@ bitmask = { workspace = true }
bitvec = { workspace = true }
bstr = { workspace = true, features = ["serde"] }
crc32fast = { workspace = true, optional = true }
cryptographic-message-syntax = { workspace = true, optional = true }
fmmap = { workspace = true }
indexmap = { workspace = true, features = ["serde"] }
intaglio = { workspace = true }
Expand All @@ -174,8 +177,9 @@ protobuf = { workspace = true }
rustc-hash = { workspace = true }
regex-syntax = { workspace = true }
regex-automata = { workspace = true }
smallvec = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["rc"] }
roxmltree = { workspace = true, optional = true }
smallvec = { workspace = true, features=["serde"] }
serde = { workspace = true, features=["rc"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
tlsh-fixed = { workspace = true, optional = true }
Expand Down
50 changes: 31 additions & 19 deletions lib/src/modules/macho/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,37 @@ fn ep_for_arch_subtype(
None
}

/// The function for checking if any dylib name present in the main Mach-O or
/// embedded Mach-O files contain a dylib with the desired name
/// Returns true if the Mach-O parsed entitlements contain `entitlement`
///
/// # Arguments
///
/// * `ctx`: A mutable reference to the scanning context.
/// * `dylib_name`: The name of the dylib to check if present
///
/// # Returns
/// `entitlement` is case-insensitive.
#[module_export(name = "entitlement_present")]
fn entitlements_present(
ctx: &ScanContext,
entitlement: RuntimeString,
) -> Option<bool> {
let macho = ctx.module_output::<Macho>()?;
let expected = entitlement.as_bstr(ctx);

for entitlement in macho.entitlements.iter() {
if expected.eq_ignore_ascii_case(entitlement.as_bytes()) {
return Some(true);
}
}

for file in macho.file.iter() {
for entitlement in file.entitlements.iter() {
if expected.eq_ignore_ascii_case(entitlement.as_bytes()) {
return Some(true);
}
}
}

Some(false)
}

/// Returns true if the Mach-O parsed dylibs contain `dylib_name`
///
/// An `Option<bool>` containing if the name is found
/// `dylib_name` is case-insensitive.
#[module_export(name = "dylib_present")]
fn dylibs_present(
ctx: &ScanContext,
Expand Down Expand Up @@ -222,17 +242,9 @@ fn dylibs_present(
Some(false)
}

/// The function for checking if any rpath present in the main Mach-O or
/// embedded Mach-O files contain a rpath with the desired path
///
/// # Arguments
///
/// * `ctx`: A mutable reference to the scanning context.
/// * `rpath`: The name of the dylib to check if present
///
/// # Returns
/// Returns true if the Mach-O parsed rpaths contain `rpath`
///
/// An `Option<bool>` containing if the path is found
/// `rpath` is case-insensitive.
#[module_export(name = "rpath_present")]
fn rpaths_present(ctx: &ScanContext, rpath: RuntimeString) -> Option<bool> {
let macho = ctx.module_output::<Macho>()?;
Expand Down
Loading

0 comments on commit 8550f8c

Please sign in to comment.