summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-02-18 19:43:43 -0800
committerMark Rowe <mark@vector35.com>2026-03-23 16:08:45 -0700
commit7aa5bd46fc2343458dff6a24ec2c67169fcac34c (patch)
tree59d68c2afafde453abcf4795f996784f4ab9740e /plugins
parenta49c29b7aea694e41fb92b100325ce34affb413f (diff)
[Swift] Initial demangling support
Diffstat (limited to 'plugins')
-rw-r--r--plugins/workflow_swift/Cargo.toml1
-rw-r--r--plugins/workflow_swift/demo/Cargo.toml1
-rw-r--r--plugins/workflow_swift/src/demangler/mod.rs34
-rw-r--r--plugins/workflow_swift/src/lib.rs6
4 files changed, 42 insertions, 0 deletions
diff --git a/plugins/workflow_swift/Cargo.toml b/plugins/workflow_swift/Cargo.toml
index 43073718..8ed4f8c4 100644
--- a/plugins/workflow_swift/Cargo.toml
+++ b/plugins/workflow_swift/Cargo.toml
@@ -16,3 +16,4 @@ binaryninja = { workspace = true }
binaryninjacore-sys.workspace = true
tracing = "0.1"
thiserror = "2.0"
+swift-demangler = { git = "https://github.com/Vector35/swift-demangler.git" }
diff --git a/plugins/workflow_swift/demo/Cargo.toml b/plugins/workflow_swift/demo/Cargo.toml
index 38fb633d..a1e46891 100644
--- a/plugins/workflow_swift/demo/Cargo.toml
+++ b/plugins/workflow_swift/demo/Cargo.toml
@@ -17,3 +17,4 @@ binaryninja = { workspace = true, features = ["demo"] }
binaryninjacore-sys.workspace = true
tracing = "0.1"
thiserror = "2.0"
+swift-demangler = { git = "https://github.com/Vector35/swift-demangler.git" }
diff --git a/plugins/workflow_swift/src/demangler/mod.rs b/plugins/workflow_swift/src/demangler/mod.rs
new file mode 100644
index 00000000..e1f22893
--- /dev/null
+++ b/plugins/workflow_swift/src/demangler/mod.rs
@@ -0,0 +1,34 @@
+use binaryninja::architecture::CoreArchitecture;
+use binaryninja::binary_view::BinaryView;
+use binaryninja::demangle::CustomDemangler;
+use binaryninja::rc::Ref;
+use binaryninja::types::{QualifiedName, Type};
+
+pub struct SwiftDemangler;
+
+impl CustomDemangler for SwiftDemangler {
+ fn is_mangled_string(&self, name: &str) -> bool {
+ name.starts_with("$s")
+ || name.starts_with("_$s")
+ || name.starts_with("$S")
+ || name.starts_with("_$S")
+ || name.starts_with("$e")
+ || name.starts_with("_$e")
+ || name.starts_with("_T")
+ }
+
+ fn demangle(
+ &self,
+ _arch: &CoreArchitecture,
+ name: &str,
+ _view: Option<Ref<BinaryView>>,
+ ) -> Option<(QualifiedName, Option<Ref<Type>>)> {
+ let ctx = swift_demangler::Context::new();
+ let symbol = swift_demangler::Symbol::parse(&ctx, name)?;
+ // Use the canonical demangled form from the parsed node tree.
+ // This matches what `xcrun swift-demangle` produces.
+ // TODO: Use the structured Symbol API to also reconstruct BN Types.
+ let demangled = symbol.display();
+ Some((QualifiedName::from(demangled), None))
+ }
+}
diff --git a/plugins/workflow_swift/src/lib.rs b/plugins/workflow_swift/src/lib.rs
index b8ddb7a4..2e97a43b 100644
--- a/plugins/workflow_swift/src/lib.rs
+++ b/plugins/workflow_swift/src/lib.rs
@@ -1,4 +1,8 @@
+mod demangler;
+
use binaryninja::add_optional_plugin_dependency;
+use binaryninja::demangle::Demangler;
+use demangler::SwiftDemangler;
#[no_mangle]
#[allow(non_snake_case)]
@@ -12,5 +16,7 @@ pub extern "C" fn CorePluginDependencies() {
pub extern "C" fn CorePluginInit() -> bool {
binaryninja::tracing_init!("Plugin.Swift");
+ Demangler::register("Swift", SwiftDemangler);
+
true
}