diff --git a/plugins/bntl_utils/src/tbd.rs b/plugins/bntl_utils/src/tbd.rs index 01855c13da..47b938a2f5 100644 --- a/plugins/bntl_utils/src/tbd.rs +++ b/plugins/bntl_utils/src/tbd.rs @@ -204,7 +204,15 @@ pub enum TbdArchitecture { Armv7s, Armv7k, Arm64, + #[serde(rename = "arm64.x1")] + Arm64X1, + #[serde(rename = "arm64.x2")] + Arm64X2, Arm64e, + #[serde(rename = "arm64e.x1")] + Arm64eX1, + #[serde(rename = "arm64e.x2")] + Arm64eX2, } impl TbdArchitecture { @@ -217,7 +225,11 @@ impl TbdArchitecture { TbdArchitecture::Armv7s => CoreArchitecture::by_name("armv7"), TbdArchitecture::Armv7k => CoreArchitecture::by_name("armv7"), TbdArchitecture::Arm64 => CoreArchitecture::by_name("aarch64"), + TbdArchitecture::Arm64X1 => CoreArchitecture::by_name("aarch64"), + TbdArchitecture::Arm64X2 => CoreArchitecture::by_name("aarch64"), TbdArchitecture::Arm64e => CoreArchitecture::by_name("aarch64"), + TbdArchitecture::Arm64eX1 => CoreArchitecture::by_name("aarch64"), + TbdArchitecture::Arm64eX2 => CoreArchitecture::by_name("aarch64"), } } } @@ -234,7 +246,11 @@ impl FromStr for TbdArchitecture { "armv7s" => Ok(TbdArchitecture::Armv7s), "armv7k" => Ok(TbdArchitecture::Armv7k), "arm64" => Ok(TbdArchitecture::Arm64), + "arm64.x1" => Ok(TbdArchitecture::Arm64X1), + "arm64.x2" => Ok(TbdArchitecture::Arm64X2), "arm64e" => Ok(TbdArchitecture::Arm64e), + "arm64e.x1" => Ok(TbdArchitecture::Arm64eX1), + "arm64e.x2" => Ok(TbdArchitecture::Arm64eX2), _ => Err(format!("Unknown architecture: {}", s)), } } @@ -394,6 +410,19 @@ exports: - targets: [ x86_64-macos, arm64-macos ] symbols: [ _VTCompressionSessionCreate, _VTDecompressionSessionCreate ] ... +"#; + + const V4_TBD_ARM64E_X1: &str = r#" +--- !tapi-tbd +tbd-version: 4 +targets: [ x86_64-macos, x86_64-maccatalyst, arm64e-macos, arm64e-maccatalyst, + arm64e.x1-macos, arm64e.x1-maccatalyst ] +install-name: '/usr/lib/libz.1.dylib' +current-version: 1.2.12 +exports: + - targets: [ x86_64-macos, arm64e-macos, arm64e.x1-macos ] + symbols: [ _deflate, _inflate ] +... "#; #[test] @@ -430,6 +459,25 @@ exports: assert!(has_arm64_macos); } + #[test] + fn test_parse_v4_tbd_arm64e_x1() { + let mut cursor = Cursor::new(V4_TBD_ARM64E_X1); + let result = parse_tbd_info(&mut cursor).expect("Should parse V4 TBD with arm64e.x1"); + + let info = &result[0]; + assert_eq!(info.targets.len(), 6); + let has_arm64e_x1_macos = info + .targets + .iter() + .any(|t| t.arch == TbdArchitecture::Arm64eX1 && t.platform == TbdPlatform::Macos); + assert!(has_arm64e_x1_macos); + let export = &info.exports[0]; + assert!(export + .targets + .iter() + .any(|t| t.arch == TbdArchitecture::Arm64eX1)); + } + #[test] fn test_multi_document_parsing() { // TBD v3+ supports multiple YAML documents in one file diff --git a/view/macho/fatmachoview.cpp b/view/macho/fatmachoview.cpp index 83499fb6c8..67835839b0 100644 --- a/view/macho/fatmachoview.cpp +++ b/view/macho/fatmachoview.cpp @@ -49,9 +49,13 @@ static bool FindMostSpecificCpuTypeSubtype(cpu_type_t cputype, cpu_subtype_t cpu } } // Then, any -all arch that matches + auto allSubtypeItr = g_allSubtypeMap.find(cputype); + if (allSubtypeItr == g_allSubtypeMap.end()) + return false; + for (const auto& type : *g_recognizedFatTypes) { - if (type.cputype == cputype && type.cpusubtype == g_allSubtypeMap.at(cputype)) + if (type.cputype == cputype && type.cpusubtype == allSubtypeItr->second) { outType = type.cpusubtype; return true; @@ -137,6 +141,9 @@ static bool ExtractFatArchForCPU(BinaryView* data, fat_arch_64& arch, cpu_type_t continue; } + // Mask away cpu subtype capability bits + iarch.cpusubtype &= ~MACHO_CPU_SUBTYPE_MASK; + // Make sure the passed subtype is the most specific, otherwise two different views // will try to display the same slice cpu_subtype_t mostSpecific; @@ -227,7 +234,11 @@ void BinaryNinja::InitFatMachoViewType() {"Fat Mach-O x86_64", "Fat Mach-O x86_64", MACHO_CPU_TYPE_X86_64, MACHO_CPU_SUBTYPE_X86_64_ALL}, {"Fat Mach-O x86", "Fat Mach-O x86", MACHO_CPU_TYPE_X86, MACHO_CPU_SUBTYPE_X86_ALL}, + {"Fat Mach-O arm64e.x2", "Fat Mach-O arm64e.x2", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E_X2}, + {"Fat Mach-O arm64e.x1", "Fat Mach-O arm64e.x1", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E_X1}, {"Fat Mach-O arm64e", "Fat Mach-O arm64e", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E}, + {"Fat Mach-O arm64.x2", "Fat Mach-O arm64.x2", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_X2}, + {"Fat Mach-O arm64.x1", "Fat Mach-O arm64.x1", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_X1}, {"Fat Mach-O arm64v8", "Fat Mach-O arm64v8", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_V8}, {"Fat Mach-O arm64", "Fat Mach-O arm64", MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_ALL}, {"Fat Mach-O arm64_32", "Fat Mach-O arm64_32", MACHO_CPU_TYPE_ARM64_32, MACHO_CPU_SUBTYPE_ARM64_32_V8}, diff --git a/view/macho/machoview.h b/view/macho/machoview.h index ee3b84d170..38dbb9a703 100644 --- a/view/macho/machoview.h +++ b/view/macho/machoview.h @@ -78,6 +78,10 @@ typedef int vm_prot_t; #define MACHO_CPU_SUBTYPE_ARM64_ALL ((cpu_subtype_t) 0) #define MACHO_CPU_SUBTYPE_ARM64_V8 ((cpu_subtype_t) 1) #define MACHO_CPU_SUBTYPE_ARM64E ((cpu_subtype_t) 2) +#define MACHO_CPU_SUBTYPE_ARM64_X1 ((cpu_subtype_t) 3) +#define MACHO_CPU_SUBTYPE_ARM64_X2 ((cpu_subtype_t) 4) +#define MACHO_CPU_SUBTYPE_ARM64E_X1 ((cpu_subtype_t) 12) +#define MACHO_CPU_SUBTYPE_ARM64E_X2 ((cpu_subtype_t) 13) #define MACHO_CPU_SUBTYPE_ARM64_32_ALL ((cpu_subtype_t) 0) #define MACHO_CPU_SUBTYPE_ARM64_32_V8 ((cpu_subtype_t) 1) diff --git a/view/macho/universaltransform.cpp b/view/macho/universaltransform.cpp index 3316421519..e44436234a 100644 --- a/view/macho/universaltransform.cpp +++ b/view/macho/universaltransform.cpp @@ -37,6 +37,10 @@ const map, string>& UniversalTransform::GetArchi {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_ALL}, "arm64"}, {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_V8}, "arm64v8"}, {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E}, "arm64e"}, + {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_X1}, "arm64.x1"}, + {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64_X2}, "arm64.x2"}, + {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E_X1}, "arm64e.x1"}, + {{MACHO_CPU_TYPE_ARM64, MACHO_CPU_SUBTYPE_ARM64E_X2}, "arm64e.x2"}, {{MACHO_CPU_TYPE_ARM64_32, MACHO_CPU_SUBTYPE_ARM64_32_ALL}, "arm64_32"}, {{MACHO_CPU_TYPE_ARM64_32, MACHO_CPU_SUBTYPE_ARM64_32_V8}, "arm64_32v8"}, {{MACHO_CPU_TYPE_MC88000, 0}, "mc88000"}, diff --git a/view/sharedcache/core/SharedCacheView.cpp b/view/sharedcache/core/SharedCacheView.cpp index 6827ac496c..b92871af2b 100644 --- a/view/sharedcache/core/SharedCacheView.cpp +++ b/view/sharedcache/core/SharedCacheView.cpp @@ -225,7 +225,7 @@ bool SharedCacheView::Init() magic[16] = 0; if (std::string(magic) == "dyld_v1 arm64" || std::string(magic) == "dyld_v1 arm64e" - || std::string(magic) == "dyld_v1arm64_32") + || std::string(magic) == "dyld_v1arm64ex1" || std::string(magic) == "dyld_v1arm64_32") { arch = "aarch64"; }