Modern, fully statically typed C# bindings for the Binary Ninja C API. Designed for safety, performance, and Native AOT compatibility. Use it as a dynamic library in your apps, compile CLI tools with Native AOT, or build native Binary Ninja plugins.
- Statically typed API surface
- 100% SafeHandle-based resource management
- Idiomatic IDisposable/Dispose pattern
- Native AOT friendly (no reflection-heavy runtime dependencies)
- Works with .NET 8.0+
- Do not use this in production. The API is experimental and may introduce breaking changes without notice.
dotnet add package BinaryNinja
- .NET 8.0 or newer
- Binary Ninja installed (Desktop or Headless)
- Ensure the Binary Ninja native libraries are discoverable at runtime:
- environment variable: BINARYNINJA_BASE or BINARYNINJA_HOME (points to Binary Ninja installation root)
using System; using BinaryNinja; class Program { static void Main() { NativeLibrary.SetDllImportResolver( typeof(BinaryNinja.Core).Assembly, new LibraryResolver().ResolveDllImport ); Core.InitPlugins(true); using BinaryView? view = BinaryView.LoadFile("driver.sys.bndb"); if (null == view) { throw new Exception("load fail"); } foreach(Function function in view.Functions) { Console.WriteLine(function.RawName); } Core.Shutdown(); } }
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using BinaryNinja; namespace Dummy { public static class Plugin { static Plugin() { NativeLibrary.SetDllImportResolver( typeof(BinaryNinja.Core).Assembly, new LibraryResolver().ResolveDllImport ); } [UnmanagedCallersOnly( EntryPoint = "CorePluginABIVersion", CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) }) ] public static uint CorePluginABIVersion() { return BinaryNinja.Core.CurrentCoreABIVersion; } [UnmanagedCallersOnly(EntryPoint = "CorePluginInit", CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] public static byte CorePluginInit() { BinaryNinja.Core.LogInfo("[+] i am native aot plugin\n"); BinaryNinja.Core.LogInfo( $"[+] Core CurrentCoreABIVersion: {Core.GetCurrentCoreABIVersion()}\n"); BinaryNinja.Core.LogInfo( $"[+] Core MinimumCoreABIVersion: {Core.GetMinimumCoreABIVersion()}\n"); BinaryNinja.Core.LogInfo( $"[+] Plugin CurrentCoreABIVersion: {Core.CurrentCoreABIVersion }\n"); BinaryNinja.Logger logger = BinaryNinja.Logger.GetOrCreateLogger("Dummy"); logger.LogInfo("[+] use private logger\n"); BinaryNinja.PluginCommand.RegisterPluginCommand( "Dummy command", "Dummy command description", Plugin.DefaultCommand, Plugin.DefaultIsValid ); logger.LogInfo("[+] init done."); return 1; // success } public static void DefaultCommand(BinaryView view ) { Logger logger = BinaryNinja.Logger.GetOrCreateLogger("Dummy"); logger.LogInfo($"view length: {view.Length}"); Core.OpenUrl("https://github.com/tinysec/binaryninja"); Function? function = view.ChooseFunction(); if (null != function) { logger.LogInfo($"function , RawName: {function.RawName}"); } } public static bool DefaultIsValid(BinaryView view ) { return true; } } }
- DllNotFoundException / EntryPointNotFoundException
- Ensure set BINARYNINJA_BASE
- On Native AOT, confirm your RID is correct and you published with PublishAot=true
- AccessViolationException
- Check lifetime: ensure using-statements dispose views/sessions before exit
- Make sure the target BN C API functions exist in the installed version