1use binaryninjacore_sys::*;
2use std::fmt;
3use std::fmt::{Debug, Display, Formatter};
4
5use super::operation::*;
6use super::{HighLevelILFunction, HighLevelILLiftedInstruction, HighLevelILLiftedInstructionKind};
7use crate::architecture::{CoreIntrinsic, IntrinsicId};
8use crate::confidence::Conf;
9use crate::disassembly::DisassemblyTextLine;
10use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref};
11use crate::types::Type;
12use crate::variable::{ConstantData, RegisterValue, SSAVariable, Variable};
13
14#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct HighLevelInstructionIndex(pub usize);
16
17impl HighLevelInstructionIndex {
18 pub fn next(&self) -> Self {
19 Self(self.0 + 1)
20 }
21}
22
23impl From<usize> for HighLevelInstructionIndex {
24 fn from(index: usize) -> Self {
25 Self(index)
26 }
27}
28
29impl From<u64> for HighLevelInstructionIndex {
30 fn from(index: u64) -> Self {
31 Self(index as usize)
32 }
33}
34
35impl Display for HighLevelInstructionIndex {
36 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
37 f.write_fmt(format_args!("{}", self.0))
38 }
39}
40
41#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub struct HighLevelExpressionIndex(pub usize);
43
44impl HighLevelExpressionIndex {
45 pub fn next(&self) -> Self {
46 Self(self.0 + 1)
47 }
48}
49
50impl From<usize> for HighLevelExpressionIndex {
51 fn from(index: usize) -> Self {
52 Self(index)
53 }
54}
55
56impl From<u64> for HighLevelExpressionIndex {
57 fn from(index: u64) -> Self {
58 Self(index as usize)
59 }
60}
61
62impl Display for HighLevelExpressionIndex {
63 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
64 f.write_fmt(format_args!("{}", self.0))
65 }
66}
67
68#[derive(Clone)]
69pub struct HighLevelILInstruction {
70 pub function: Ref<HighLevelILFunction>,
71 pub address: u64,
72 pub instr_index: HighLevelInstructionIndex,
73 pub expr_index: HighLevelExpressionIndex,
74 pub size: usize,
75 pub kind: HighLevelILInstructionKind,
76}
77
78impl HighLevelILInstruction {
79 pub(crate) fn from_instr_index(
80 function: Ref<HighLevelILFunction>,
81 instr_index: HighLevelInstructionIndex,
82 ) -> Self {
83 let expr_index_raw =
85 unsafe { BNGetHighLevelILIndexForInstruction(function.handle, instr_index.0) };
86 Self::new(
87 function,
88 instr_index,
89 HighLevelExpressionIndex(expr_index_raw),
90 )
91 }
92
93 pub(crate) fn from_expr_index(
94 function: Ref<HighLevelILFunction>,
95 expr_index: HighLevelExpressionIndex,
96 ) -> Self {
97 let instr_index_raw =
99 unsafe { BNGetHighLevelILInstructionForExpr(function.handle, expr_index.0) };
100 Self::new(
101 function,
102 HighLevelInstructionIndex(instr_index_raw),
103 expr_index,
104 )
105 }
106
107 pub(crate) fn new(
108 function: Ref<HighLevelILFunction>,
109 instr_index: HighLevelInstructionIndex,
110 expr_index: HighLevelExpressionIndex,
111 ) -> Self {
112 let op =
113 unsafe { BNGetHighLevelILByIndex(function.handle, expr_index.0, function.full_ast) };
114 use BNHighLevelILOperation::*;
115 use HighLevelILInstructionKind as Op;
116 let kind = match op.operation {
117 HLIL_NOP => Op::Nop,
118 HLIL_BREAK => Op::Break,
119 HLIL_CONTINUE => Op::Continue,
120 HLIL_NORET => Op::Noret,
121 HLIL_UNREACHABLE => Op::Unreachable,
122 HLIL_BP => Op::Bp,
123 HLIL_UNDEF => Op::Undef,
124 HLIL_FORCE_VER | HLIL_FORCE_VER_SSA | HLIL_ASSERT | HLIL_ASSERT_SSA => Op::Undef,
125 HLIL_UNIMPL => Op::Unimpl,
126 HLIL_ADC => Op::Adc(BinaryOpCarry {
127 left: HighLevelExpressionIndex::from(op.operands[0]),
128 right: HighLevelExpressionIndex::from(op.operands[1]),
129 carry: HighLevelExpressionIndex::from(op.operands[2]),
130 }),
131 HLIL_SBB => Op::Sbb(BinaryOpCarry {
132 left: HighLevelExpressionIndex::from(op.operands[0]),
133 right: HighLevelExpressionIndex::from(op.operands[1]),
134 carry: HighLevelExpressionIndex::from(op.operands[2]),
135 }),
136 HLIL_RLC => Op::Rlc(BinaryOpCarry {
137 left: HighLevelExpressionIndex::from(op.operands[0]),
138 right: HighLevelExpressionIndex::from(op.operands[1]),
139 carry: HighLevelExpressionIndex::from(op.operands[2]),
140 }),
141 HLIL_RRC => Op::Rrc(BinaryOpCarry {
142 left: HighLevelExpressionIndex::from(op.operands[0]),
143 right: HighLevelExpressionIndex::from(op.operands[1]),
144 carry: HighLevelExpressionIndex::from(op.operands[2]),
145 }),
146 HLIL_ADD => Op::Add(BinaryOp {
147 left: HighLevelExpressionIndex::from(op.operands[0]),
148 right: HighLevelExpressionIndex::from(op.operands[1]),
149 }),
150 HLIL_SUB => Op::Sub(BinaryOp {
151 left: HighLevelExpressionIndex::from(op.operands[0]),
152 right: HighLevelExpressionIndex::from(op.operands[1]),
153 }),
154 HLIL_AND => Op::And(BinaryOp {
155 left: HighLevelExpressionIndex::from(op.operands[0]),
156 right: HighLevelExpressionIndex::from(op.operands[1]),
157 }),
158 HLIL_OR => Op::Or(BinaryOp {
159 left: HighLevelExpressionIndex::from(op.operands[0]),
160 right: HighLevelExpressionIndex::from(op.operands[1]),
161 }),
162 HLIL_XOR => Op::Xor(BinaryOp {
163 left: HighLevelExpressionIndex::from(op.operands[0]),
164 right: HighLevelExpressionIndex::from(op.operands[1]),
165 }),
166 HLIL_LSL => Op::Lsl(BinaryOp {
167 left: HighLevelExpressionIndex::from(op.operands[0]),
168 right: HighLevelExpressionIndex::from(op.operands[1]),
169 }),
170 HLIL_LSR => Op::Lsr(BinaryOp {
171 left: HighLevelExpressionIndex::from(op.operands[0]),
172 right: HighLevelExpressionIndex::from(op.operands[1]),
173 }),
174 HLIL_ASR => Op::Asr(BinaryOp {
175 left: HighLevelExpressionIndex::from(op.operands[0]),
176 right: HighLevelExpressionIndex::from(op.operands[1]),
177 }),
178 HLIL_ROL => Op::Rol(BinaryOp {
179 left: HighLevelExpressionIndex::from(op.operands[0]),
180 right: HighLevelExpressionIndex::from(op.operands[1]),
181 }),
182 HLIL_ROR => Op::Ror(BinaryOp {
183 left: HighLevelExpressionIndex::from(op.operands[0]),
184 right: HighLevelExpressionIndex::from(op.operands[1]),
185 }),
186 HLIL_MUL => Op::Mul(BinaryOp {
187 left: HighLevelExpressionIndex::from(op.operands[0]),
188 right: HighLevelExpressionIndex::from(op.operands[1]),
189 }),
190 HLIL_MULU_DP => Op::MuluDp(BinaryOp {
191 left: HighLevelExpressionIndex::from(op.operands[0]),
192 right: HighLevelExpressionIndex::from(op.operands[1]),
193 }),
194 HLIL_MULS_DP => Op::MulsDp(BinaryOp {
195 left: HighLevelExpressionIndex::from(op.operands[0]),
196 right: HighLevelExpressionIndex::from(op.operands[1]),
197 }),
198 HLIL_DIVU => Op::Divu(BinaryOp {
199 left: HighLevelExpressionIndex::from(op.operands[0]),
200 right: HighLevelExpressionIndex::from(op.operands[1]),
201 }),
202 HLIL_DIVU_DP => Op::DivuDp(BinaryOp {
203 left: HighLevelExpressionIndex::from(op.operands[0]),
204 right: HighLevelExpressionIndex::from(op.operands[1]),
205 }),
206 HLIL_DIVS => Op::Divs(BinaryOp {
207 left: HighLevelExpressionIndex::from(op.operands[0]),
208 right: HighLevelExpressionIndex::from(op.operands[1]),
209 }),
210 HLIL_DIVS_DP => Op::DivsDp(BinaryOp {
211 left: HighLevelExpressionIndex::from(op.operands[0]),
212 right: HighLevelExpressionIndex::from(op.operands[1]),
213 }),
214 HLIL_MODU => Op::Modu(BinaryOp {
215 left: HighLevelExpressionIndex::from(op.operands[0]),
216 right: HighLevelExpressionIndex::from(op.operands[1]),
217 }),
218 HLIL_MODU_DP => Op::ModuDp(BinaryOp {
219 left: HighLevelExpressionIndex::from(op.operands[0]),
220 right: HighLevelExpressionIndex::from(op.operands[1]),
221 }),
222 HLIL_MODS => Op::Mods(BinaryOp {
223 left: HighLevelExpressionIndex::from(op.operands[0]),
224 right: HighLevelExpressionIndex::from(op.operands[1]),
225 }),
226 HLIL_MODS_DP => Op::ModsDp(BinaryOp {
227 left: HighLevelExpressionIndex::from(op.operands[0]),
228 right: HighLevelExpressionIndex::from(op.operands[1]),
229 }),
230 HLIL_MINS => Op::MinSigned(BinaryOp {
231 left: HighLevelExpressionIndex::from(op.operands[0]),
232 right: HighLevelExpressionIndex::from(op.operands[1]),
233 }),
234 HLIL_MAXS => Op::MaxSigned(BinaryOp {
235 left: HighLevelExpressionIndex::from(op.operands[0]),
236 right: HighLevelExpressionIndex::from(op.operands[1]),
237 }),
238 HLIL_MINU => Op::MinUnsigned(BinaryOp {
239 left: HighLevelExpressionIndex::from(op.operands[0]),
240 right: HighLevelExpressionIndex::from(op.operands[1]),
241 }),
242 HLIL_MAXU => Op::MaxUnsigned(BinaryOp {
243 left: HighLevelExpressionIndex::from(op.operands[0]),
244 right: HighLevelExpressionIndex::from(op.operands[1]),
245 }),
246 HLIL_CMP_E => Op::CmpE(BinaryOp {
247 left: HighLevelExpressionIndex::from(op.operands[0]),
248 right: HighLevelExpressionIndex::from(op.operands[1]),
249 }),
250 HLIL_CMP_NE => Op::CmpNe(BinaryOp {
251 left: HighLevelExpressionIndex::from(op.operands[0]),
252 right: HighLevelExpressionIndex::from(op.operands[1]),
253 }),
254 HLIL_CMP_SLT => Op::CmpSlt(BinaryOp {
255 left: HighLevelExpressionIndex::from(op.operands[0]),
256 right: HighLevelExpressionIndex::from(op.operands[1]),
257 }),
258 HLIL_CMP_ULT => Op::CmpUlt(BinaryOp {
259 left: HighLevelExpressionIndex::from(op.operands[0]),
260 right: HighLevelExpressionIndex::from(op.operands[1]),
261 }),
262 HLIL_CMP_SLE => Op::CmpSle(BinaryOp {
263 left: HighLevelExpressionIndex::from(op.operands[0]),
264 right: HighLevelExpressionIndex::from(op.operands[1]),
265 }),
266 HLIL_CMP_ULE => Op::CmpUle(BinaryOp {
267 left: HighLevelExpressionIndex::from(op.operands[0]),
268 right: HighLevelExpressionIndex::from(op.operands[1]),
269 }),
270 HLIL_CMP_SGE => Op::CmpSge(BinaryOp {
271 left: HighLevelExpressionIndex::from(op.operands[0]),
272 right: HighLevelExpressionIndex::from(op.operands[1]),
273 }),
274 HLIL_CMP_UGE => Op::CmpUge(BinaryOp {
275 left: HighLevelExpressionIndex::from(op.operands[0]),
276 right: HighLevelExpressionIndex::from(op.operands[1]),
277 }),
278 HLIL_CMP_SGT => Op::CmpSgt(BinaryOp {
279 left: HighLevelExpressionIndex::from(op.operands[0]),
280 right: HighLevelExpressionIndex::from(op.operands[1]),
281 }),
282 HLIL_CMP_UGT => Op::CmpUgt(BinaryOp {
283 left: HighLevelExpressionIndex::from(op.operands[0]),
284 right: HighLevelExpressionIndex::from(op.operands[1]),
285 }),
286 HLIL_TEST_BIT => Op::TestBit(BinaryOp {
287 left: HighLevelExpressionIndex::from(op.operands[0]),
288 right: HighLevelExpressionIndex::from(op.operands[1]),
289 }),
290 HLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp {
291 left: HighLevelExpressionIndex::from(op.operands[0]),
292 right: HighLevelExpressionIndex::from(op.operands[1]),
293 }),
294 HLIL_FADD => Op::Fadd(BinaryOp {
295 left: HighLevelExpressionIndex::from(op.operands[0]),
296 right: HighLevelExpressionIndex::from(op.operands[1]),
297 }),
298 HLIL_FSUB => Op::Fsub(BinaryOp {
299 left: HighLevelExpressionIndex::from(op.operands[0]),
300 right: HighLevelExpressionIndex::from(op.operands[1]),
301 }),
302 HLIL_FMUL => Op::Fmul(BinaryOp {
303 left: HighLevelExpressionIndex::from(op.operands[0]),
304 right: HighLevelExpressionIndex::from(op.operands[1]),
305 }),
306 HLIL_FDIV => Op::Fdiv(BinaryOp {
307 left: HighLevelExpressionIndex::from(op.operands[0]),
308 right: HighLevelExpressionIndex::from(op.operands[1]),
309 }),
310 HLIL_FCMP_E => Op::FcmpE(BinaryOp {
311 left: HighLevelExpressionIndex::from(op.operands[0]),
312 right: HighLevelExpressionIndex::from(op.operands[1]),
313 }),
314 HLIL_FCMP_NE => Op::FcmpNe(BinaryOp {
315 left: HighLevelExpressionIndex::from(op.operands[0]),
316 right: HighLevelExpressionIndex::from(op.operands[1]),
317 }),
318 HLIL_FCMP_LT => Op::FcmpLt(BinaryOp {
319 left: HighLevelExpressionIndex::from(op.operands[0]),
320 right: HighLevelExpressionIndex::from(op.operands[1]),
321 }),
322 HLIL_FCMP_LE => Op::FcmpLe(BinaryOp {
323 left: HighLevelExpressionIndex::from(op.operands[0]),
324 right: HighLevelExpressionIndex::from(op.operands[1]),
325 }),
326 HLIL_FCMP_GE => Op::FcmpGe(BinaryOp {
327 left: HighLevelExpressionIndex::from(op.operands[0]),
328 right: HighLevelExpressionIndex::from(op.operands[1]),
329 }),
330 HLIL_FCMP_GT => Op::FcmpGt(BinaryOp {
331 left: HighLevelExpressionIndex::from(op.operands[0]),
332 right: HighLevelExpressionIndex::from(op.operands[1]),
333 }),
334 HLIL_FCMP_O => Op::FcmpO(BinaryOp {
335 left: HighLevelExpressionIndex::from(op.operands[0]),
336 right: HighLevelExpressionIndex::from(op.operands[1]),
337 }),
338 HLIL_FCMP_UO => Op::FcmpUo(BinaryOp {
339 left: HighLevelExpressionIndex::from(op.operands[0]),
340 right: HighLevelExpressionIndex::from(op.operands[1]),
341 }),
342 HLIL_ARRAY_INDEX => Op::ArrayIndex(ArrayIndex {
343 src: HighLevelExpressionIndex::from(op.operands[0]),
344 index: HighLevelExpressionIndex::from(op.operands[1]),
345 }),
346 HLIL_ARRAY_INDEX_SSA => Op::ArrayIndexSsa(ArrayIndexSsa {
347 src: HighLevelExpressionIndex::from(op.operands[0]),
348 src_memory: op.operands[1],
349 index: HighLevelExpressionIndex::from(op.operands[2]),
350 }),
351 HLIL_ASSIGN => Op::Assign(Assign {
352 dest: HighLevelExpressionIndex::from(op.operands[0]),
353 src: HighLevelExpressionIndex::from(op.operands[1]),
354 }),
355 HLIL_ASSIGN_MEM_SSA => Op::AssignMemSsa(AssignMemSsa {
356 dest: HighLevelExpressionIndex::from(op.operands[0]),
357 dest_memory: op.operands[1],
358 src: HighLevelExpressionIndex::from(op.operands[2]),
359 src_memory: op.operands[3],
360 }),
361 HLIL_ASSIGN_UNPACK => Op::AssignUnpack(AssignUnpack {
362 num_dests: op.operands[0] as usize,
363 first_dest: op.operands[1] as usize,
364 src: HighLevelExpressionIndex::from(op.operands[2]),
365 }),
366 HLIL_ASSIGN_UNPACK_MEM_SSA => Op::AssignUnpackMemSsa(AssignUnpackMemSsa {
367 num_dests: op.operands[0] as usize,
368 first_dest: op.operands[1] as usize,
369 dest_memory: op.operands[2],
370 src: HighLevelExpressionIndex::from(op.operands[3]),
371 src_memory: op.operands[4],
372 }),
373 HLIL_BLOCK => Op::Block(Block {
374 num_params: op.operands[0] as usize,
375 first_param: op.operands[1] as usize,
376 }),
377 HLIL_CALL => Op::Call(Call {
378 dest: HighLevelExpressionIndex::from(op.operands[0]),
379 num_params: op.operands[1] as usize,
380 first_param: op.operands[2] as usize,
381 }),
382 HLIL_TAILCALL => Op::Tailcall(Call {
383 dest: HighLevelExpressionIndex::from(op.operands[0]),
384 num_params: op.operands[1] as usize,
385 first_param: op.operands[2] as usize,
386 }),
387 HLIL_CALL_SSA => Op::CallSsa(CallSsa {
388 dest: HighLevelExpressionIndex::from(op.operands[0]),
389 num_params: op.operands[1] as usize,
390 first_param: op.operands[2] as usize,
391 dest_memory: op.operands[3],
392 src_memory: op.operands[4],
393 }),
394 HLIL_CASE => Op::Case(Case {
395 num_values: op.operands[0] as usize,
396 first_value: op.operands[1] as usize,
397 body: HighLevelExpressionIndex::from(op.operands[2]),
398 }),
399 HLIL_CONST => Op::Const(Const {
400 constant: op.operands[0],
401 }),
402 HLIL_CONST_PTR => Op::ConstPtr(Const {
403 constant: op.operands[0],
404 }),
405 HLIL_IMPORT => Op::Import(Const {
406 constant: op.operands[0],
407 }),
408 HLIL_CONST_DATA => Op::ConstData(ConstData {
409 constant_data_kind: op.operands[0] as u32,
410 constant_data_value: op.operands[1] as i64,
411 size: op.size,
412 }),
413 HLIL_DEREF => Op::Deref(UnaryOp {
414 src: HighLevelExpressionIndex::from(op.operands[0]),
415 }),
416 HLIL_ADDRESS_OF => Op::AddressOf(UnaryOp {
417 src: HighLevelExpressionIndex::from(op.operands[0]),
418 }),
419 HLIL_PASS_BY_REF => Op::PassByRef(UnaryOp {
420 src: HighLevelExpressionIndex::from(op.operands[0]),
421 }),
422 HLIL_RETURN_BY_REF => Op::ReturnByRef(UnaryOp {
423 src: HighLevelExpressionIndex::from(op.operands[0]),
424 }),
425 HLIL_NEG => Op::Neg(UnaryOp {
426 src: HighLevelExpressionIndex::from(op.operands[0]),
427 }),
428 HLIL_NOT => Op::Not(UnaryOp {
429 src: HighLevelExpressionIndex::from(op.operands[0]),
430 }),
431 HLIL_BSWAP => Op::Bswap(UnaryOp {
432 src: HighLevelExpressionIndex::from(op.operands[0]),
433 }),
434 HLIL_POPCNT => Op::Popcnt(UnaryOp {
435 src: HighLevelExpressionIndex::from(op.operands[0]),
436 }),
437 HLIL_CLZ => Op::Clz(UnaryOp {
438 src: HighLevelExpressionIndex::from(op.operands[0]),
439 }),
440 HLIL_CTZ => Op::Ctz(UnaryOp {
441 src: HighLevelExpressionIndex::from(op.operands[0]),
442 }),
443 HLIL_RBIT => Op::Rbit(UnaryOp {
444 src: HighLevelExpressionIndex::from(op.operands[0]),
445 }),
446 HLIL_CLS => Op::Cls(UnaryOp {
447 src: HighLevelExpressionIndex::from(op.operands[0]),
448 }),
449 HLIL_ABS => Op::Abs(UnaryOp {
450 src: HighLevelExpressionIndex::from(op.operands[0]),
451 }),
452 HLIL_SX => Op::Sx(UnaryOp {
453 src: HighLevelExpressionIndex::from(op.operands[0]),
454 }),
455 HLIL_ZX => Op::Zx(UnaryOp {
456 src: HighLevelExpressionIndex::from(op.operands[0]),
457 }),
458 HLIL_LOW_PART => Op::LowPart(UnaryOp {
459 src: HighLevelExpressionIndex::from(op.operands[0]),
460 }),
461 HLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp {
462 src: HighLevelExpressionIndex::from(op.operands[0]),
463 }),
464 HLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp {
465 src: HighLevelExpressionIndex::from(op.operands[0]),
466 }),
467 HLIL_FSQRT => Op::Fsqrt(UnaryOp {
468 src: HighLevelExpressionIndex::from(op.operands[0]),
469 }),
470 HLIL_FNEG => Op::Fneg(UnaryOp {
471 src: HighLevelExpressionIndex::from(op.operands[0]),
472 }),
473 HLIL_FABS => Op::Fabs(UnaryOp {
474 src: HighLevelExpressionIndex::from(op.operands[0]),
475 }),
476 HLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp {
477 src: HighLevelExpressionIndex::from(op.operands[0]),
478 }),
479 HLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp {
480 src: HighLevelExpressionIndex::from(op.operands[0]),
481 }),
482 HLIL_FLOAT_CONV => Op::FloatConv(UnaryOp {
483 src: HighLevelExpressionIndex::from(op.operands[0]),
484 }),
485 HLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp {
486 src: HighLevelExpressionIndex::from(op.operands[0]),
487 }),
488 HLIL_FLOOR => Op::Floor(UnaryOp {
489 src: HighLevelExpressionIndex::from(op.operands[0]),
490 }),
491 HLIL_CEIL => Op::Ceil(UnaryOp {
492 src: HighLevelExpressionIndex::from(op.operands[0]),
493 }),
494 HLIL_FTRUNC => Op::Ftrunc(UnaryOp {
495 src: HighLevelExpressionIndex::from(op.operands[0]),
496 }),
497 HLIL_DEREF_FIELD_SSA => Op::DerefFieldSsa(DerefFieldSsa {
498 src: HighLevelExpressionIndex::from(op.operands[0]),
499 src_memory: op.operands[1],
500 offset: op.operands[2],
501 member_index: get_member_index(op.operands[3]),
502 }),
503 HLIL_DEREF_SSA => Op::DerefSsa(DerefSsa {
504 src: HighLevelExpressionIndex::from(op.operands[0]),
505 src_memory: op.operands[1],
506 }),
507 HLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr {
508 constant: op.operands[0],
509 offset: op.operands[1],
510 }),
511 HLIL_FLOAT_CONST => Op::FloatConst(FloatConst {
512 constant: get_float(op.operands[0], op.size),
513 }),
514 HLIL_FOR => Op::For(ForLoop {
515 init: HighLevelExpressionIndex::from(op.operands[0]),
516 condition: HighLevelExpressionIndex::from(op.operands[1]),
517 update: HighLevelExpressionIndex::from(op.operands[2]),
518 body: HighLevelExpressionIndex::from(op.operands[3]),
519 }),
520 HLIL_FOR_SSA => Op::ForSsa(ForLoopSsa {
521 init: HighLevelExpressionIndex::from(op.operands[0]),
522 condition_phi: HighLevelExpressionIndex::from(op.operands[1]),
523 condition: HighLevelExpressionIndex::from(op.operands[2]),
524 update: HighLevelExpressionIndex::from(op.operands[3]),
525 body: HighLevelExpressionIndex::from(op.operands[4]),
526 }),
527 HLIL_GOTO => Op::Goto(Label {
528 target: op.operands[0],
529 }),
530 HLIL_LABEL => Op::Label(Label {
531 target: op.operands[0],
532 }),
533 HLIL_IF => Op::If(If {
534 condition: HighLevelExpressionIndex::from(op.operands[0]),
535 cond_true: HighLevelExpressionIndex::from(op.operands[1]),
536 cond_false: HighLevelExpressionIndex::from(op.operands[2]),
537 }),
538 HLIL_INTRINSIC => Op::Intrinsic(Intrinsic {
539 intrinsic: op.operands[0] as u32,
540 num_params: op.operands[1] as usize,
541 first_param: op.operands[2] as usize,
542 }),
543 HLIL_INTRINSIC_SSA => Op::IntrinsicSsa(IntrinsicSsa {
544 intrinsic: op.operands[0] as u32,
545 num_params: op.operands[1] as usize,
546 first_param: op.operands[2] as usize,
547 dest_memory: op.operands[3],
548 src_memory: op.operands[4],
549 }),
550 HLIL_JUMP => Op::Jump(Jump {
551 dest: HighLevelExpressionIndex::from(op.operands[0]),
552 }),
553 HLIL_MEM_PHI => Op::MemPhi(MemPhi {
554 dest: op.operands[0],
555 num_srcs: op.operands[1] as usize,
556 first_src: op.operands[2] as usize,
557 }),
558 HLIL_RET => Op::Ret(Ret {
559 num_srcs: op.operands[0] as usize,
560 first_src: op.operands[1] as usize,
561 }),
562 HLIL_SPLIT => Op::Split(Split {
563 high: HighLevelExpressionIndex::from(op.operands[0]),
564 low: HighLevelExpressionIndex::from(op.operands[1]),
565 }),
566 HLIL_STRUCT_FIELD => Op::StructField(StructField {
567 src: HighLevelExpressionIndex::from(op.operands[0]),
568 offset: op.operands[1],
569 member_index: get_member_index(op.operands[2]),
570 }),
571 HLIL_DEREF_FIELD => Op::DerefField(StructField {
572 src: HighLevelExpressionIndex::from(op.operands[0]),
573 offset: op.operands[1],
574 member_index: get_member_index(op.operands[2]),
575 }),
576 HLIL_STRUCT_INIT => Op::StructInit(StructInit {
577 num_fields: op.operands[0] as usize,
578 first_field: op.operands[1] as usize,
579 }),
580 HLIL_STRUCT_INIT_FIELD => Op::StructInitField(StructField {
581 offset: op.operands[0],
582 member_index: get_member_index(op.operands[1]),
583 src: HighLevelExpressionIndex::from(op.operands[2]),
584 }),
585 HLIL_SWITCH => Op::Switch(Switch {
586 condition: HighLevelExpressionIndex::from(op.operands[0]),
587 default: HighLevelExpressionIndex::from(op.operands[1]),
588 num_cases: op.operands[2] as usize,
589 first_case: op.operands[3] as usize,
590 }),
591 HLIL_SYSCALL => Op::Syscall(Syscall {
592 num_params: op.operands[0] as usize,
593 first_param: op.operands[1] as usize,
594 }),
595 HLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa {
596 num_params: op.operands[0] as usize,
597 first_param: op.operands[1] as usize,
598 dest_memory: op.operands[2],
599 src_memory: op.operands[3],
600 }),
601 HLIL_TRAP => Op::Trap(Trap {
602 vector: op.operands[0],
603 }),
604 HLIL_VAR_DECLARE => Op::VarDeclare(Var {
605 var: get_var(op.operands[0]),
606 }),
607 HLIL_VAR => Op::Var(Var {
608 var: get_var(op.operands[0]),
609 }),
610 HLIL_VAR_INIT => Op::VarInit(VarInit {
611 dest: get_var(op.operands[0]),
612 src: HighLevelExpressionIndex::from(op.operands[1]),
613 }),
614 HLIL_VAR_INIT_SSA => Op::VarInitSsa(VarInitSsa {
615 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
616 src: HighLevelExpressionIndex::from(op.operands[2]),
617 }),
618 HLIL_VAR_PHI => Op::VarPhi(VarPhi {
619 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
620 num_srcs: op.operands[2] as usize,
621 first_src: op.operands[3] as usize,
622 }),
623 HLIL_VAR_SSA => Op::VarSsa(VarSsa {
624 var: get_var_ssa((op.operands[0], op.operands[1] as usize)),
625 }),
626 HLIL_VAR_SSA_PARTIAL => Op::VarSsaPartial(VarSsaPartial {
627 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
628 prev: get_var_ssa((op.operands[0], op.operands[2] as usize)),
629 }),
630 HLIL_WHILE => Op::While(While {
631 condition: HighLevelExpressionIndex::from(op.operands[0]),
632 body: HighLevelExpressionIndex::from(op.operands[1]),
633 }),
634 HLIL_DO_WHILE => Op::DoWhile(While {
635 body: HighLevelExpressionIndex::from(op.operands[0]),
636 condition: HighLevelExpressionIndex::from(op.operands[1]),
637 }),
638 HLIL_WHILE_SSA => Op::WhileSsa(WhileSsa {
639 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
640 condition: HighLevelExpressionIndex::from(op.operands[1]),
641 body: HighLevelExpressionIndex::from(op.operands[2]),
642 }),
643 HLIL_DO_WHILE_SSA => Op::DoWhileSsa(WhileSsa {
644 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
645 condition: HighLevelExpressionIndex::from(op.operands[1]),
646 body: HighLevelExpressionIndex::from(op.operands[2]),
647 }),
648 };
649 Self {
650 function,
651 address: op.address,
652 instr_index,
653 expr_index,
654 size: op.size,
655 kind,
656 }
657 }
658
659 fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
660 let mut count = 0;
661 let raw_list_ptr = unsafe {
662 BNHighLevelILGetOperandList(
663 self.function.handle,
664 self.expr_index.0,
665 operand_idx,
666 &mut count,
667 )
668 };
669 assert!(!raw_list_ptr.is_null());
670 let list = unsafe { std::slice::from_raw_parts(raw_list_ptr, count).to_vec() };
671 unsafe { BNHighLevelILFreeOperandList(raw_list_ptr) };
672 list
673 }
674
675 fn get_ssa_var_list(&self, operand_idx: usize) -> Vec<SSAVariable> {
676 self.get_operand_list(operand_idx)
677 .chunks(2)
678 .map(|chunk| (Variable::from_identifier(chunk[0]), chunk[1] as usize))
679 .map(|(var, version)| SSAVariable::new(var, version))
680 .collect()
681 }
682
683 fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> {
684 self.get_operand_list(operand_idx)
685 .into_iter()
686 .map(|val| HighLevelExpressionIndex(val as usize))
687 .filter_map(|idx| self.function.instruction_from_expr_index(idx))
688 .collect()
689 }
690
691 pub fn lift(&self) -> HighLevelILLiftedInstruction {
692 use HighLevelILInstructionKind::*;
693 use HighLevelILLiftedInstructionKind as Lifted;
694 let kind = match self.kind {
695 Nop => Lifted::Nop,
696 Break => Lifted::Break,
697 Continue => Lifted::Continue,
698 Noret => Lifted::Noret,
699 Unreachable => Lifted::Unreachable,
700 Bp => Lifted::Bp,
701 Undef => Lifted::Undef,
702 Unimpl => Lifted::Unimpl,
703
704 Adc(op) => Lifted::Adc(self.lift_binary_op_carry(op)),
705 Sbb(op) => Lifted::Sbb(self.lift_binary_op_carry(op)),
706 Rlc(op) => Lifted::Rlc(self.lift_binary_op_carry(op)),
707 Rrc(op) => Lifted::Rrc(self.lift_binary_op_carry(op)),
708
709 Add(op) => Lifted::Add(self.lift_binary_op(op)),
710 Sub(op) => Lifted::Sub(self.lift_binary_op(op)),
711 And(op) => Lifted::And(self.lift_binary_op(op)),
712 Or(op) => Lifted::Or(self.lift_binary_op(op)),
713 Xor(op) => Lifted::Xor(self.lift_binary_op(op)),
714 Lsl(op) => Lifted::Lsl(self.lift_binary_op(op)),
715 Lsr(op) => Lifted::Lsr(self.lift_binary_op(op)),
716 Asr(op) => Lifted::Asr(self.lift_binary_op(op)),
717 Rol(op) => Lifted::Rol(self.lift_binary_op(op)),
718 Ror(op) => Lifted::Ror(self.lift_binary_op(op)),
719 Mul(op) => Lifted::Mul(self.lift_binary_op(op)),
720 MuluDp(op) => Lifted::MuluDp(self.lift_binary_op(op)),
721 MulsDp(op) => Lifted::MulsDp(self.lift_binary_op(op)),
722 Divu(op) => Lifted::Divu(self.lift_binary_op(op)),
723 DivuDp(op) => Lifted::DivuDp(self.lift_binary_op(op)),
724 Divs(op) => Lifted::Divs(self.lift_binary_op(op)),
725 DivsDp(op) => Lifted::DivsDp(self.lift_binary_op(op)),
726 Modu(op) => Lifted::Modu(self.lift_binary_op(op)),
727 ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)),
728 Mods(op) => Lifted::Mods(self.lift_binary_op(op)),
729 ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)),
730 MinSigned(op) => Lifted::MinSigned(self.lift_binary_op(op)),
731 MaxSigned(op) => Lifted::MaxSigned(self.lift_binary_op(op)),
732 MinUnsigned(op) => Lifted::MinUnsigned(self.lift_binary_op(op)),
733 MaxUnsigned(op) => Lifted::MaxUnsigned(self.lift_binary_op(op)),
734 CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)),
735 CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)),
736 CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)),
737 CmpUlt(op) => Lifted::CmpUlt(self.lift_binary_op(op)),
738 CmpSle(op) => Lifted::CmpSle(self.lift_binary_op(op)),
739 CmpUle(op) => Lifted::CmpUle(self.lift_binary_op(op)),
740 CmpSge(op) => Lifted::CmpSge(self.lift_binary_op(op)),
741 CmpUge(op) => Lifted::CmpUge(self.lift_binary_op(op)),
742 CmpSgt(op) => Lifted::CmpSgt(self.lift_binary_op(op)),
743 CmpUgt(op) => Lifted::CmpUgt(self.lift_binary_op(op)),
744 TestBit(op) => Lifted::TestBit(self.lift_binary_op(op)),
745 AddOverflow(op) => Lifted::AddOverflow(self.lift_binary_op(op)),
746 Fadd(op) => Lifted::Fadd(self.lift_binary_op(op)),
747 Fsub(op) => Lifted::Fsub(self.lift_binary_op(op)),
748 Fmul(op) => Lifted::Fmul(self.lift_binary_op(op)),
749 Fdiv(op) => Lifted::Fdiv(self.lift_binary_op(op)),
750 FcmpE(op) => Lifted::FcmpE(self.lift_binary_op(op)),
751 FcmpNe(op) => Lifted::FcmpNe(self.lift_binary_op(op)),
752 FcmpLt(op) => Lifted::FcmpLt(self.lift_binary_op(op)),
753 FcmpLe(op) => Lifted::FcmpLe(self.lift_binary_op(op)),
754 FcmpGe(op) => Lifted::FcmpGe(self.lift_binary_op(op)),
755 FcmpGt(op) => Lifted::FcmpGt(self.lift_binary_op(op)),
756 FcmpO(op) => Lifted::FcmpO(self.lift_binary_op(op)),
757 FcmpUo(op) => Lifted::FcmpUo(self.lift_binary_op(op)),
758
759 ArrayIndex(op) => Lifted::ArrayIndex(LiftedArrayIndex {
760 src: self.lift_operand(op.src),
761 index: self.lift_operand(op.index),
762 }),
763 ArrayIndexSsa(op) => Lifted::ArrayIndexSsa(LiftedArrayIndexSsa {
764 src: self.lift_operand(op.src),
765 src_memory: op.src_memory,
766 index: self.lift_operand(op.index),
767 }),
768 Assign(op) => Lifted::Assign(LiftedAssign {
769 dest: self.lift_operand(op.dest),
770 src: self.lift_operand(op.src),
771 }),
772 AssignUnpack(op) => Lifted::AssignUnpack(LiftedAssignUnpack {
773 dest: self
774 .get_expr_list(0)
775 .iter()
776 .map(|expr| expr.lift())
777 .collect(),
778 src: self.lift_operand(op.src),
779 }),
780 AssignMemSsa(op) => Lifted::AssignMemSsa(LiftedAssignMemSsa {
781 dest: self.lift_operand(op.dest),
782 dest_memory: op.dest_memory,
783 src: self.lift_operand(op.src),
784 src_memory: op.src_memory,
785 }),
786 AssignUnpackMemSsa(op) => Lifted::AssignUnpackMemSsa(LiftedAssignUnpackMemSsa {
787 dest: self
788 .get_expr_list(0)
789 .iter()
790 .map(|expr| expr.lift())
791 .collect(),
792 dest_memory: op.dest_memory,
793 src: self.lift_operand(op.src),
794 src_memory: op.src_memory,
795 }),
796 Block(_op) => Lifted::Block(LiftedBlock {
797 body: self
798 .get_expr_list(0)
799 .iter()
800 .map(|expr| expr.lift())
801 .collect(),
802 }),
803
804 Call(op) => Lifted::Call(self.lift_call(op)),
805 Tailcall(op) => Lifted::Tailcall(self.lift_call(op)),
806 CallSsa(op) => Lifted::CallSsa(LiftedCallSsa {
807 dest: self.lift_operand(op.dest),
808 params: self
809 .get_expr_list(1)
810 .iter()
811 .map(|expr| expr.lift())
812 .collect(),
813 dest_memory: op.dest_memory,
814 src_memory: op.src_memory,
815 }),
816
817 Case(op) => Lifted::Case(LiftedCase {
818 values: self
819 .get_expr_list(0)
820 .iter()
821 .map(|expr| expr.lift())
822 .collect(),
823 body: self.lift_operand(op.body),
824 }),
825 Const(op) => Lifted::Const(op),
826 ConstPtr(op) => Lifted::ConstPtr(op),
827 Import(op) => Lifted::Import(op),
828 ConstData(op) => Lifted::ConstData(LiftedConstData {
829 constant_data: ConstantData::new(
830 self.function.function(),
831 RegisterValue {
832 state: unsafe {
836 std::mem::transmute::<u32, BNRegisterValueType>(op.constant_data_kind)
837 },
838 value: op.constant_data_value,
839 offset: 0,
840 size: op.size,
841 },
842 ),
843 }),
844
845 Deref(op) => Lifted::Deref(self.lift_unary_op(op)),
846 AddressOf(op) => Lifted::AddressOf(self.lift_unary_op(op)),
847 PassByRef(op) => Lifted::PassByRef(self.lift_unary_op(op)),
848 ReturnByRef(op) => Lifted::ReturnByRef(self.lift_unary_op(op)),
849 Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
850 Not(op) => Lifted::Not(self.lift_unary_op(op)),
851 Bswap(op) => Lifted::Bswap(self.lift_unary_op(op)),
852 Popcnt(op) => Lifted::Popcnt(self.lift_unary_op(op)),
853 Clz(op) => Lifted::Clz(self.lift_unary_op(op)),
854 Ctz(op) => Lifted::Ctz(self.lift_unary_op(op)),
855 Rbit(op) => Lifted::Rbit(self.lift_unary_op(op)),
856 Cls(op) => Lifted::Cls(self.lift_unary_op(op)),
857 Abs(op) => Lifted::Abs(self.lift_unary_op(op)),
858 Sx(op) => Lifted::Sx(self.lift_unary_op(op)),
859 Zx(op) => Lifted::Zx(self.lift_unary_op(op)),
860 LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)),
861 BoolToInt(op) => Lifted::BoolToInt(self.lift_unary_op(op)),
862 UnimplMem(op) => Lifted::UnimplMem(self.lift_unary_op(op)),
863 Fsqrt(op) => Lifted::Fsqrt(self.lift_unary_op(op)),
864 Fneg(op) => Lifted::Fneg(self.lift_unary_op(op)),
865 Fabs(op) => Lifted::Fabs(self.lift_unary_op(op)),
866 FloatToInt(op) => Lifted::FloatToInt(self.lift_unary_op(op)),
867 IntToFloat(op) => Lifted::IntToFloat(self.lift_unary_op(op)),
868 FloatConv(op) => Lifted::FloatConv(self.lift_unary_op(op)),
869 RoundToInt(op) => Lifted::RoundToInt(self.lift_unary_op(op)),
870 Floor(op) => Lifted::Floor(self.lift_unary_op(op)),
871 Ceil(op) => Lifted::Ceil(self.lift_unary_op(op)),
872 Ftrunc(op) => Lifted::Ftrunc(self.lift_unary_op(op)),
873
874 DerefFieldSsa(op) => Lifted::DerefFieldSsa(LiftedDerefFieldSsa {
875 src: self.lift_operand(op.src),
876 src_memory: op.src_memory,
877 offset: op.offset,
878 member_index: op.member_index,
879 }),
880 DerefSsa(op) => Lifted::DerefSsa(LiftedDerefSsa {
881 src: self.lift_operand(op.src),
882 src_memory: op.src_memory,
883 }),
884 ExternPtr(op) => Lifted::ExternPtr(op),
885 FloatConst(op) => Lifted::FloatConst(op),
886 For(op) => Lifted::For(LiftedForLoop {
887 init: self.lift_operand(op.init),
888 condition: self.lift_operand(op.condition),
889 update: self.lift_operand(op.update),
890 body: self.lift_operand(op.body),
891 }),
892 Goto(op) => Lifted::Goto(self.lift_label(op)),
893 Label(op) => Lifted::Label(self.lift_label(op)),
894 ForSsa(op) => Lifted::ForSsa(LiftedForLoopSsa {
895 init: self.lift_operand(op.init),
896 condition_phi: self.lift_operand(op.condition_phi),
897 condition: self.lift_operand(op.condition),
898 update: self.lift_operand(op.update),
899 body: self.lift_operand(op.body),
900 }),
901 If(op) => Lifted::If(LiftedIf {
902 condition: self.lift_operand(op.condition),
903 cond_true: self.lift_operand(op.cond_true),
904 cond_false: self.lift_operand(op.cond_false),
905 }),
906 Intrinsic(op) => Lifted::Intrinsic(LiftedIntrinsic {
907 intrinsic: CoreIntrinsic::new(
908 self.function.function().arch(),
909 IntrinsicId(op.intrinsic),
910 )
911 .expect("Invalid intrinsic"),
912 params: self
913 .get_expr_list(1)
914 .iter()
915 .map(|expr| expr.lift())
916 .collect(),
917 }),
918 IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
919 intrinsic: CoreIntrinsic::new(
920 self.function.function().arch(),
921 IntrinsicId(op.intrinsic),
922 )
923 .expect("Invalid intrinsic"),
924 params: self
925 .get_expr_list(1)
926 .iter()
927 .map(|expr| expr.lift())
928 .collect(),
929 dest_memory: op.dest_memory,
930 src_memory: op.src_memory,
931 }),
932 Jump(op) => Lifted::Jump(LiftedJump {
933 dest: self.lift_operand(op.dest),
934 }),
935 MemPhi(op) => Lifted::MemPhi(LiftedMemPhi {
936 dest: op.dest,
937 src: self.get_operand_list(1),
938 }),
939 Ret(_op) => Lifted::Ret(LiftedRet {
940 src: self
941 .get_expr_list(0)
942 .iter()
943 .map(|expr| expr.lift())
944 .collect(),
945 }),
946 Split(op) => Lifted::Split(LiftedSplit {
947 high: self.lift_operand(op.high),
948 low: self.lift_operand(op.low),
949 }),
950 StructField(op) => Lifted::StructField(self.lift_struct_field(op)),
951 DerefField(op) => Lifted::DerefField(self.lift_struct_field(op)),
952 StructInit(_op) => Lifted::StructInit(LiftedStructInit {
953 fields: self
954 .get_expr_list(0)
955 .iter()
956 .map(|expr| expr.lift())
957 .collect(),
958 }),
959 StructInitField(op) => Lifted::StructInitField(self.lift_struct_field(op)),
960 Switch(op) => Lifted::Switch(LiftedSwitch {
961 condition: self.lift_operand(op.condition),
962 default: self.lift_operand(op.default),
963 cases: self
964 .get_expr_list(2)
965 .iter()
966 .map(|expr| expr.lift())
967 .collect(),
968 }),
969 Syscall(_op) => Lifted::Syscall(LiftedSyscall {
970 params: self
971 .get_expr_list(0)
972 .iter()
973 .map(|expr| expr.lift())
974 .collect(),
975 }),
976 SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa {
977 params: self
978 .get_expr_list(0)
979 .iter()
980 .map(|expr| expr.lift())
981 .collect(),
982 dest_memory: op.dest_memory,
983 src_memory: op.src_memory,
984 }),
985 Trap(op) => Lifted::Trap(op),
986 VarDeclare(op) => Lifted::VarDeclare(op),
987 Var(op) => Lifted::Var(op),
988 VarInit(op) => Lifted::VarInit(LiftedVarInit {
989 dest: op.dest,
990 src: self.lift_operand(op.src),
991 }),
992 VarInitSsa(op) => Lifted::VarInitSsa(LiftedVarInitSsa {
993 dest: op.dest,
994 src: self.lift_operand(op.src),
995 }),
996 VarPhi(op) => Lifted::VarPhi(LiftedVarPhi {
997 dest: op.dest,
998 src: self.get_ssa_var_list(2),
999 }),
1000 VarSsa(op) => Lifted::VarSsa(op),
1001 VarSsaPartial(op) => Lifted::VarSsaPartial(op),
1002
1003 While(op) => Lifted::While(self.lift_while(op)),
1004 DoWhile(op) => Lifted::DoWhile(self.lift_while(op)),
1005
1006 WhileSsa(op) => Lifted::WhileSsa(self.lift_while_ssa(op)),
1007 DoWhileSsa(op) => Lifted::DoWhileSsa(self.lift_while_ssa(op)),
1008 };
1009 HighLevelILLiftedInstruction {
1010 function: self.function.clone(),
1011 address: self.address,
1012 instr_index: self.instr_index,
1013 expr_index: self.expr_index,
1014 size: self.size,
1015 kind,
1016 }
1017 }
1018
1019 pub fn lines(&self) -> Array<DisassemblyTextLine> {
1021 let mut count = 0;
1022 let lines = unsafe {
1023 BNGetHighLevelILExprText(
1024 self.function.handle,
1025 self.expr_index.0,
1026 self.function.full_ast,
1027 &mut count,
1028 core::ptr::null_mut(),
1029 )
1030 };
1031 unsafe { Array::new(lines, count, ()) }
1032 }
1033
1034 pub fn expr_type(&self) -> Option<Conf<Ref<Type>>> {
1036 let result = unsafe { BNGetHighLevelILExprType(self.function.handle, self.expr_index.0) };
1037 (!result.type_.is_null()).then(|| {
1038 Conf::new(
1039 unsafe { Type::ref_from_raw(result.type_) },
1040 result.confidence,
1041 )
1042 })
1043 }
1044
1045 pub fn ssa_memory_version(&self) -> usize {
1047 unsafe {
1048 BNGetHighLevelILSSAMemoryVersionAtILInstruction(self.function.handle, self.expr_index.0)
1049 }
1050 }
1051
1052 pub fn ssa_variable_version(&self, variable: Variable) -> SSAVariable {
1053 let version = unsafe {
1054 BNGetHighLevelILSSAVarVersionAtILInstruction(
1055 self.function.handle,
1056 &variable.into(),
1057 self.expr_index.0,
1058 )
1059 };
1060 SSAVariable::new(variable, version)
1061 }
1062
1063 fn lift_operand(
1064 &self,
1065 expr_idx: HighLevelExpressionIndex,
1066 ) -> Box<HighLevelILLiftedInstruction> {
1067 let operand_instr = self.function.instruction_from_expr_index(expr_idx).unwrap();
1068 Box::new(operand_instr.lift())
1069 }
1070
1071 fn lift_binary_op(&self, op: BinaryOp) -> LiftedBinaryOp {
1072 LiftedBinaryOp {
1073 left: self.lift_operand(op.left),
1074 right: self.lift_operand(op.right),
1075 }
1076 }
1077
1078 fn lift_binary_op_carry(&self, op: BinaryOpCarry) -> LiftedBinaryOpCarry {
1079 LiftedBinaryOpCarry {
1080 left: self.lift_operand(op.left),
1081 right: self.lift_operand(op.right),
1082 carry: self.lift_operand(op.carry),
1083 }
1084 }
1085
1086 fn lift_unary_op(&self, op: UnaryOp) -> LiftedUnaryOp {
1087 LiftedUnaryOp {
1088 src: self.lift_operand(op.src),
1089 }
1090 }
1091
1092 fn lift_label(&self, op: Label) -> LiftedLabel {
1093 LiftedLabel {
1094 target: GotoLabel {
1095 function: self.function.function(),
1096 target: op.target,
1097 },
1098 }
1099 }
1100
1101 fn lift_call(&self, op: Call) -> LiftedCall {
1102 LiftedCall {
1103 dest: self.lift_operand(op.dest),
1104 params: self
1105 .get_expr_list(1)
1106 .iter()
1107 .map(|expr| expr.lift())
1108 .collect(),
1109 }
1110 }
1111
1112 fn lift_while(&self, op: While) -> LiftedWhile {
1113 LiftedWhile {
1114 condition: self.lift_operand(op.condition),
1115 body: self.lift_operand(op.body),
1116 }
1117 }
1118
1119 fn lift_while_ssa(&self, op: WhileSsa) -> LiftedWhileSsa {
1120 LiftedWhileSsa {
1121 condition_phi: self.lift_operand(op.condition_phi),
1122 condition: self.lift_operand(op.condition),
1123 body: self.lift_operand(op.body),
1124 }
1125 }
1126
1127 fn lift_struct_field(&self, op: StructField) -> LiftedStructField {
1128 LiftedStructField {
1129 src: self.lift_operand(op.src),
1130 offset: op.offset,
1131 member_index: op.member_index,
1132 }
1133 }
1134}
1135
1136impl CoreArrayProvider for HighLevelILInstruction {
1137 type Raw = usize;
1138 type Context = Ref<HighLevelILFunction>;
1139 type Wrapped<'a> = Self;
1140}
1141
1142unsafe impl CoreArrayProviderInner for HighLevelILInstruction {
1143 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
1144 unsafe { BNFreeILInstructionList(raw) }
1145 }
1146
1147 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
1148 context
1149 .instruction_from_expr_index(HighLevelExpressionIndex(*raw))
1150 .unwrap()
1151 }
1152}
1153
1154impl Debug for HighLevelILInstruction {
1155 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1156 write!(
1158 f,
1159 "<{} at 0x{:08}>",
1160 core::any::type_name::<Self>(),
1161 self.address,
1162 )
1163 }
1164}
1165
1166#[derive(Debug, Copy, Clone)]
1167pub enum HighLevelILInstructionKind {
1168 Nop,
1169 Break,
1170 Continue,
1171 Noret,
1172 Unreachable,
1173 Bp,
1174 Undef,
1175 Unimpl,
1176 Adc(BinaryOpCarry),
1177 Sbb(BinaryOpCarry),
1178 Rlc(BinaryOpCarry),
1179 Rrc(BinaryOpCarry),
1180 Add(BinaryOp),
1181 Sub(BinaryOp),
1182 And(BinaryOp),
1183 Or(BinaryOp),
1184 Xor(BinaryOp),
1185 Lsl(BinaryOp),
1186 Lsr(BinaryOp),
1187 Asr(BinaryOp),
1188 Rol(BinaryOp),
1189 Ror(BinaryOp),
1190 Mul(BinaryOp),
1191 MuluDp(BinaryOp),
1192 MulsDp(BinaryOp),
1193 Divu(BinaryOp),
1194 DivuDp(BinaryOp),
1195 Divs(BinaryOp),
1196 DivsDp(BinaryOp),
1197 Modu(BinaryOp),
1198 ModuDp(BinaryOp),
1199 Mods(BinaryOp),
1200 ModsDp(BinaryOp),
1201 MinSigned(BinaryOp),
1202 MaxSigned(BinaryOp),
1203 MinUnsigned(BinaryOp),
1204 MaxUnsigned(BinaryOp),
1205 CmpE(BinaryOp),
1206 CmpNe(BinaryOp),
1207 CmpSlt(BinaryOp),
1208 CmpUlt(BinaryOp),
1209 CmpSle(BinaryOp),
1210 CmpUle(BinaryOp),
1211 CmpSge(BinaryOp),
1212 CmpUge(BinaryOp),
1213 CmpSgt(BinaryOp),
1214 CmpUgt(BinaryOp),
1215 TestBit(BinaryOp),
1216 AddOverflow(BinaryOp),
1217 Fadd(BinaryOp),
1218 Fsub(BinaryOp),
1219 Fmul(BinaryOp),
1220 Fdiv(BinaryOp),
1221 FcmpE(BinaryOp),
1222 FcmpNe(BinaryOp),
1223 FcmpLt(BinaryOp),
1224 FcmpLe(BinaryOp),
1225 FcmpGe(BinaryOp),
1226 FcmpGt(BinaryOp),
1227 FcmpO(BinaryOp),
1228 FcmpUo(BinaryOp),
1229 ArrayIndex(ArrayIndex),
1230 ArrayIndexSsa(ArrayIndexSsa),
1231 Assign(Assign),
1232 AssignMemSsa(AssignMemSsa),
1233 AssignUnpack(AssignUnpack),
1234 AssignUnpackMemSsa(AssignUnpackMemSsa),
1235 Block(Block),
1236 Call(Call),
1237 Tailcall(Call),
1238 CallSsa(CallSsa),
1239 Case(Case),
1240 Const(Const),
1241 ConstPtr(Const),
1242 Import(Const),
1243 ConstData(ConstData),
1244 Deref(UnaryOp),
1245 AddressOf(UnaryOp),
1246 PassByRef(UnaryOp),
1247 ReturnByRef(UnaryOp),
1248 Neg(UnaryOp),
1249 Not(UnaryOp),
1250 Bswap(UnaryOp),
1251 Popcnt(UnaryOp),
1252 Clz(UnaryOp),
1253 Ctz(UnaryOp),
1254 Rbit(UnaryOp),
1255 Cls(UnaryOp),
1256 Abs(UnaryOp),
1257 Sx(UnaryOp),
1258 Zx(UnaryOp),
1259 LowPart(UnaryOp),
1260 BoolToInt(UnaryOp),
1261 UnimplMem(UnaryOp),
1262 Fsqrt(UnaryOp),
1263 Fneg(UnaryOp),
1264 Fabs(UnaryOp),
1265 FloatToInt(UnaryOp),
1266 IntToFloat(UnaryOp),
1267 FloatConv(UnaryOp),
1268 RoundToInt(UnaryOp),
1269 Floor(UnaryOp),
1270 Ceil(UnaryOp),
1271 Ftrunc(UnaryOp),
1272 DerefFieldSsa(DerefFieldSsa),
1273 DerefSsa(DerefSsa),
1274 ExternPtr(ExternPtr),
1275 FloatConst(FloatConst),
1276 For(ForLoop),
1277 ForSsa(ForLoopSsa),
1278 Goto(Label),
1279 Label(Label),
1280 If(If),
1281 Intrinsic(Intrinsic),
1282 IntrinsicSsa(IntrinsicSsa),
1283 Jump(Jump),
1284 MemPhi(MemPhi),
1285 Ret(Ret),
1286 Split(Split),
1287 StructField(StructField),
1288 DerefField(StructField),
1289 StructInit(StructInit),
1290 StructInitField(StructField),
1291 Switch(Switch),
1292 Syscall(Syscall),
1293 SyscallSsa(SyscallSsa),
1294 Trap(Trap),
1295 VarDeclare(Var),
1296 Var(Var),
1297 VarInit(VarInit),
1298 VarInitSsa(VarInitSsa),
1299 VarPhi(VarPhi),
1300 VarSsa(VarSsa),
1301 VarSsaPartial(VarSsaPartial),
1302 While(While),
1303 DoWhile(While),
1304 WhileSsa(WhileSsa),
1305 DoWhileSsa(WhileSsa),
1306}
1307
1308fn get_float(value: u64, size: usize) -> f64 {
1309 match size {
1310 4 => f32::from_bits(value as u32) as f64,
1311 8 => f64::from_bits(value),
1312 size => todo!("float size {}", size),
1314 }
1315}
1316
1317fn get_var(id: u64) -> Variable {
1318 Variable::from_identifier(id)
1319}
1320
1321fn get_member_index(idx: u64) -> Option<usize> {
1322 (idx as i64 > 0).then_some(idx as usize)
1323}
1324
1325fn get_var_ssa(input: (u64, usize)) -> SSAVariable {
1326 SSAVariable::new(get_var(input.0), input.1)
1327}