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_SWITCH => Op::Switch(Switch {
577 condition: HighLevelExpressionIndex::from(op.operands[0]),
578 default: HighLevelExpressionIndex::from(op.operands[1]),
579 num_cases: op.operands[2] as usize,
580 first_case: op.operands[3] as usize,
581 }),
582 HLIL_SYSCALL => Op::Syscall(Syscall {
583 num_params: op.operands[0] as usize,
584 first_param: op.operands[1] as usize,
585 }),
586 HLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa {
587 num_params: op.operands[0] as usize,
588 first_param: op.operands[1] as usize,
589 dest_memory: op.operands[2],
590 src_memory: op.operands[3],
591 }),
592 HLIL_TRAP => Op::Trap(Trap {
593 vector: op.operands[0],
594 }),
595 HLIL_VAR_DECLARE => Op::VarDeclare(Var {
596 var: get_var(op.operands[0]),
597 }),
598 HLIL_VAR => Op::Var(Var {
599 var: get_var(op.operands[0]),
600 }),
601 HLIL_VAR_INIT => Op::VarInit(VarInit {
602 dest: get_var(op.operands[0]),
603 src: HighLevelExpressionIndex::from(op.operands[1]),
604 }),
605 HLIL_VAR_INIT_SSA => Op::VarInitSsa(VarInitSsa {
606 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
607 src: HighLevelExpressionIndex::from(op.operands[2]),
608 }),
609 HLIL_VAR_PHI => Op::VarPhi(VarPhi {
610 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
611 num_srcs: op.operands[2] as usize,
612 first_src: op.operands[3] as usize,
613 }),
614 HLIL_VAR_SSA => Op::VarSsa(VarSsa {
615 var: get_var_ssa((op.operands[0], op.operands[1] as usize)),
616 }),
617 HLIL_VAR_SSA_PARTIAL => Op::VarSsaPartial(VarSsaPartial {
618 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
619 prev: get_var_ssa((op.operands[0], op.operands[2] as usize)),
620 }),
621 HLIL_WHILE => Op::While(While {
622 condition: HighLevelExpressionIndex::from(op.operands[0]),
623 body: HighLevelExpressionIndex::from(op.operands[1]),
624 }),
625 HLIL_DO_WHILE => Op::DoWhile(While {
626 body: HighLevelExpressionIndex::from(op.operands[0]),
627 condition: HighLevelExpressionIndex::from(op.operands[1]),
628 }),
629 HLIL_WHILE_SSA => Op::WhileSsa(WhileSsa {
630 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
631 condition: HighLevelExpressionIndex::from(op.operands[1]),
632 body: HighLevelExpressionIndex::from(op.operands[2]),
633 }),
634 HLIL_DO_WHILE_SSA => Op::DoWhileSsa(WhileSsa {
635 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
636 condition: HighLevelExpressionIndex::from(op.operands[1]),
637 body: HighLevelExpressionIndex::from(op.operands[2]),
638 }),
639 };
640 Self {
641 function,
642 address: op.address,
643 instr_index,
644 expr_index,
645 size: op.size,
646 kind,
647 }
648 }
649
650 fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
651 let mut count = 0;
652 let raw_list_ptr = unsafe {
653 BNHighLevelILGetOperandList(
654 self.function.handle,
655 self.expr_index.0,
656 operand_idx,
657 &mut count,
658 )
659 };
660 assert!(!raw_list_ptr.is_null());
661 let list = unsafe { std::slice::from_raw_parts(raw_list_ptr, count).to_vec() };
662 unsafe { BNHighLevelILFreeOperandList(raw_list_ptr) };
663 list
664 }
665
666 fn get_ssa_var_list(&self, operand_idx: usize) -> Vec<SSAVariable> {
667 self.get_operand_list(operand_idx)
668 .chunks(2)
669 .map(|chunk| (Variable::from_identifier(chunk[0]), chunk[1] as usize))
670 .map(|(var, version)| SSAVariable::new(var, version))
671 .collect()
672 }
673
674 fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> {
675 self.get_operand_list(operand_idx)
676 .into_iter()
677 .map(|val| HighLevelExpressionIndex(val as usize))
678 .filter_map(|idx| self.function.instruction_from_expr_index(idx))
679 .collect()
680 }
681
682 pub fn lift(&self) -> HighLevelILLiftedInstruction {
683 use HighLevelILInstructionKind::*;
684 use HighLevelILLiftedInstructionKind as Lifted;
685 let kind = match self.kind {
686 Nop => Lifted::Nop,
687 Break => Lifted::Break,
688 Continue => Lifted::Continue,
689 Noret => Lifted::Noret,
690 Unreachable => Lifted::Unreachable,
691 Bp => Lifted::Bp,
692 Undef => Lifted::Undef,
693 Unimpl => Lifted::Unimpl,
694
695 Adc(op) => Lifted::Adc(self.lift_binary_op_carry(op)),
696 Sbb(op) => Lifted::Sbb(self.lift_binary_op_carry(op)),
697 Rlc(op) => Lifted::Rlc(self.lift_binary_op_carry(op)),
698 Rrc(op) => Lifted::Rrc(self.lift_binary_op_carry(op)),
699
700 Add(op) => Lifted::Add(self.lift_binary_op(op)),
701 Sub(op) => Lifted::Sub(self.lift_binary_op(op)),
702 And(op) => Lifted::And(self.lift_binary_op(op)),
703 Or(op) => Lifted::Or(self.lift_binary_op(op)),
704 Xor(op) => Lifted::Xor(self.lift_binary_op(op)),
705 Lsl(op) => Lifted::Lsl(self.lift_binary_op(op)),
706 Lsr(op) => Lifted::Lsr(self.lift_binary_op(op)),
707 Asr(op) => Lifted::Asr(self.lift_binary_op(op)),
708 Rol(op) => Lifted::Rol(self.lift_binary_op(op)),
709 Ror(op) => Lifted::Ror(self.lift_binary_op(op)),
710 Mul(op) => Lifted::Mul(self.lift_binary_op(op)),
711 MuluDp(op) => Lifted::MuluDp(self.lift_binary_op(op)),
712 MulsDp(op) => Lifted::MulsDp(self.lift_binary_op(op)),
713 Divu(op) => Lifted::Divu(self.lift_binary_op(op)),
714 DivuDp(op) => Lifted::DivuDp(self.lift_binary_op(op)),
715 Divs(op) => Lifted::Divs(self.lift_binary_op(op)),
716 DivsDp(op) => Lifted::DivsDp(self.lift_binary_op(op)),
717 Modu(op) => Lifted::Modu(self.lift_binary_op(op)),
718 ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)),
719 Mods(op) => Lifted::Mods(self.lift_binary_op(op)),
720 ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)),
721 MinSigned(op) => Lifted::MinSigned(self.lift_binary_op(op)),
722 MaxSigned(op) => Lifted::MaxSigned(self.lift_binary_op(op)),
723 MinUnsigned(op) => Lifted::MinUnsigned(self.lift_binary_op(op)),
724 MaxUnsigned(op) => Lifted::MaxUnsigned(self.lift_binary_op(op)),
725 CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)),
726 CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)),
727 CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)),
728 CmpUlt(op) => Lifted::CmpUlt(self.lift_binary_op(op)),
729 CmpSle(op) => Lifted::CmpSle(self.lift_binary_op(op)),
730 CmpUle(op) => Lifted::CmpUle(self.lift_binary_op(op)),
731 CmpSge(op) => Lifted::CmpSge(self.lift_binary_op(op)),
732 CmpUge(op) => Lifted::CmpUge(self.lift_binary_op(op)),
733 CmpSgt(op) => Lifted::CmpSgt(self.lift_binary_op(op)),
734 CmpUgt(op) => Lifted::CmpUgt(self.lift_binary_op(op)),
735 TestBit(op) => Lifted::TestBit(self.lift_binary_op(op)),
736 AddOverflow(op) => Lifted::AddOverflow(self.lift_binary_op(op)),
737 Fadd(op) => Lifted::Fadd(self.lift_binary_op(op)),
738 Fsub(op) => Lifted::Fsub(self.lift_binary_op(op)),
739 Fmul(op) => Lifted::Fmul(self.lift_binary_op(op)),
740 Fdiv(op) => Lifted::Fdiv(self.lift_binary_op(op)),
741 FcmpE(op) => Lifted::FcmpE(self.lift_binary_op(op)),
742 FcmpNe(op) => Lifted::FcmpNe(self.lift_binary_op(op)),
743 FcmpLt(op) => Lifted::FcmpLt(self.lift_binary_op(op)),
744 FcmpLe(op) => Lifted::FcmpLe(self.lift_binary_op(op)),
745 FcmpGe(op) => Lifted::FcmpGe(self.lift_binary_op(op)),
746 FcmpGt(op) => Lifted::FcmpGt(self.lift_binary_op(op)),
747 FcmpO(op) => Lifted::FcmpO(self.lift_binary_op(op)),
748 FcmpUo(op) => Lifted::FcmpUo(self.lift_binary_op(op)),
749
750 ArrayIndex(op) => Lifted::ArrayIndex(LiftedArrayIndex {
751 src: self.lift_operand(op.src),
752 index: self.lift_operand(op.index),
753 }),
754 ArrayIndexSsa(op) => Lifted::ArrayIndexSsa(LiftedArrayIndexSsa {
755 src: self.lift_operand(op.src),
756 src_memory: op.src_memory,
757 index: self.lift_operand(op.index),
758 }),
759 Assign(op) => Lifted::Assign(LiftedAssign {
760 dest: self.lift_operand(op.dest),
761 src: self.lift_operand(op.src),
762 }),
763 AssignUnpack(op) => Lifted::AssignUnpack(LiftedAssignUnpack {
764 dest: self
765 .get_expr_list(0)
766 .iter()
767 .map(|expr| expr.lift())
768 .collect(),
769 src: self.lift_operand(op.src),
770 }),
771 AssignMemSsa(op) => Lifted::AssignMemSsa(LiftedAssignMemSsa {
772 dest: self.lift_operand(op.dest),
773 dest_memory: op.dest_memory,
774 src: self.lift_operand(op.src),
775 src_memory: op.src_memory,
776 }),
777 AssignUnpackMemSsa(op) => Lifted::AssignUnpackMemSsa(LiftedAssignUnpackMemSsa {
778 dest: self
779 .get_expr_list(0)
780 .iter()
781 .map(|expr| expr.lift())
782 .collect(),
783 dest_memory: op.dest_memory,
784 src: self.lift_operand(op.src),
785 src_memory: op.src_memory,
786 }),
787 Block(_op) => Lifted::Block(LiftedBlock {
788 body: self
789 .get_expr_list(0)
790 .iter()
791 .map(|expr| expr.lift())
792 .collect(),
793 }),
794
795 Call(op) => Lifted::Call(self.lift_call(op)),
796 Tailcall(op) => Lifted::Tailcall(self.lift_call(op)),
797 CallSsa(op) => Lifted::CallSsa(LiftedCallSsa {
798 dest: self.lift_operand(op.dest),
799 params: self
800 .get_expr_list(1)
801 .iter()
802 .map(|expr| expr.lift())
803 .collect(),
804 dest_memory: op.dest_memory,
805 src_memory: op.src_memory,
806 }),
807
808 Case(op) => Lifted::Case(LiftedCase {
809 values: self
810 .get_expr_list(0)
811 .iter()
812 .map(|expr| expr.lift())
813 .collect(),
814 body: self.lift_operand(op.body),
815 }),
816 Const(op) => Lifted::Const(op),
817 ConstPtr(op) => Lifted::ConstPtr(op),
818 Import(op) => Lifted::Import(op),
819 ConstData(op) => Lifted::ConstData(LiftedConstData {
820 constant_data: ConstantData::new(
821 self.function.function(),
822 RegisterValue {
823 state: unsafe {
827 std::mem::transmute::<u32, BNRegisterValueType>(op.constant_data_kind)
828 },
829 value: op.constant_data_value,
830 offset: 0,
831 size: op.size,
832 },
833 ),
834 }),
835
836 Deref(op) => Lifted::Deref(self.lift_unary_op(op)),
837 AddressOf(op) => Lifted::AddressOf(self.lift_unary_op(op)),
838 PassByRef(op) => Lifted::PassByRef(self.lift_unary_op(op)),
839 ReturnByRef(op) => Lifted::ReturnByRef(self.lift_unary_op(op)),
840 Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
841 Not(op) => Lifted::Not(self.lift_unary_op(op)),
842 Bswap(op) => Lifted::Bswap(self.lift_unary_op(op)),
843 Popcnt(op) => Lifted::Popcnt(self.lift_unary_op(op)),
844 Clz(op) => Lifted::Clz(self.lift_unary_op(op)),
845 Ctz(op) => Lifted::Ctz(self.lift_unary_op(op)),
846 Rbit(op) => Lifted::Rbit(self.lift_unary_op(op)),
847 Cls(op) => Lifted::Cls(self.lift_unary_op(op)),
848 Abs(op) => Lifted::Abs(self.lift_unary_op(op)),
849 Sx(op) => Lifted::Sx(self.lift_unary_op(op)),
850 Zx(op) => Lifted::Zx(self.lift_unary_op(op)),
851 LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)),
852 BoolToInt(op) => Lifted::BoolToInt(self.lift_unary_op(op)),
853 UnimplMem(op) => Lifted::UnimplMem(self.lift_unary_op(op)),
854 Fsqrt(op) => Lifted::Fsqrt(self.lift_unary_op(op)),
855 Fneg(op) => Lifted::Fneg(self.lift_unary_op(op)),
856 Fabs(op) => Lifted::Fabs(self.lift_unary_op(op)),
857 FloatToInt(op) => Lifted::FloatToInt(self.lift_unary_op(op)),
858 IntToFloat(op) => Lifted::IntToFloat(self.lift_unary_op(op)),
859 FloatConv(op) => Lifted::FloatConv(self.lift_unary_op(op)),
860 RoundToInt(op) => Lifted::RoundToInt(self.lift_unary_op(op)),
861 Floor(op) => Lifted::Floor(self.lift_unary_op(op)),
862 Ceil(op) => Lifted::Ceil(self.lift_unary_op(op)),
863 Ftrunc(op) => Lifted::Ftrunc(self.lift_unary_op(op)),
864
865 DerefFieldSsa(op) => Lifted::DerefFieldSsa(LiftedDerefFieldSsa {
866 src: self.lift_operand(op.src),
867 src_memory: op.src_memory,
868 offset: op.offset,
869 member_index: op.member_index,
870 }),
871 DerefSsa(op) => Lifted::DerefSsa(LiftedDerefSsa {
872 src: self.lift_operand(op.src),
873 src_memory: op.src_memory,
874 }),
875 ExternPtr(op) => Lifted::ExternPtr(op),
876 FloatConst(op) => Lifted::FloatConst(op),
877 For(op) => Lifted::For(LiftedForLoop {
878 init: self.lift_operand(op.init),
879 condition: self.lift_operand(op.condition),
880 update: self.lift_operand(op.update),
881 body: self.lift_operand(op.body),
882 }),
883 Goto(op) => Lifted::Goto(self.lift_label(op)),
884 Label(op) => Lifted::Label(self.lift_label(op)),
885 ForSsa(op) => Lifted::ForSsa(LiftedForLoopSsa {
886 init: self.lift_operand(op.init),
887 condition_phi: self.lift_operand(op.condition_phi),
888 condition: self.lift_operand(op.condition),
889 update: self.lift_operand(op.update),
890 body: self.lift_operand(op.body),
891 }),
892 If(op) => Lifted::If(LiftedIf {
893 condition: self.lift_operand(op.condition),
894 cond_true: self.lift_operand(op.cond_true),
895 cond_false: self.lift_operand(op.cond_false),
896 }),
897 Intrinsic(op) => Lifted::Intrinsic(LiftedIntrinsic {
898 intrinsic: CoreIntrinsic::new(
899 self.function.function().arch(),
900 IntrinsicId(op.intrinsic),
901 )
902 .expect("Invalid intrinsic"),
903 params: self
904 .get_expr_list(1)
905 .iter()
906 .map(|expr| expr.lift())
907 .collect(),
908 }),
909 IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
910 intrinsic: CoreIntrinsic::new(
911 self.function.function().arch(),
912 IntrinsicId(op.intrinsic),
913 )
914 .expect("Invalid intrinsic"),
915 params: self
916 .get_expr_list(1)
917 .iter()
918 .map(|expr| expr.lift())
919 .collect(),
920 dest_memory: op.dest_memory,
921 src_memory: op.src_memory,
922 }),
923 Jump(op) => Lifted::Jump(LiftedJump {
924 dest: self.lift_operand(op.dest),
925 }),
926 MemPhi(op) => Lifted::MemPhi(LiftedMemPhi {
927 dest: op.dest,
928 src: self.get_operand_list(1),
929 }),
930 Ret(_op) => Lifted::Ret(LiftedRet {
931 src: self
932 .get_expr_list(0)
933 .iter()
934 .map(|expr| expr.lift())
935 .collect(),
936 }),
937 Split(op) => Lifted::Split(LiftedSplit {
938 high: self.lift_operand(op.high),
939 low: self.lift_operand(op.low),
940 }),
941 StructField(op) => Lifted::StructField(self.lift_struct_field(op)),
942 DerefField(op) => Lifted::DerefField(self.lift_struct_field(op)),
943 Switch(op) => Lifted::Switch(LiftedSwitch {
944 condition: self.lift_operand(op.condition),
945 default: self.lift_operand(op.default),
946 cases: self
947 .get_expr_list(2)
948 .iter()
949 .map(|expr| expr.lift())
950 .collect(),
951 }),
952 Syscall(_op) => Lifted::Syscall(LiftedSyscall {
953 params: self
954 .get_expr_list(0)
955 .iter()
956 .map(|expr| expr.lift())
957 .collect(),
958 }),
959 SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa {
960 params: self
961 .get_expr_list(0)
962 .iter()
963 .map(|expr| expr.lift())
964 .collect(),
965 dest_memory: op.dest_memory,
966 src_memory: op.src_memory,
967 }),
968 Trap(op) => Lifted::Trap(op),
969 VarDeclare(op) => Lifted::VarDeclare(op),
970 Var(op) => Lifted::Var(op),
971 VarInit(op) => Lifted::VarInit(LiftedVarInit {
972 dest: op.dest,
973 src: self.lift_operand(op.src),
974 }),
975 VarInitSsa(op) => Lifted::VarInitSsa(LiftedVarInitSsa {
976 dest: op.dest,
977 src: self.lift_operand(op.src),
978 }),
979 VarPhi(op) => Lifted::VarPhi(LiftedVarPhi {
980 dest: op.dest,
981 src: self.get_ssa_var_list(2),
982 }),
983 VarSsa(op) => Lifted::VarSsa(op),
984 VarSsaPartial(op) => Lifted::VarSsaPartial(op),
985
986 While(op) => Lifted::While(self.lift_while(op)),
987 DoWhile(op) => Lifted::DoWhile(self.lift_while(op)),
988
989 WhileSsa(op) => Lifted::WhileSsa(self.lift_while_ssa(op)),
990 DoWhileSsa(op) => Lifted::DoWhileSsa(self.lift_while_ssa(op)),
991 };
992 HighLevelILLiftedInstruction {
993 function: self.function.clone(),
994 address: self.address,
995 instr_index: self.instr_index,
996 expr_index: self.expr_index,
997 size: self.size,
998 kind,
999 }
1000 }
1001
1002 pub fn lines(&self) -> Array<DisassemblyTextLine> {
1004 let mut count = 0;
1005 let lines = unsafe {
1006 BNGetHighLevelILExprText(
1007 self.function.handle,
1008 self.expr_index.0,
1009 self.function.full_ast,
1010 &mut count,
1011 core::ptr::null_mut(),
1012 )
1013 };
1014 unsafe { Array::new(lines, count, ()) }
1015 }
1016
1017 pub fn expr_type(&self) -> Option<Conf<Ref<Type>>> {
1019 let result = unsafe { BNGetHighLevelILExprType(self.function.handle, self.expr_index.0) };
1020 (!result.type_.is_null()).then(|| {
1021 Conf::new(
1022 unsafe { Type::ref_from_raw(result.type_) },
1023 result.confidence,
1024 )
1025 })
1026 }
1027
1028 pub fn ssa_memory_version(&self) -> usize {
1030 unsafe {
1031 BNGetHighLevelILSSAMemoryVersionAtILInstruction(self.function.handle, self.expr_index.0)
1032 }
1033 }
1034
1035 pub fn ssa_variable_version(&self, variable: Variable) -> SSAVariable {
1036 let version = unsafe {
1037 BNGetHighLevelILSSAVarVersionAtILInstruction(
1038 self.function.handle,
1039 &variable.into(),
1040 self.expr_index.0,
1041 )
1042 };
1043 SSAVariable::new(variable, version)
1044 }
1045
1046 fn lift_operand(
1047 &self,
1048 expr_idx: HighLevelExpressionIndex,
1049 ) -> Box<HighLevelILLiftedInstruction> {
1050 let operand_instr = self.function.instruction_from_expr_index(expr_idx).unwrap();
1051 Box::new(operand_instr.lift())
1052 }
1053
1054 fn lift_binary_op(&self, op: BinaryOp) -> LiftedBinaryOp {
1055 LiftedBinaryOp {
1056 left: self.lift_operand(op.left),
1057 right: self.lift_operand(op.right),
1058 }
1059 }
1060
1061 fn lift_binary_op_carry(&self, op: BinaryOpCarry) -> LiftedBinaryOpCarry {
1062 LiftedBinaryOpCarry {
1063 left: self.lift_operand(op.left),
1064 right: self.lift_operand(op.right),
1065 carry: self.lift_operand(op.carry),
1066 }
1067 }
1068
1069 fn lift_unary_op(&self, op: UnaryOp) -> LiftedUnaryOp {
1070 LiftedUnaryOp {
1071 src: self.lift_operand(op.src),
1072 }
1073 }
1074
1075 fn lift_label(&self, op: Label) -> LiftedLabel {
1076 LiftedLabel {
1077 target: GotoLabel {
1078 function: self.function.function(),
1079 target: op.target,
1080 },
1081 }
1082 }
1083
1084 fn lift_call(&self, op: Call) -> LiftedCall {
1085 LiftedCall {
1086 dest: self.lift_operand(op.dest),
1087 params: self
1088 .get_expr_list(1)
1089 .iter()
1090 .map(|expr| expr.lift())
1091 .collect(),
1092 }
1093 }
1094
1095 fn lift_while(&self, op: While) -> LiftedWhile {
1096 LiftedWhile {
1097 condition: self.lift_operand(op.condition),
1098 body: self.lift_operand(op.body),
1099 }
1100 }
1101
1102 fn lift_while_ssa(&self, op: WhileSsa) -> LiftedWhileSsa {
1103 LiftedWhileSsa {
1104 condition_phi: self.lift_operand(op.condition_phi),
1105 condition: self.lift_operand(op.condition),
1106 body: self.lift_operand(op.body),
1107 }
1108 }
1109
1110 fn lift_struct_field(&self, op: StructField) -> LiftedStructField {
1111 LiftedStructField {
1112 src: self.lift_operand(op.src),
1113 offset: op.offset,
1114 member_index: op.member_index,
1115 }
1116 }
1117}
1118
1119impl CoreArrayProvider for HighLevelILInstruction {
1120 type Raw = usize;
1121 type Context = Ref<HighLevelILFunction>;
1122 type Wrapped<'a> = Self;
1123}
1124
1125unsafe impl CoreArrayProviderInner for HighLevelILInstruction {
1126 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
1127 unsafe { BNFreeILInstructionList(raw) }
1128 }
1129
1130 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
1131 context
1132 .instruction_from_expr_index(HighLevelExpressionIndex(*raw))
1133 .unwrap()
1134 }
1135}
1136
1137impl Debug for HighLevelILInstruction {
1138 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1139 write!(
1141 f,
1142 "<{} at 0x{:08}>",
1143 core::any::type_name::<Self>(),
1144 self.address,
1145 )
1146 }
1147}
1148
1149#[derive(Debug, Copy, Clone)]
1150pub enum HighLevelILInstructionKind {
1151 Nop,
1152 Break,
1153 Continue,
1154 Noret,
1155 Unreachable,
1156 Bp,
1157 Undef,
1158 Unimpl,
1159 Adc(BinaryOpCarry),
1160 Sbb(BinaryOpCarry),
1161 Rlc(BinaryOpCarry),
1162 Rrc(BinaryOpCarry),
1163 Add(BinaryOp),
1164 Sub(BinaryOp),
1165 And(BinaryOp),
1166 Or(BinaryOp),
1167 Xor(BinaryOp),
1168 Lsl(BinaryOp),
1169 Lsr(BinaryOp),
1170 Asr(BinaryOp),
1171 Rol(BinaryOp),
1172 Ror(BinaryOp),
1173 Mul(BinaryOp),
1174 MuluDp(BinaryOp),
1175 MulsDp(BinaryOp),
1176 Divu(BinaryOp),
1177 DivuDp(BinaryOp),
1178 Divs(BinaryOp),
1179 DivsDp(BinaryOp),
1180 Modu(BinaryOp),
1181 ModuDp(BinaryOp),
1182 Mods(BinaryOp),
1183 ModsDp(BinaryOp),
1184 MinSigned(BinaryOp),
1185 MaxSigned(BinaryOp),
1186 MinUnsigned(BinaryOp),
1187 MaxUnsigned(BinaryOp),
1188 CmpE(BinaryOp),
1189 CmpNe(BinaryOp),
1190 CmpSlt(BinaryOp),
1191 CmpUlt(BinaryOp),
1192 CmpSle(BinaryOp),
1193 CmpUle(BinaryOp),
1194 CmpSge(BinaryOp),
1195 CmpUge(BinaryOp),
1196 CmpSgt(BinaryOp),
1197 CmpUgt(BinaryOp),
1198 TestBit(BinaryOp),
1199 AddOverflow(BinaryOp),
1200 Fadd(BinaryOp),
1201 Fsub(BinaryOp),
1202 Fmul(BinaryOp),
1203 Fdiv(BinaryOp),
1204 FcmpE(BinaryOp),
1205 FcmpNe(BinaryOp),
1206 FcmpLt(BinaryOp),
1207 FcmpLe(BinaryOp),
1208 FcmpGe(BinaryOp),
1209 FcmpGt(BinaryOp),
1210 FcmpO(BinaryOp),
1211 FcmpUo(BinaryOp),
1212 ArrayIndex(ArrayIndex),
1213 ArrayIndexSsa(ArrayIndexSsa),
1214 Assign(Assign),
1215 AssignMemSsa(AssignMemSsa),
1216 AssignUnpack(AssignUnpack),
1217 AssignUnpackMemSsa(AssignUnpackMemSsa),
1218 Block(Block),
1219 Call(Call),
1220 Tailcall(Call),
1221 CallSsa(CallSsa),
1222 Case(Case),
1223 Const(Const),
1224 ConstPtr(Const),
1225 Import(Const),
1226 ConstData(ConstData),
1227 Deref(UnaryOp),
1228 AddressOf(UnaryOp),
1229 PassByRef(UnaryOp),
1230 ReturnByRef(UnaryOp),
1231 Neg(UnaryOp),
1232 Not(UnaryOp),
1233 Bswap(UnaryOp),
1234 Popcnt(UnaryOp),
1235 Clz(UnaryOp),
1236 Ctz(UnaryOp),
1237 Rbit(UnaryOp),
1238 Cls(UnaryOp),
1239 Abs(UnaryOp),
1240 Sx(UnaryOp),
1241 Zx(UnaryOp),
1242 LowPart(UnaryOp),
1243 BoolToInt(UnaryOp),
1244 UnimplMem(UnaryOp),
1245 Fsqrt(UnaryOp),
1246 Fneg(UnaryOp),
1247 Fabs(UnaryOp),
1248 FloatToInt(UnaryOp),
1249 IntToFloat(UnaryOp),
1250 FloatConv(UnaryOp),
1251 RoundToInt(UnaryOp),
1252 Floor(UnaryOp),
1253 Ceil(UnaryOp),
1254 Ftrunc(UnaryOp),
1255 DerefFieldSsa(DerefFieldSsa),
1256 DerefSsa(DerefSsa),
1257 ExternPtr(ExternPtr),
1258 FloatConst(FloatConst),
1259 For(ForLoop),
1260 ForSsa(ForLoopSsa),
1261 Goto(Label),
1262 Label(Label),
1263 If(If),
1264 Intrinsic(Intrinsic),
1265 IntrinsicSsa(IntrinsicSsa),
1266 Jump(Jump),
1267 MemPhi(MemPhi),
1268 Ret(Ret),
1269 Split(Split),
1270 StructField(StructField),
1271 DerefField(StructField),
1272 Switch(Switch),
1273 Syscall(Syscall),
1274 SyscallSsa(SyscallSsa),
1275 Trap(Trap),
1276 VarDeclare(Var),
1277 Var(Var),
1278 VarInit(VarInit),
1279 VarInitSsa(VarInitSsa),
1280 VarPhi(VarPhi),
1281 VarSsa(VarSsa),
1282 VarSsaPartial(VarSsaPartial),
1283 While(While),
1284 DoWhile(While),
1285 WhileSsa(WhileSsa),
1286 DoWhileSsa(WhileSsa),
1287}
1288
1289fn get_float(value: u64, size: usize) -> f64 {
1290 match size {
1291 4 => f32::from_bits(value as u32) as f64,
1292 8 => f64::from_bits(value),
1293 size => todo!("float size {}", size),
1295 }
1296}
1297
1298fn get_var(id: u64) -> Variable {
1299 Variable::from_identifier(id)
1300}
1301
1302fn get_member_index(idx: u64) -> Option<usize> {
1303 (idx as i64 > 0).then_some(idx as usize)
1304}
1305
1306fn get_var_ssa(input: (u64, usize)) -> SSAVariable {
1307 SSAVariable::new(get_var(input.0), input.1)
1308}