summaryrefslogtreecommitdiff
path: root/plugins/warp/src/plugin/render_layer.rs
blob: 3417c9b1c828b70636b77d9b69e0ca0c960ddca4 (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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::{
    filtered_instructions_at, is_blacklisted_instruction, is_computed_variant_instruction,
    is_variant_instruction, relocatable_regions,
};
use binaryninja::basic_block::BasicBlock;
use binaryninja::disassembly::DisassemblyTextLine;
use binaryninja::flowgraph::FlowGraph;
use binaryninja::function::{HighlightColor, HighlightStandardColor, NativeBlock};
use binaryninja::low_level_il::LowLevelILRegularFunction;
use binaryninja::render_layer::{register_render_layer, RenderLayer};

// TODO: Add a render layer to show basic block GUID's?
// TODO: Add a render layer to show constraints for current function?

pub struct HighlightRenderLayer {
    blacklist: HighlightColor,
    variant: HighlightColor,
    computed_variant: HighlightColor,
}

impl HighlightRenderLayer {
    pub fn register() {
        register_render_layer(
            "WARP Highlight Layer",
            // TODO: Make the highlight colors configurable.
            HighlightRenderLayer {
                blacklist: HighlightColor::StandardHighlightColor {
                    color: HighlightStandardColor::BlackHighlightColor,
                    alpha: 155,
                },
                variant: HighlightColor::StandardHighlightColor {
                    color: HighlightStandardColor::RedHighlightColor,
                    alpha: 155,
                },
                computed_variant: HighlightColor::StandardHighlightColor {
                    color: HighlightStandardColor::OrangeHighlightColor,
                    alpha: 155,
                },
            },
            Default::default(),
        );
    }

    /// Highlights the lines that are variant or blacklisted.
    pub fn highlight_lines(
        &self,
        lifted_il: &LowLevelILRegularFunction,
        llil: &LowLevelILRegularFunction,
        lines: &mut [DisassemblyTextLine],
    ) {
        let Some(owner_function) = lifted_il.function() else {
            return;
        };

        let relocatable_regions = relocatable_regions(&owner_function.view());
        for line in lines {
            // We use address here instead of index since it's more reliable for other IL's.
            for lifted_il_instr in filtered_instructions_at(lifted_il, line.address) {
                if is_blacklisted_instruction(&lifted_il_instr) {
                    line.highlight = self.blacklist;
                } else if is_variant_instruction(&relocatable_regions, &lifted_il_instr) {
                    line.highlight = self.variant;
                }
            }

            for llil_instr in filtered_instructions_at(llil, line.address) {
                if is_computed_variant_instruction(&relocatable_regions, &llil_instr) {
                    line.highlight = self.computed_variant;
                }
            }
        }
    }
}

impl RenderLayer for HighlightRenderLayer {
    fn apply_to_flow_graph(&self, graph: &mut FlowGraph) {
        if let (Some(lifted_il), Some(llil)) = (graph.lifted_il(), graph.low_level_il()) {
            for node in &graph.nodes() {
                let mut new_lines = node.lines().to_vec();
                self.highlight_lines(&lifted_il, &llil, &mut new_lines);
                node.set_lines(new_lines);
            }
        }
    }

    fn apply_to_block(
        &self,
        block: &BasicBlock<NativeBlock>,
        mut lines: Vec<DisassemblyTextLine>,
    ) -> Vec<DisassemblyTextLine> {
        // Highlight any instruction that WARP will mask.
        let function = block.function();
        if let (Some(lifted_il), Some(llil)) = (
            function.lifted_il_if_available(),
            function.low_level_il_if_available(),
        ) {
            self.highlight_lines(&lifted_il, &llil, &mut lines);
        }
        lines
    }
}