1use super::{SimilarityAnnotationType, SimilarityEntityRef, SimilarityViewType};
2use crate::binary_view::BinaryView;
3use crate::flowgraph::FlowGraph;
4use crate::function::{Function, FunctionViewType};
5use crate::linear_view::LinearViewObject;
6use crate::rc::{Ref, RefCountable};
7use crate::string::{BnString, IntoCStr};
8use binaryninjacore_sys::*;
9
10pub struct SimilarityView {
12 pub group: String,
14 pub view_type: SimilarityViewType,
16 pub graph: Option<Ref<FlowGraph>>,
18 pub data: Option<Ref<BinaryView>>,
20 pub linear_view: Option<Ref<LinearViewObject>>,
22 pub entity: Option<SimilarityEntityRef>,
24}
25
26#[derive(Debug, Copy, Clone, PartialEq, Eq)]
28pub struct SimilarityRangeAnnotation {
29 pub start: u64,
30 pub end: u64,
31 pub annotation_type: SimilarityAnnotationType,
32}
33
34pub struct SimilarityRenderContext {
36 pub(crate) handle: *mut BNSimilarityRenderContext,
37}
38
39impl SimilarityRenderContext {
40 pub fn new() -> Ref<Self> {
42 unsafe { Self::ref_from_raw(BNCreateSimilarityRenderContext()) }
43 }
44
45 pub unsafe fn from_raw(handle: *mut BNSimilarityRenderContext) -> Self {
46 Self { handle }
47 }
48
49 pub unsafe fn ref_from_raw(handle: *mut BNSimilarityRenderContext) -> Ref<Self> {
50 Ref::new(Self { handle })
51 }
52
53 pub fn set_preferred_view_type(&self, view_type: FunctionViewType) {
55 let raw = FunctionViewType::into_raw(view_type);
56 unsafe { BNSimilarityRenderContextSetPreferredViewType(self.handle, raw) };
57 FunctionViewType::free_raw(raw);
58 }
59
60 pub fn preferred_view_type(&self) -> FunctionViewType {
62 let type_ = unsafe { BNSimilarityRenderContextGetPreferredViewType(self.handle) };
63 let name = if type_ == BNFunctionGraphType::HighLevelLanguageRepresentationFunctionGraph {
64 unsafe { BNSimilarityRenderContextGetPreferredViewTypeName(self.handle) }
65 } else {
66 std::ptr::null_mut()
67 };
68 FunctionViewType::from_owned_raw(BNFunctionViewType { type_, name }).unwrap()
69 }
70
71 pub fn add_flow_graph(&self, group: &str, graph: &FlowGraph) {
73 let group = group.to_cstr();
74 unsafe { BNSimilarityRenderContextAddFlowGraph(self.handle, group.as_ptr(), graph.handle) }
75 }
76
77 pub fn add_flow_graph_for_entity(
79 &self,
80 group: &str,
81 graph: &FlowGraph,
82 entity: SimilarityEntityRef,
83 ) {
84 let group = group.to_cstr();
85 let entity = BNSimilarityEntityRef::from(entity);
86 unsafe {
87 BNSimilarityRenderContextAddFlowGraphForEntity(
88 self.handle,
89 group.as_ptr(),
90 graph.handle,
91 &entity,
92 )
93 }
94 }
95
96 pub fn add_linear_view(&self, group: &str, data: &BinaryView, linear_view: &LinearViewObject) {
98 let group = group.to_cstr();
99 unsafe {
100 BNSimilarityRenderContextAddLinearView(
101 self.handle,
102 group.as_ptr(),
103 data.handle,
104 linear_view.handle,
105 )
106 }
107 }
108
109 pub fn add_linear_view_for_entity(
111 &self,
112 group: &str,
113 data: &BinaryView,
114 linear_view: &LinearViewObject,
115 entity: SimilarityEntityRef,
116 ) {
117 let group = group.to_cstr();
118 let entity = BNSimilarityEntityRef::from(entity);
119 unsafe {
120 BNSimilarityRenderContextAddLinearViewForEntity(
121 self.handle,
122 group.as_ptr(),
123 data.handle,
124 linear_view.handle,
125 &entity,
126 )
127 }
128 }
129
130 pub fn views(&self) -> Vec<SimilarityView> {
132 let mut count = 0;
133 let raw = unsafe { BNGetSimilarityRenderContextViews(self.handle, &mut count) };
134 let views = unsafe { std::slice::from_raw_parts(raw, count) };
135 let result = views
136 .iter()
137 .map(|view| {
138 let view = *view;
139 let graph = unsafe { BNSimilarityViewGetFlowGraph(view) };
140 let data = unsafe { BNSimilarityViewGetLinearViewData(view) };
141 let linear_view = unsafe { BNSimilarityViewGetLinearView(view) };
142 let mut entity = std::mem::MaybeUninit::uninit();
143 let entity = unsafe { BNSimilarityViewGetEntity(view, entity.as_mut_ptr()) }
144 .then(|| unsafe { entity.assume_init().into() });
145 SimilarityView {
146 group: unsafe { BnString::into_string(BNSimilarityViewGetGroup(view)) },
147 view_type: unsafe { BNSimilarityViewGetType(view) },
148 graph: (!graph.is_null()).then(|| unsafe { FlowGraph::ref_from_raw(graph) }),
149 data: (!data.is_null()).then(|| unsafe { BinaryView::ref_from_raw(data) }),
150 linear_view: (!linear_view.is_null())
151 .then(|| unsafe { LinearViewObject::ref_from_raw(linear_view) }),
152 entity,
153 }
154 })
155 .collect();
156 unsafe { BNFreeSimilarityViewList(raw, count) };
157 result
158 }
159}
160
161impl ToOwned for SimilarityRenderContext {
162 type Owned = Ref<Self>;
163
164 fn to_owned(&self) -> Self::Owned {
165 unsafe { RefCountable::inc_ref(self) }
166 }
167}
168
169unsafe impl RefCountable for SimilarityRenderContext {
170 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
171 Ref::new(Self {
172 handle: BNNewSimilarityRenderContextReference(handle.handle),
173 })
174 }
175
176 unsafe fn dec_ref(handle: &Self) {
177 BNFreeSimilarityRenderContext(handle.handle)
178 }
179}
180
181pub struct DiffRenderer {
183 handle: *mut BNDiffRenderer,
184}
185
186impl DiffRenderer {
187 pub fn new() -> Ref<Self> {
189 unsafe {
190 Ref::new(Self {
191 handle: BNCreateDiffRenderer(),
192 })
193 }
194 }
195
196 pub fn add_range_annotation(&self, annotation: SimilarityRangeAnnotation) {
200 unsafe {
201 BNDiffRendererAddRangeAnnotation(
202 self.handle,
203 annotation.start,
204 annotation.end,
205 annotation.annotation_type,
206 )
207 }
208 }
209
210 pub fn render_function(&self, context: &SimilarityRenderContext, function: &Function) {
212 unsafe { BNDiffRendererRenderFunction(self.handle, context.handle, function.handle) }
213 }
214
215 pub fn render_function_for_entity(
217 &self,
218 context: &SimilarityRenderContext,
219 function: &Function,
220 entity: SimilarityEntityRef,
221 ) {
222 let entity = BNSimilarityEntityRef::from(entity);
223 unsafe {
224 BNDiffRendererRenderFunctionForEntity(
225 self.handle,
226 context.handle,
227 function.handle,
228 &entity,
229 )
230 }
231 }
232
233 pub fn render_flow_graph(
235 &self,
236 context: &SimilarityRenderContext,
237 group: &str,
238 graph: &FlowGraph,
239 ) {
240 let group = group.to_cstr();
241 unsafe {
242 BNDiffRendererRenderFlowGraph(self.handle, context.handle, group.as_ptr(), graph.handle)
243 }
244 }
245
246 pub fn render_flow_graph_for_entity(
248 &self,
249 context: &SimilarityRenderContext,
250 group: &str,
251 graph: &FlowGraph,
252 entity: SimilarityEntityRef,
253 ) {
254 let group = group.to_cstr();
255 let entity = BNSimilarityEntityRef::from(entity);
256 unsafe {
257 BNDiffRendererRenderFlowGraphForEntity(
258 self.handle,
259 context.handle,
260 group.as_ptr(),
261 graph.handle,
262 &entity,
263 )
264 }
265 }
266
267 pub fn render_linear_view(
269 &self,
270 context: &SimilarityRenderContext,
271 group: &str,
272 data: &BinaryView,
273 linear_view: &LinearViewObject,
274 ) {
275 let group = group.to_cstr();
276 unsafe {
277 BNDiffRendererRenderLinearView(
278 self.handle,
279 context.handle,
280 group.as_ptr(),
281 data.handle,
282 linear_view.handle,
283 )
284 }
285 }
286
287 pub fn render_linear_view_for_entity(
289 &self,
290 context: &SimilarityRenderContext,
291 group: &str,
292 data: &BinaryView,
293 linear_view: &LinearViewObject,
294 entity: SimilarityEntityRef,
295 ) {
296 let group = group.to_cstr();
297 let entity = BNSimilarityEntityRef::from(entity);
298 unsafe {
299 BNDiffRendererRenderLinearViewForEntity(
300 self.handle,
301 context.handle,
302 group.as_ptr(),
303 data.handle,
304 linear_view.handle,
305 &entity,
306 )
307 }
308 }
309}
310
311impl ToOwned for DiffRenderer {
312 type Owned = Ref<Self>;
313
314 fn to_owned(&self) -> Self::Owned {
315 unsafe { RefCountable::inc_ref(self) }
316 }
317}
318
319unsafe impl RefCountable for DiffRenderer {
320 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
321 Ref::new(Self {
322 handle: BNNewDiffRendererReference(handle.handle),
323 })
324 }
325
326 unsafe fn dec_ref(handle: &Self) {
327 BNFreeDiffRenderer(handle.handle)
328 }
329}