Enums Just Got So Much Better in Binary Ninja

Enums in Binary Ninja have always been nice, but they are even better in the latest 4.3 update.

Binary Ninja correctly showing the enumeration bit mask flags.
Bitmask flags are certainly more readable.

In late November 2024, I made a post in the Binary Ninja Slack channel lamenting how enums are shown in the intermediate language. If you didn't know, in Binary Ninja, you can have constant values displayed as their enum variable names. This general aids readability of the decompiled program. However, this broke down a little bit when the enum contained a variable assigned to zero.

Why? The zero case is always matched. So in a bitfield mask, the zero case is always shown. Consider a Boolean value.

enum Bool : uint8_t
{
    YES = 0x1,
    NO  = 0x0
};

When a constant, clearly boolean value, is set to this structure in Binary Ninja, it will only ever show NO or YES | NO, as shown in this example.

A HLIL expression in Binary Ninja showing YES | NO.
A boolean in Binary Ninja.

As RevPanda on the GitHub issue correctly points out, this syntax is technically correct. Anything OR'ed with the zero'ed value will always be the true value. But it's meaningless information. In scenarios where a single line of HLIL contains numerous enum fields, it gets quite messy.

However, in the latest version of Binary Ninja, on the development build of 4.3, this has been fixed.

Let's consider the following Objective-C program. It just accepts an input (string or number) and displays the bool value.

#import <Foundation/Foundation.h>
#import <stdio.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        if (argc != 2) {
            NSLog(@"Usage: program_name <input>");
            return EXIT_FAILURE;
        }
        
        /* Get the input number */
        NSString * input = [NSString stringWithUTF8String:argv[1]];
        NSNumber * number = @([input intValue]);
        
        /* Get the boolean value. */
        BOOL flag = [number boolValue];
        NSLog(@"The boolean value is %@.", flag ? @"YES" : @"NO");
    }
    return EXIT_SUCCESS;
}

If we compile without optimizations, define an enum as shown above, and set the constant to that enum, we get the following.

HLIL in Binary Ninja that checks a boolean value.
Binary Ninja 4.2.x showing both enum values.

Notice how we see YES | NO? Ew. But 4.3.x fixes this.

Another piece of HLIL in Binary Ninja that checks a boolean value.
Binary Ninja 4.3.x showing just one of the enum values.

Far more readable.

Thanks to the Binja team for quickly adding this feature. Cheers!

Subscribe to Sean Deaton

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe