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