What a release! Even we were surprised when we started tallying up all the major improvements since 4.0. Even though this is a minor version increment, the list of improvements is huge. It’s hard to pick favorites as we’ve seen major improvements in decompilation quality, multiple new architectures, type library improvements across most of the supported platforms and so many other important new features.
- Decompiler Improvements
- Linux ARM Builds
- UEFI Enhancements
- BASE
- UI Improvements
- macOS/iOS/Objective-C Improvements
- Fallback Libc
- Debugger
- Architecture/Platform Changes
- Open-Source Contributions
- Many More
Major Features
Decompiler Improvements
With Binary Ninja 4.1, our out of the box decompilation quality has dramatically improved. Of course, many of the features later in this blog all contribute to this improvement, but the most impactful change has been our control flow recovery changes. Along with dedicated verification by emulating IL to validate transformations, we’ve been able to not only improve the accuracy of our decompilation, but the readability as well.
Here’s one small example showing a C runtime function before and after this change:
While it’s impossible to convey the improvements exactly for any given binary, we ran a quick script across a recent ntoskrnl.exe
and saw show fantastic improvements: we observed 8% less if
statements, and 34% more for
loops. This was in addition to a decrease in 28% of total conditional instructions. Combined with the higher accuracy of our transformations, this again shows that not only is the decompilation better, it should be far more readable too.
We’ve also added many new boolean simplifications. While the higher level restructuring means they are needed far less frequently, when they do show up this will also result in far easier to read decompilation. See the detailed list of changes at the bottom of the blog for examples of the many types of boolean simplification added.
Of course many other changes also improved decompilation quality as well. In addition to the many type library improvements described below, we also improved lifting across multiple architectures. How much of a difference can that make? Check out this before/after from improved lifting:
![](/blog/images/4.1-release/checkpw-after.png)
![](/blog/images/4.1-release/checkpw-before.png)
Also, if you want to understand more about the internals of our decompilation, make sure to check out our recent blog post on Debug Visualizations built right into the product. They show in great detail how every step of analysis happens.
Linux ARM Builds
Whether you’re an Apple Silicon user missing your x86 virtual machines, or one of the few running ARM Linux on a native platform, either way we’ve got you covered. Elysium now has official support for ARM Linux on our officially supported Linux platforms. We’d show screenshots of the UI, but it’s just… the same UI as always. Except on ARM. So instead, enjoy this image of Phido chasing a penguin.
Note that the free version of Binary Ninja is not being released on ARM Linux in 4.1 due to ARMv8 not being included in free.
UEFI Enhancements
While we announced UEFI support with a plugin and core changes in Binary Ninja 3.5, this release brings a host of improvements to that support. First, we now have a Terse Executable (TE) view. Additionally, we added new platform types for System Management Mode (SMM), Pre-EFI Initialization (PEI), and PEIM-to-PEIM Interfaces (PPI). New functionality has been added to EFI Resolver to make use of these new types to identify SMM protocol interfaces and PPIs and to provide enhanced supplemental analysis for PEI and SMM modules. Some of the new types even take advantage of Binary Ninja’s offset pointers to allow EFI Resolver to identify accesses to PEI services relative to the x86 Interrupt Descriptor Table (IDT)!
Binary Ninja Base Address Scan Engine (BASE)
Announced a few months ago in a previous blog post, our new BASE feature is now live on version 4.1. It’s designed to automatically identify the correct load address when reverse engineering embedded firmware. True to our philosophy of “do the right thing by default” we have an intelligent set of default settings to automatically identify a binary blob’s default load address, but we also expose a large number of advanced settings to let you tune the search to your needs.
UI Improvements
History Widget
A brand new UI feature was added for 4.1: a history widget! Accessible from the bottom-right sidebar panel by default, this view even lets you see changes in databases that were created prior to the UI existing as our database format has supported this information since the first release of the product. The right click-menu, shown below, lets you restore to a particular point and also choose whether or not to show timestamps for the changes.
When changes are batched up by a plugin or certain actions, they will be clustered into a summary just showing their count for now. If you wish to remove this snapshot data, see the save with options documentation.
Address Display / Stack View
We’ve also highlighted these features in a recent post, but the new Address Display setting is especially helpful when you want to change the representation for the virtual addresses shown in any of the various views. The stack view changes make it a snap to be able to reference relative addresses from a particular stack offset. Great for when you’ve got a local variable overwrite and want to one-shot your target address without doing math!
macOS/iOS/Objective-C Improvements
We’ve had so many improvements to our Apple type libraries and platform handling that we’ve bundled them all into their own section. One of the most noticeable improvements is that Objective-C workflows no longer need to be manually enabled when analyzing a file. Instead, the BinaryView will automatically apply the appropriate transformations without any user-interaction. Additionally, the combination of new type libraries results in vastly improved analysis. See the below list for specific changes, and keep your eyes out for a forthcoming blog post that will go in much more detail about the current state of iOS and macOS analysis in Binary Ninja.
Note: the Objective-C workflow that is automatically run is not currently available in the free version, but it is available in cloud.
- Feature: Objective-C Processing is now automatic on binaries with Objective-C Metadata, enabling call rewrites will be automatically
- Feature: Objective-C msgSend stubs will now be automatically inlined
- Feature: objc_msgSend will automatically be overridden with a call type based on the amount of arguments in the selector
- Feature: Objective-C ARMv7/thumb2 support
- Feature: Added support for Objective-C Categories and ‘Lazy Classes’
- Feature: Massive update to macOS and iOS type libraries
- Improvement: Vast reliability improvements to Objective-C call rewrites
- Improvement: Enhanced error handling and recovery in malformed Objective-C binaries
- Improvement: Better handling for Objective-C information in Swift binaries
- Improvement: Better handling for Objective-C metaclass definitions
- Improvement: Better automatic naming and typing for Objective-C metadata
- Improvement: Vastly improved handling for CFStrings including UTF16 support and appropriate variable naming
- Improvement: Objective-C Mark
__objc_ivar
as const, define names for class/super refs - Improvement: Objective-C Parse CFStrings separately from primary Objective-C Processing, allowing CFString metadata to be processed in binaries with no Objective-C information. Resolves #5610
- Improvement: Objective-C Non-lazy Category Support, improve naming for category variables
- Improvement: Objective-C Parse protocol information, resolves #5589
- Improvement: Objective-C Properly wrap undo actions created by the processor
Fallback Libc
One of the most important sources of information Binary Ninja has about any binary you open are the type libraries we ship. While it’s important to allow users to leverage their own sources of information, the more we do out of the box, the better the results will be. Prior to Binary Ninja 4.1, each platform required its own dedicated libc type library which meant that any specific platform that didn’t have a library would have worse analysis as a result. With this release however, a default type library has been added with basic safe assumptions for type information that results in dramatically improved decompilation for binaries relying on a standard libc.
You’ll notice that even now the fallback library isn’t totally complete but there are several improvements in testing for dev after release and we expect to continue to improve the coverage in the future.
Debugger
Two main improvements in the debugger this release are better Time-Travel-Debugging (TTD) support and a single unified memory view.
Debugger Annotations and Memory Map API
Previously when using the debugger, any changes to analysis needed to be carefully made. An ephemeral BinaryView was created just for debugging that was associated with the debugger back-end, but this design decision had one crippling flaw — if you made changes such as adding types or a comment to your analysis but did it in the ephemeral view, these changes would be lost when ending your debugging session. Obviously this was bad and thankfully we’ve been able to fix it. The new MemoryMap API allows far more control over how memory is represented in a BinaryView and part of our goals for it were to allow representing memory that comes partially from a BinaryView or analysis session, and partly from a debugger backend.
The improvements in the MemoryMap also mean that for anyone working with embedded platforms and files, you now have far more control over how memory is laid out! Check out the API documentation as well as our feature announcement stream for more details.
TTD Made Easy
Time-travel debugging (TTD) integration has been a beta feature in Binary Ninja. In this release, we made it full-featured by adding the control buttons and API to do the reverse debugging, as well as a simplified workflow to configure WinDbg and record a TTD trace directly within Binary Ninja. If you have not used TTD before, definitely give it a try since it can dramatically boost your efficiency in many cases! Check out the docs online.
Architecture / Platform Changes
Much like our 4.0 release, we’re announcing support for two new architectures. First, MIPS Octeon support is in the base product for all customers, and TriCore support has been created as a paid add-on. Interested customers can contact us for pricing information.
Platform Changes
We’ve made some behind the scenes changes to how our platform system works. One of the immediate benefits of this is that the windows platform has been expanded to support automatically annotating PEB/TEB entries at the appropriate fs
offsets. Check out the following decompilation for example of a chunk of raw shellcode (in fact, you can test this yourself using Binary Ninja’s scc with its own builtin PEB scan implementation)
Just compile the example in an empty file and hit p
at the start to create a function. That’s it! Everything else shown above is 100% default analysis.
Octeon Support
Thanks to funding from one of our enterprise customers, we’ve been able to coordinate development of a new platform available for all customers in this release. If you’re interested in sponsoring a new architecture that’s important for you, let us know! Not only is the architecture open source, but it also fixed a large number of lifting issues in the base MIPS architecture as well.
TriCore (Paid Add-On)
Much like nanoMIPS previously, we have had a small number of customers express interest in a paid plugin for TriCore support and so we have created one that’s available for purchase. If you’re interested in more details, contact us.
Open-Source Contributions
Special thanks (in no particular order) to the following open source contributors whose unpaid work is either directly merged into this release or whose PRs prompted changes that landed! deadc0de6, samrussell, VisualEhrmanntraut, jrmo14, nbailluet, comex, whitequark, yrp604, joshwatson, clubby789, ergrelet, and JohnathanKG. We appreciate your contributions!
Finally, a special thank you to mkrasnitski, our top external contributor during this period!
Other Updates
And those are just the major features, here’s a more complete list of features, improvements, and fixes (even a deprecation or two) for 4.1:
UI Updates
- Feature: Automated base address detection
- Feature: New advanced search features
- Feature: Address display modes
- Feature: Allow users to specify file name displayed in offsets
- Feature: Show addresses relative to a fixed base address
- Feature: Added ability to only show ‘live’ stack variables
- Feature: Show variable increments as
+=
- Feature: Indention lines can now be highlighted
- Feature: Cross references can now navigate to precisely the correct IL instruction in many more situations
- Feature: Cross references will now preview according to currently displayed IL type
- Feature: New History Sidebar
- Feature: New actions to quickly adjust the selection size in linear and hex view
- Feature: Add “Navigate to Matching Brace” action
- Feature: Add “Reopen Current File” ui action
- Feature: Added “Create Array” to the Linear View context menu
- Feature: Add option to view stack variable offset from stack pointer (or other register)
- Feature: Setting to skip rendering braces for single line code blocks
- Improvement: Project browser tab is now closable
- Improvement: Display of Product Information dialog in Enterprise edition
- Improvement: Enumeration member in enumeration selection dialog is confirmed on double click
- Improvement: Use platform-specific names for keybinds in Keybindings View
- Improvement: Allow editing multiple external locations at once
- Improvement: Added copy actions to TypeBrowserView
- Improvement: Added setting to disable background parsing in change Type dialog
- Improvement: Automatically update the element count when the type is changed in the create array dialog
- Improvement: Populate default name for enums and unions in type view
- Improvement: Offer to create structure when pressing
s
while PossibleAddressToken is selected - Improvement: Ask(1) the user to confirm the action when renaming a type to an existing one or creating a type with existing name
- Improvement: Fallback to clang for name demangling when Binary Ninja’s demanglers fail
- Improvement: Option to have exact search matches come first in Type Browser
- Improvement: Make call param hints more configurable & support more param types for hint deduplication
- Improvement: Improved performance when loading DebugInfo
- Improvement: New lines now shown around code blocks
- Improvement: Remove ‘Installation Instructions’ tab from plugin manager
- Improvement: New backend for servicing plugin manager
- Improvement: Added maximum version for plugins
- Improvement: Faster loading of files with lots of strings on Windows
- Improvement: Make ReportCollectionWidget remember graph scale too
- Fix: Issue causing log spew when analyzing project files
- Fix: Issue causing filter to not display proper count in cross references
- Fix: Project browser interactions happening on deselected items
- Fix: bndb extension duplication on “Save As”
- Fix: Issue where the ‘Run Script’ actions were not usable
- Fix: Issue with log view filtering
- Fix: Issue with the clarity of when FilterEdit controls were disabled
- Fix: Issue where clang could error but not report those errors to the UI
- Fix: Issue where sidebar widgets could be inserted into the wrong location if there is a floating widget open
- Fix: Issue where BNDBs using nested folders could crash or hang upon opening
- Fix: Issue with tab bar sizing
- Fix: Issue with “import type by GUID”
- Fix: Issue(s) with copying the text of an opcode token
- Fix: Issue where installing package dependencies could fail
- Fix: Memory leak in Type Archives
- Fix: Issue causing type dialog to be unresponsive when large number of types are in use
- Fix: Crash when using “Create Array” on undefined bytes in a structure
- Fix: Bug with
create struct members referenced
- Fix: Bug in type propagation when accessing members of stack structures
- Fix: Crash on progress cancel when opening a database
- Fix: Crash when using LLDB adapter on Windows in free version
- Fix: Bug causing loss of type information when duplicating expressions in HLIL
- Fix: Bug causing non-deterministic application of PDB debug information
- Fix: Issue were ARM ELF mapping symbols could be defined as actual symbols
- Fix: Issue where creating an array could overlap function boundaries
- Fix: Crash while saving under some conditions
- Fix: Display of possible values in UIDF dialog
- Fix: Edge case setting UIDF value in mlil-ssa
- Fix: Display of constant intermediate values
- Fix: Crash in CreateArrayDialog
- Fix: Issue causing ‘Append Field’ action to not show up in type editor
- Fix: Location resetting when changing options in graph view
- Fix: Potential crash when opening a BNDB with external links
- Fix: Issue with focusing the Command Palette on some Linux distributions
- Fix: Crash on latest Fedora
- Fix: Crash when analyzing some binaries
- Fix: Crash when adding tags to cross references
- Fix: search/find dialog does not trim the input string
- Fix: Symbols list search now uses AND rather than OR for search terms
- Fix: Hang when selecting “clear variable type” from variables sidebar
- Fix: Issue where the description of a project wasn’t being set
- Fix: Non-deterministic application of PDB type information
- Fix: Issue preventing “Call Type Override” from working on imported symbols
- Fix: Issue preventing the display of types after saving a database
- Fix: Issue causing DataVariables to infer the wrong type
- Fix: Issue preventing case labels from showing up in disassembly blocks
- Fix: Issue where empty lines could show up when filtering items in the symbols list
- Fix: Crash when quickly cancelling remote SSO authentication
- Fix: Issue on macos where progress dialog wouldn’t make progress without UI interaction
- Fix: Issue preventing installation of some plugins on systems with non-ascii paths
- Fix: Some HLIL cross references appeared to be duplicates
- Fix: Python console magic variables for lifted_il, mmlil, mmlil_ssa
- Fix: Bug where certain cross references would cease to be navigable in higher IL views
Binary View Improvements
- Feature: Added support for
md1rom
BinaryView - Feature: PE view now parses the resource section
- Improvement: Unnamed functions pointed to by the .init_array/.fini_array/.ctors/.dtors sections now get names indicating this fact
- Fix: Issue with how
guardCFCheckFunctionPointer
andguardCFDispatchFunctionPointer
were parsed
Analysis
- Feature: Add support for variable width delay slots
- Feature: Automatic recognition of TEB in user mode Windows binaries
- Feature: Add support for binaries with multiple entry points
- Feature: Apply DWARF debug info to stack variables
- Feature: Propagate enumerations to switch case values
- Feature: Add support for local debug directories
- Feature: Add support for __chain_start section parsing in Mach-O binaries
- Feature: Add support for disabling site-specific outlining when full-confidence types are available
- Feature: Fold jump table bounds check into switch statement default case under more conditions
- Feature: Improve Windows Control Flow Guard re-writing
- Feature: Add support for downloading symbols through debuginfod
- Improvement: Enhanced correctness of intrinsic instruction that have memory side-effects
- Improvement: Builtin outlining is more selectively applied
- Improvement: Better recovery of strings in data sections
- Improvement: memcpy outlining heuristic enhancement when considering variable sized writes
- Improvement: Simplify
a&a
,a|a
,a^a
- Improvement: Simplify HLIL conditions of the form
a || (!a && b)
and recognize more if/else constructs - Improvement: Simplify
!(!a && !b) => a || b
and!(!a || !b) => a && b
- Improvement:
FloatToInt(FloatTrunc())
is now simplified to justFloatToInt
- Improvement: Simplify
(x - -10) => (x + 10)
- Improvement:
<condition> ? 1 : 0 == 1
simplified to<condition>
- Improvement: Simplify
A << 0
andA >> 0
toA
- Improvement: Simplify
A >> N >> M
andA << N << M
toA <</>> (N + M)
- Improvement: Simplify
RCR X, 1, 0
toX >> 1
- Improvement: Large c++ template simplifier performance improvement
- Improvement: Large performance improvement in applying DWARF debug info
- Improvement: Large PDB parsing performance improvements
- Improvement: Clearer auto-generated type definitions
- Improvement: Load all types from DWARF even if they are unused
- Improvement: Better stack string recovery
- Improvement: Better definitions for NT_TIB and things that reference it
- Fix: Rendering of floor, ceil, fsqrt, ftrunc, and fabs functions in Pseudo-C
- Fix: partial value calculation for signed ranges with step != 1
- Fix: Rare duplicate goto labels in HLIL
- Fix: Crash when
MarkLabel
is not called as required - Fix: Handling of compressed debug sections in 32-bit ELFs
- Fix: Issue when rebasing Objective-C binaries
- Fix: Issue preventing functions from updating when structures they reference change
- Fix: Issue where databases with workflow_objc enabled would occasionally reanalyze after being reopened
- Fix: Issue with rebasing in relation to applying DWARF debug info
- Fix: Issue with handling of split registers
- Fix: Crash whenever legacy databases were missing type information expected by Objective-C Call rewrites
- Fix: Issue where constant pointers to structures didn’t resolve as intended
- Fix: Issue where blank lines would show up as the same address as the function itself
- Fix: Some issues 1 with global pointer value discovery effecting dataflow
- Fix: Hang when simplifying some array dereferences
- Fix: Escaping of utf-8 encoded strings
API
- Feature: Add additional python apis for opening and closing projects
- Feature:
uiSelectionAction
setting type is a setting type that can present a file picker or trigger an action - Feature: based pointer support
- Feature: Added platform callback to allow specification of type parser arguments
- Improvement: Improved
traverse
API to support shallow traversal - Fix:
get_functions_by_name
when platform is passed - New API: Additional NotificationDispatcher APIs added
- New API: BinaryReader.TryReadPointer
- New API: BinaryDataNotifications for undo actions
- New API: BNCustomPlatform
- New API: BaseAddressDetection
- New API:
Platform::GetGlobalRegsiters
&Platform::GetGlobalRegisterType
- New API:
BinaryView::AddToEntryFunctions
- New API:
BinaryView::GetAllEntryFunctions
- New API: Python methods for getting/setting default calling convention
- New API: Create your own magic python variables
- New API:
get_expr
,copy_expr
,raw_operands
,get_expr_count
- New API:
ILIsCFGProtected
attribute on CFG and XFG Calls in Windows binaries - New API:
getThemeHighlightColor
- Deprecated:
loader.architecture
in favor ofloader.platform
Architecture & Platform
- Feature: Added architecture detection support for RISC-V 32-bit (rv32gc) and RISC-V 64-bit (rv64gc)
- Improvement: Aarch64: complete review of intrinsics: 179 instruction encodings newly lifted, 169 as intrinsics, and 39 converted from intrinsics to direct lifting
- Improvement: x86 Enhanced lifting for
movd
andmovq
instructions - Improvement: PowerPC: added lifting for:
EXTSW
LD
LDU
LDUX
LDX
SLD
SRAD
SRADI
SRD
STD
STDU
STDUX
STDX
instructions - Improvement: add lifting for
scvtf
, scalar integer/float variants - Improvement: Updated x86 architecture to use XED v2024.04.01
- Improvement: Recognize uClibc MIPS ELF PLT entries
- Improvement: Added additional arm system registers
- Fix: RISC-V instructions
CSRRW/CSRRS/CSRRC
- Fix: AArch64
LDP/LDNP/LDPSW
lifting edge cases - Fix: AArch64 lifting for
LDADD*
andSTADD*
family of instructions - Fix: Issue where some obfuscated ELF binaries could be detected as little endian
- Fix: Issue with post index of PC
Debugger
- Feature: Support for windows dump files
- Feature: Added TTD buttons in the debugger sidebar for reverse go/step into/step over
- Feature: Support installing WinDbg and making a TTD recording directly from within the debugger
- Feature: Added reverse debugging APIs
- Feature: Use the MemoryMap API to represent the memory regions for the debugger. Do not lose analysis after debugging
- Improvement: Debugger now avoids excessive analysis updates which improves performance when stepping through code
- Improvement: Massive performance improvement while debugging on Windows
- Fix: Not rebasing the input view during headless usage
- Fix: Issue with navigating while using the debugger
- Fix: Ensure not to hide the console window of the running process on Windows
- Fix: Out-of-state when the user kills the process while it is running
- Fix: Various issues ([1], [2]) when using the debugger in the free version
- Fix: debugging arm64e files on macOS now works
Enterprise
- Feature: Complete refactor of the entire collaboration system, immediate benefits include performance improvements, enables many other future enhancements
- Improvement: Overhauled entire first-run process, which now more gracefully handles specifying your license server and/or named license
- Improvement: Merged all client documentation into our user documentation
- Fix: No longer fail silently if your license server is an invalid host or protocol
- Fix: Can now properly resize the columns in the Remote Dialog
- Fix: Properly pass file events through the license checkout process (double-clicking a file now works if you need to check out a license while starting the client)
- Fix: Can now delete a type archive in a remote project on Windows
- Fix: Python API
remote.connect
now properly checks environment variables for credentials - Fix: Python API
request_authentication_token
now returns values other thanNone
- Fix: Using an external link to navigate to a file that does not exist in the local project cache no longer requires a client restart
- Fix: Users no longer stay in the User Positions list after they have closed the file
- Fix: A series of errors during merge conflicts arising from a bad
any_cast
of a string
Documentation
- Feature: Added Triage documentation, including new BASE feature
- Feature: Added BinaryView to concepts documentation
- Improvement: Documentation on Intel CPU bug in troubleshooting
- Improvement: Debug Info section includes how to prevent it from applying (and now has a screenshot)
- Improvement: Updated Walking ILs concept section
- Improvement: Compression on images for space-savings
- Improvement: Better highlighting for search results in user documentation
Miscellaneous Notes
- All the architecture and view plugins have been moved from individual repos to binaryninja-api 🚝 #Mono-repo-4-lyfe 🚝
- New Open Source: Our PDB Plugin! 🦀
- End of life: We are have dropped for Ubuntu 20.04. 4.1 will support Ubuntu 22.04 and 24.04.
- End of life: We have dropped support for Python 3.8. Python 3.9 is now the oldest supported version.
…and, of course, all the usual “many miscellaneous crashes and fixes” not explicitly listed here. Check them out in our full milestone list: https://github.com/Vector35/binaryninja-api/milestone/19?closed=1