
For Binary Ninja 5.3, we’re bringing features and fixes across a number of areas. For improved interoperability, we’ve added Ghidra Export to the existing Ghidra Import code and have improved our IDB Import capability. For new architectures and platforms, we’ve added NDS32 to Ultimate, a new ILP32 ABI for AArch64, and a new set of APIs for “weird” architectures. And of course, we’ve made a number of improvements to the UI including a new Universal Mach-O loader UI, usability improvements to the container browser, and a new “super” command palette! Plus, changes to the debugger, enterprise features, new opt-in crash reporting to help us squash bugs faster, and so much more!
Building on the new architecture APIs added in 5.1, we’ve added a new set of APIs to support standalone function-level lifting. Our initial design for Binary Ninja was optimized for multithreaded analysis with as little state as possible so that each basic block could potentially be analyzed in its own thread. However, for plenty of architectures (including a lot of VM-based ones such as Java, Python bytecode, .NET, etc.), there is far too much state or even metadata at the top of each function. The only way to handle such architectures is to enable a single thread to analyze the entire function. While the ABB feature in 5.1 added support for basic block recovery and analysis in a single thread, in 5.3 we now support full function-level lifting.
Internally, we’re using these APIs to work on our upcoming TMS320C6x support, but because we use the same APIs available to third parties, this also means other projects like banjo or some of the WASM plugins we’ve heard about could be updated for much better decompilation results using these new APIs.
Keep an eye out for an upcoming blog post explaining more about how you can leverage these APIs yourself!
Ultimate customers will appreciate the brand new NDS32 support. We now have 18 officially supported architectures including full decompilation in our Ultimate/Enterprise edition!
It’s not enough to just have support for the instructions in a CPU architecture since there are lots of platforms or variants that need to be supported. For example, ILP32 adds a mode for AArch64 that has 32-bit pointers despite still using 64-bit mode. In 5.3, we’ve not only added the platform, but also updated our function recognizer for ILP32 PLT entries and fixed a bug related to the address size calculation.
While it’s long been possible to open a specific slice in a fat Mach-O or even adjust your settings to default to a particular slice, the UI around it was fairly painful, reusing our “Open With Options” dialog in a way that led to a lot of confusion.
In 5.3, you now get a much more streamlined dialog that lets you pick the architecture and, more importantly, makes it easy to set the default for future opens without having to dig through the settings! The dialog also shows the size of each slice, so you can quickly identify the one you need.
We first introduced the Container Browser in 5.2; however, we’ve made a number of improvements to both the container system and to the formats it supports!
Already Supported Formats: CaRT, Gzip, IntelHex, LZFSE, SRec, TiTxt, Zip, Zlib
New In 5.3: AR, Bzip2, CPIO, DMG (compression only), FIT, IMG4/KernelCache, LZ4Frame, LZMA, Tar, TRX, UImage, Universal Mach-O, XZ, Zstd
The Container Browser UI itself has also had a number of improvements, as well. It now remembers your most recent selection, can be triggered for files explicitly from the file menu (or by holding Ctrl+Alt and dragging/dropping), and the UI has been refreshed.
We’ve also added better documentation about the transform system and UI.
While we’ve had our command-palette for some time, in 5.3 we’ve turbocharged it with a ton of new features. You can prefix your search with various characters to get different behaviors. Note that the default CTRL/CMD-P hotkey defaults to “action search” (the previous behavior) but can be rebound to use any of the new behaviors.
= Use the expression parser to calculate an address and navigate there (including a preview)> Action search, the previous default/ Search recent files and projects, as well as open tabs@ Search function symbols (similar to searching in the symbol sidebar)? Display available search prefixest: Just search open tabs (useful as a bindable hotkey)" Search stringsFor more details, check out our recent blog post about it.
One of our major focus areas currently is our type system and how we collect, manage, and apply types. To that end, this release includes a new set of utilities to handle type libraries. This can be used to automatically create usable type libraries from a binary view or from files in a directory. For users with project support (currently commercial and above), type libraries can also be generated from files in a project.
See the BNTL plugin menu for the available commands:
There’s also a command-line version for headless automation for customers with headless support:
/t/bntl_utils_cli > ./bntl_cli --help
Generate, inspect, and validate Binary Ninja type libraries (BNTL)
Usage: bntl_cli <COMMAND>
Commands:
create Create a new type library from a set of files
dump Dump the type library to a C header file
diff Generate a diff between two type libraries
validate Validate the type libraries for common errors
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
/t/bntl_utils_cli > ls -l
total 13728
-rwxr-xr-x 1 jwiens wheel 5498296 Apr 9 11:23 bntl_cli*
drwxr-xr-x 4 jwiens wheel 128 Apr 9 11:37 headers/
/t/bntl_utils_cli > ls -l headers/
total 1360
-rw-r--r--@ 1 jwiens wheel 690055 Apr 9 11:35 sqlite3.h
-rw-r--r-- 1 jwiens wheel 286 Apr 9 11:37 stdarg.h
/t/bntl_utils_cli > ./bntl_cli create sqlite3.dll "windows-x86_64" ./headers/ ./output |grep -v "Loaded native"
2026-04-09T15:40:37.966972Z WARN binaryninja: User plugins disabled from command-line override logger=Default
2026-04-09T15:40:39.381327Z INFO binaryninja: 10021 bundled types for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.381337Z INFO binaryninja: 0 bundled variables for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.381339Z INFO binaryninja: 77 bundled functions for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.384452Z INFO binaryninja: 1 types for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.384459Z INFO binaryninja: 0 variables for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.384461Z INFO binaryninja: 0 functions for platform windows-x86_64 loaded logger=Platform
2026-04-09T15:40:39.677619Z INFO bntl_cli::create: Created type library 'sqlite3.dll': ./output/x86_64/sqlite3.dll.bntl
Keep an eye out for an upcoming blog post that will include more details about how these tools can make your life easier.
Last release, we added networked functionality to WARP, our tool for matching previously identified functions. This allowed users to push and pull function information from our server. Additionally, the v2 enterprise server release included a built-in WARP server for our enterprise customers. For this release we are continuing to improve the UX of interacting with the WARP server.
Pushing signatures is more straightforward with a new UI, and fetching signatures from the server uses less bandwidth by performing server-side matching.
For this release, we also deprecated SigKit (which can be re-enabled with analysis.signatureMatcher.autorun), with its removal scheduled for next release. To that end, we bundled signatures for common Linux libraries (libc6, libgcc, libstdc++) to finalize the migration from SigKit to WARP. These signatures are available for x86, x86_64, aarch64, and armv7.
We added Ghidra Import in Binary Ninja 5.2, and now we’ve come full circle with Ghidra Export capabilities in 5.3.
First, use the plugin menu to export a .gzf file:
Next, import the file into Ghidra:
That’s it! Now you’ll have all the types, symbols, bookmarks, comments, function starts, etc. that you had in Binary Ninja in Ghidra:
With this release, we overhauled our IDB (and TIL) import functionality. This new version processes more information and will work with many more IDA databases.
The biggest feature for Enterprise in 5.3 is that this is the first stable release since we launched our v2 Enterprise server. The new server comes with a number of major features:
Check out the release blog post for more details. We encourage all Enterprise customers to migrate to v2, but we do plan to maintain the v1 server for some additional time to ease the transition.
Two of our most requested debugger features are finally here: hardware breakpoints and conditional breakpoints, making your debugging workflow much more flexible.
To add a hardware breakpoint, press F3 or use Debugger / Add Hardware Breakpoint... (also available by right-clicking in the Breakpoint Widget). The dialog lets you pick the address, type (Hardware Execute, Read, Write, or Access), watchpoint size (1, 2, 4, or 8 bytes), and the entries show up in the Breakpoint Widget tagged HE/HR/HW/HA.
Conditional breakpoints attach to any existing breakpoint: right-click on a breakpoint (in either the Breakpoint Widget or the disassembly view) and choose Edit Condition.... Conditions support register names, arithmetic, comparisons, and memory dereferences (e.g., rax == 0x1234, [rsp + 0x20] != 0), and execution only pauses when the expression evaluates to non-zero.
Two new debug adapters ship with 5.3:
The Windows Native Debug Adapter is a brand-new adapter built on top of the Windows debugging APIs and is now the default debugger on Windows. It comes with major performance improvements over the previous DbgEng-based adapter.
The GDB MI Adapter provides a new way to connect to GDB-compatible targets using the GDB Machine Interface protocol, fixing many corner cases in the previous GDB RSP adapter. It works seamlessly with gdbserver or GDB stubs such as those from QEMU, and includes support for TTD (Time Travel Debugging) via Mozilla’s rr. Currently Linux-only, with Windows and macOS support planned.
To ensure we can fix issues faster, in 5.3 we’ve added opt-in automatic crash reporting. The first time you launch 5.3 (unless you’ve already seen it on dev) you’ll see a prompt asking whether you’d like to share crash reports with us. In paid versions, it’s disabled by default. In the Free version, it’s enabled by default but you can still opt-out and you can change your mind at any time by changing the appropriate setting.
When enabled, a crash report contains:
No binary content or identifying information is intentionally included, though application and plug-in paths may contain your system username. Full details are in our privacy policy.
If you want to help us fix bugs faster, we’d appreciate enabling crash reporting but absolutely understand for many this is not desired which is why we default to NOT sending this information.
Special thanks to the following open source contributors whose PRs were merged into this release:
We appreciate your contributions!
ZxTransform to the transform systemPossibleValueSet::Compare to resolve set and range comparisons to constantsPossibleValueSet operation APIs and fixed Python PossibleValueSet bindings0x0 entry address and no entry at allUNDEF instruction chains with a more compact representationcanMakeString by avoiding large scans for null terminators in UTF-16 and UTF-32 stringsSectionMap to section creation APIs for more consistent behaviorUNDEF instructionsDemangledTypeNode(X << Y) u>> Y and (X u>> Y) << YreadLEB128 is passed a null pointerQualifiedName stateDW_AT_location variants for DW_TAG_variableAnalysis::DeleteUnusedAutoFunctions hanging for many minutes on large binaries with over 1 million functionsFloatType alternate name not rendering in tokens when setLowLevelILFunction::GetInstructionsAt not working on SSA formMLILSSATranslator not consulting the Platform for global register informationWorkflowMachine task name when resuming from an inactive stateOutlineResolver caused by cycles involving named type referencesWorkflowMachine when a workflow activity threw an exceptionvoid variable type and an MLIL pointer expression typeFunction that could cause crashes during analysis0x7cNamedTypeReferences instead of resolving them to raw structs__offset attribute losing their offset due to struct member relationship not being preservedABB incorrectly triggering guided analysisFunctionLifterContextOutlineResolver[api:...] annotationsOutlineResolver handling when merging different stream types while writing to fully-typed byte arraysFilterEdit widgetFilterEdit widget.bndb files from the triage file picker to avoid opening database files in triage modeunordered_map, and using uniform row heightsMemoryRegionDialog incorrectly prepopulating length for file-backed regionsTypeDialog when parser results arrived at the wrong timeget_choice_input is called without an active windowtypedefCopy As actionQStringsResolveMemberOrBaseMember for improved accuracyGetInstructionTextWithContext callback to the architecture class to share context between basic block recovery, lifting, and disassemblyR_CKCORE_PCREL_JSR_IMM26BY2 relocation support for C-SKY architectureLiftFunctionro_after_init region and synthesize overlay section for improved kernel analysisDTPOFF64 and DTPMOD64 TLS relocationsjalr instruction incorrectly receiving a default branch typesi_split16 immediate decoding for PPC VLE I16A-form instructionsobjc_retain_xN / objc_release_xN in the Objective-C runtime type libraryjalr[.hb] $zero, $ra to be recognized as a return instructionFreeFunctionArchContext error logs on LinuxLIST_ENTRY type specializations for AMD64 Windows platformCpop instruction outputlinux-x32 which retains 8-byte pointers)p0 dependenciesldq/stq instruction handling in M-CORE architectureobjc_alloc_init and related functions in the Obj-C plugincorePlugins.ghidraImport to corePlugins.ghidraBeginBulkAddSegments/EndBulkAddSegments to defer section map rebuildsflags with SECTION_TYPEobjc_msgSend calls that send an init message to a known classSectionMapadd bitfield setting from SVD Import as bitfields are now always included with correct type system representation.interp or .dynamic sectionsBIND_SPECIAL_DYLIB_\*_LOOKUP modes in MachO chained fixups where negative-encoded library values were mishandledFileAccessorCache LRU eviction discarding mapped filescore.function.metaAnalysis workflow description.bndb__offset fields to appear in structuresbinaryninjacore, which prevented it from loadingOpen Selected Files with Container Browser... option to the project browser context menuSave As behavior when working with project filesdatabasesync.pyCreate Type Archive dialog when used with a project fileUser Positions errorsget_metadata() method to BinaryView, Function, and Project, and made query_metadata() raise KeyError consistentlymutex and recursive_mutex to bn::base, using os_unfair_lock on Apple platformsTransformSession constructor that adopts an existing TransformContextQualifiedName.separator property to the Python APIBinaryView subclasses to run code after snapshot data is appliedLowLevelILFunction::AddOverFlow APITransformSessionBNDetectSearchMode to the Python API for search mode testingTypeLibrary.remove_named_object and TypeLibrary.remove_named_type to the Python APIGetNamedTypeSource API to type librariesTypeLibrary::Register to allow loading type libraries programmatically from scriptsTypeLibrary.duplicate API to Python bindingsTypeLibrary objects without requiring them to be written to disk firstBN_DEPRECATED macro to annotate deprecated C++ APIs with compiler warningsProjectFile type annotation to the Python load functionSegmentInfo and SectionInfo dataclasses and helper functions to make add_user_segment, add_auto_segment, and section APIs more PythonicVariableList::updateCrossReferences declaration to the APITransform system and improved documentationNamedTypeReferenceBuilder properties in the Python API[[nodiscard]] attribute to Structure/StructureBuilder GetMemberByName/GetMemberByOffset to catch ignored return values at compile timeForEachField APIs to reduce copying of structure membersMLIL_SEPARATE_PARAM_LIST and MLIL_SHARED_PARAM_SLOT in Python copy_expr_toArchitecture flags fields in the Python APIILInstruction::CopyToMemoryMap bindings and added support to re-enable disabled regions in the UIConfidence<T> move semantics to avoid unnecessary copies and reference count churncanMakeStringQualifiedName constructor to accept a separator parameterIntFlag instead of IntEnumbn::base::function_ref instead of std::function for non-stored callback parameters to reduce overheadBinaryView.get_modification failing when passing a length argumentLogTrace *FV/*F variants to respect the BN_ENABLE_LOG_TRACE compile guard instead of unconditionally calling fmt::vformatTypeError when slicing FunctionList/BasicBlockList with [:], [n:], or [:n]show_message_box when description is None in PythonQueueGenerator search APIsNone cases when empty strings are returned from core and corrected associated coreversion usageTagList to match FunctionList/BasicBlockList behaviorBinaryView types in Python APICallingConvention.get_incoming_flag_value in the Python APICoreVersionInfo API and added unit testsFunction::StoreMetadata not marking the function as changed, ensuring dependent analysis is properly invalidatedget_flag_write_low_level_il to properly extract LLIL flags in the Python APIPlatform.view_init passing the cffi object instead of the API objectQualifiedName join from FFI and added NameSpace join supportInvalidILViewType)flags parameter type annotation to correctly reflect flag writes rather than flagsflag_name in Python APIArchitecture.assemble in Python subclasses being brokenQName separator method to use the correct name join to match the C++ APIQualifiedName structTypeBuilder.handle where the underlying object was deleted before the handle was usedaddress_comments to BinaryViewExt in the Rust APIBinaryViewExt::tags_all_scopes, tag_types, and tags_by_type to the Rust APIBinaryViewExt::type_libraries to the Rust APIFrom<BnString> impl for QualifiedName to simplify conversionsFunction::defined_symbol to retrieve a function’s symbol only when it is explicitly definedload_project_file and load_project_file_with_progress to open project-linked files and avoid detached binary viewsLowLevelILSSARegister type to the Rust APIOwnedBackgroundTaskGuard for automatically finishing background tasks via RAIIPlatform::address_size to the Rust APISymbol::ordinal to the Rust APITypeBuilder::function and TypeBuilder::function_with_opts to the Rust API for constructing function typesTypeBuilder::set_signed to the Rust APITypeLibrary::remove_named_object and TypeLibrary::remove_named_type to the Rust APITypeLibrary API improvements to the Rust bindingsTypeArchiveId type to prevent ID type confusion in the type archive APISend and Sync for TypeLibrary to enable safe cross-thread usagetracing and logger modulesBinaryViewEventHandler for Fn(&BinaryView), allowing closures to be passed directly to the register functionDebug for RemoteProject, RemoteFolder, and BinaryViewTypeDisplay for Symbol, FileMetadata, and VersionInfoPartialEq, Eq, and Hash for ProjectFile and ProjectSend and Sync for RemoteFolder, CoreLanguageRepresentationFunctionType, RemoteProject, and RemoteFileInstructionTextToken field expr_index optional via Option typeAnalysisProgress returned from BinaryViewExt::analysis_progressFileMetadata to rename and retype filename and require it to be set at construction timeUnusedRegisterStackInfo and updated architecture documentation in the Rust APIArchAndAddr type in favor of Locationlog with tracing for logging in the Rust APItypes module for improved discoverability and documentationTagReference to optionally accept architecture and function parametersTypeBuilder::named_type to accept type_reference by reference instead of by valueTypeParser to use PathBuf instead of String for include directory parametersArray types for more consistent Rust API patternsload_view_with_progress when options is NonePartialEq and Hash impls for FileMetadata to use the unique session_id for comparisons and hashingQualifiedName::default() incorrectly creating a QualifiedName with an empty separatorLowLevelILFunction::generate_ssa_form without an owner functionanalysis_info with function refs and added string reader helpersWebsocketClientCallback objects in the Rust APIFunction::guided_source_blocks where BNFreeArchitectureAndAddressList was not calledRemoteFile::core_fileCoreTypeParserexpr_idx within MLIL ILReferenceSource in the Rust APIBinaryViewExt::address_comments memory leak and refactored implementationOwnedBackgroundTaskGuard to not require mutable selfNextMemoryAccess/PrevMemoryAccess API and UI for TTD (Time Travel Debugging)debugger.autoRebase setting and a new Rebase to Remote Base actionGetCurrentTTDPosition and SetTTDPosition for the esReven adapter using rvn:get-current-transition and rvn:set-current-transitionGetThreadList and GetFramesOfThread for the esReven adapter using the rvn:list-threads packetrvn:get-memory-accessesFilterEdit in the debuggerttd.maxSymbolsLimit setting (default 50, 0 for no limit) for esReven TTD wildcard symbol lookupsDebugBreakpoint.__repr__ to include the condition when setParseGdbValue to correctly handle vector/SIMD registers and unavailable values in GDB MI register outputg_debuggerControllers by replacing raw pointer management with thread-safe storagedbgeng fails to initializedbghelp.dll from loading from System32 and breaking the dbgeng adapterdbg.breakpoints0x0 in the TTD memory widgetexecute_ APIs__attrDespite the list of changes getting bigger with almost every release, it still doesn’t cover everything that’s happened! If you want to see even more details, check out our closed milestone on GitHub.