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
}
}
|