summaryrefslogtreecommitdiff
path: root/python/examples/bid64_constant.py
blob: d5f49ccd48d6be9ed4ca8fdaa9820085a955abca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# This plugin renders 64-bit binary integer decimal floating point constants directly in the
# decompilation. See the sample binary at `examples/bid64_constant/sample_binary` for an
# example of a binary that uses this unusual format.

from binaryninja import (ConstantRenderer, InstructionTextToken, InstructionTextTokenType, IntegerType)
from decimal import Decimal


class Bid64ConstantRenderer(ConstantRenderer):
    renderer_name = "bid64_constant"

    def render_constant(self, instr, type, val, tokens, settings, precedence):
        # Typedefs have the final type, so make sure it is a 64 bit integer. The registered name
        # should be the typedef "BID_UINT64".
        if not isinstance(type, IntegerType):
            return False
        if type.width != 8:
            return False
        if type.registered_name is None or type.registered_name.name != 'BID_UINT64':
            return False

        sign = (val & (1 << 63)) != 0
        raw_exponent = (val >> 53) & 0x3ff
        if raw_exponent >= 0x300:
            # Don't try and render NaN or infinity
            return False

        bias = 398
        exponent = raw_exponent - bias
        magnitude = val & ((1 << 53) - 1)

        if magnitude == 0:
            exponent = 0

        value = Decimal(magnitude) * Decimal(10.0) ** Decimal(exponent)
        if sign:
            value = -value
        tokens.append(InstructionTextToken(InstructionTextTokenType.FloatingPointToken, str(value) + "_bid"))
        return True


Bid64ConstantRenderer().register()