angr 9.2.83__py3-none-win_amd64.whl → 9.2.85__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (62) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_base.py +6 -1
  3. angr/analyses/cfg/cfg_fast.py +32 -10
  4. angr/analyses/decompiler/clinic.py +204 -4
  5. angr/analyses/decompiler/condition_processor.py +8 -2
  6. angr/analyses/decompiler/decompilation_options.py +10 -0
  7. angr/analyses/decompiler/decompiler.py +19 -17
  8. angr/analyses/decompiler/goto_manager.py +34 -51
  9. angr/analyses/decompiler/optimization_passes/__init__.py +5 -5
  10. angr/analyses/decompiler/optimization_passes/div_simplifier.py +2 -0
  11. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
  12. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +2 -0
  13. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +2 -0
  14. angr/analyses/decompiler/optimization_passes/optimization_pass.py +131 -3
  15. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -3
  16. angr/analyses/decompiler/optimization_passes/return_duplicator.py +519 -0
  17. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +14 -2
  18. angr/analyses/decompiler/region_identifier.py +8 -2
  19. angr/analyses/decompiler/region_simplifiers/goto.py +5 -4
  20. angr/analyses/decompiler/structured_codegen/c.py +66 -5
  21. angr/analyses/decompiler/structuring/phoenix.py +3 -1
  22. angr/analyses/decompiler/structuring/structurer_nodes.py +11 -5
  23. angr/analyses/decompiler/utils.py +50 -0
  24. angr/analyses/disassembly.py +10 -3
  25. angr/analyses/propagator/engine_ail.py +125 -0
  26. angr/analyses/reaching_definitions/engine_ail.py +36 -2
  27. angr/analyses/reaching_definitions/rd_initializer.py +15 -1
  28. angr/analyses/reaching_definitions/rd_state.py +9 -4
  29. angr/analyses/stack_pointer_tracker.py +10 -17
  30. angr/analyses/variable_recovery/engine_ail.py +27 -1
  31. angr/angrdb/serializers/loader.py +10 -3
  32. angr/calling_conventions.py +2 -0
  33. angr/engines/pcode/behavior.py +7 -2
  34. angr/engines/pcode/cc.py +1 -0
  35. angr/engines/pcode/emulate.py +144 -104
  36. angr/engines/pcode/lifter.py +135 -79
  37. angr/knowledge_plugins/functions/function.py +28 -0
  38. angr/knowledge_plugins/functions/function_manager.py +48 -5
  39. angr/knowledge_plugins/propagations/states.py +14 -0
  40. angr/lib/angr_native.dll +0 -0
  41. angr/procedures/cgc/deallocate.py +5 -2
  42. angr/procedures/posix/gethostbyname.py +23 -8
  43. angr/project.py +4 -0
  44. angr/simos/__init__.py +2 -0
  45. angr/simos/simos.py +1 -0
  46. angr/simos/snimmuc_nxp.py +152 -0
  47. angr/state_plugins/history.py +3 -1
  48. angr/utils/graph.py +20 -18
  49. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/METADATA +9 -8
  50. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/RECORD +61 -59
  51. tests/analyses/cfg/test_cfg_rust_got_resolution.py +2 -1
  52. tests/analyses/cfg/test_jumptables.py +2 -1
  53. tests/analyses/decompiler/test_decompiler.py +155 -103
  54. tests/engines/pcode/test_emulate.py +607 -0
  55. tests/engines/test_java.py +609 -663
  56. tests/knowledge_plugins/functions/test_function_manager.py +13 -0
  57. tests/serialization/test_db.py +30 -0
  58. angr/analyses/decompiler/optimization_passes/eager_returns.py +0 -285
  59. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/LICENSE +0 -0
  60. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/WHEEL +0 -0
  61. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/entry_points.txt +0 -0
  62. {angr-9.2.83.dist-info → angr-9.2.85.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,607 @@
1
+ import logging
2
+ import unittest
3
+ import operator
4
+ from dataclasses import dataclass
5
+ from typing import Optional, List
6
+
7
+ import claripy
8
+
9
+ import angr
10
+ from angr.engines.pcode.behavior import BehaviorFactory
11
+ from angr.engines.pcode.emulate import PcodeEmulatorMixin
12
+ from angr.sim_state import SimState
13
+ from angr.engines import SimSuccessors
14
+
15
+
16
+ try:
17
+ import pypcode
18
+ from pypcode import OpCode
19
+ except ImportError:
20
+ pypcode = None
21
+
22
+
23
+ log = logging.getLogger(__name__)
24
+
25
+
26
+ @dataclass(eq=True)
27
+ class MockAddrSpace:
28
+ """
29
+ Mock AddrSpace
30
+ """
31
+
32
+ name: str
33
+
34
+
35
+ CONST_SPACE = MockAddrSpace("const")
36
+ RAM_SPACE = MockAddrSpace("ram")
37
+ REGISTER_SPACE = MockAddrSpace("register")
38
+ UNIQUE_SPACE = MockAddrSpace("unique")
39
+
40
+
41
+ @dataclass(eq=True)
42
+ class MockVarnode:
43
+ """
44
+ Mock Varnode
45
+ """
46
+
47
+ space: MockAddrSpace
48
+ offset: int
49
+ size: int
50
+
51
+ register_name: str = "<mock>"
52
+ space_encoded_in_offset: Optional[MockAddrSpace] = None
53
+
54
+ def getRegisterName(self) -> str:
55
+ return self.register_name
56
+
57
+ def getSpaceFromConst(self) -> Optional[MockAddrSpace]:
58
+ return self.space_encoded_in_offset
59
+
60
+
61
+ @dataclass(eq=True)
62
+ class MockPcodeOp:
63
+ """
64
+ Mock P-Code Op
65
+ """
66
+
67
+ opcode: "OpCode"
68
+ output: Optional[MockVarnode]
69
+ inputs: List[MockVarnode]
70
+
71
+
72
+ BEHAVIORS = BehaviorFactory()
73
+
74
+
75
+ @dataclass
76
+ class MockIRSB:
77
+ """
78
+ Mock IRSB
79
+ """
80
+
81
+ _ops: List[MockPcodeOp]
82
+ addr: int = 0
83
+ behaviors: BehaviorFactory = BEHAVIORS
84
+
85
+
86
+ OP = MockPcodeOp
87
+ VN = MockVarnode
88
+
89
+
90
+ @unittest.skipUnless(pypcode, "pypcode is not available")
91
+ class TestPcodeEmulatorMixin(unittest.TestCase):
92
+ """
93
+ Test P-Code engine emulator mixin
94
+ """
95
+
96
+ @staticmethod
97
+ def _step_irsb(irsb, state=None):
98
+ emulator = PcodeEmulatorMixin()
99
+ # FIMXE: *sigh* it's not so easy to use the mixin in isolation
100
+
101
+ emulator.project = angr.load_shellcode(b"\x90", arch="AMD64")
102
+ if state is None:
103
+ state = SimState(arch="AMD64")
104
+ emulator.state = state
105
+ emulator.state.history.recent_bbl_addrs.append(0)
106
+ emulator.successors = SimSuccessors(0, emulator.state)
107
+ emulator.handle_pcode_block(irsb)
108
+ emulator.successors.processed = True
109
+ return emulator.successors
110
+
111
+ def _test_branch_and_call_common(self, opcode: "OpCode"):
112
+ target_addr = 0x12345678
113
+ successors = self._step_irsb(
114
+ MockIRSB(
115
+ [
116
+ OP(
117
+ OpCode.IMARK,
118
+ None,
119
+ [VN(RAM_SPACE, 0, 1)],
120
+ ),
121
+ OP(
122
+ opcode,
123
+ None,
124
+ [VN(RAM_SPACE, target_addr, 1)],
125
+ ),
126
+ ]
127
+ )
128
+ )
129
+
130
+ assert len(successors.all_successors) == 1
131
+ state = successors.all_successors[0]
132
+ assert state.solver.eval(state.regs.pc == target_addr)
133
+
134
+ def test_branch(self):
135
+ self._test_branch_and_call_common(OpCode.BRANCH)
136
+
137
+ def test_call(self):
138
+ self._test_branch_and_call_common(OpCode.CALL)
139
+
140
+ def _test_branchind_and_callind_common(self, opcode: "OpCode"):
141
+ target_addr = 0x12345678
142
+ target_pointer_addr = 0x100000
143
+ target_pointer_size = 8
144
+
145
+ state = SimState(arch="AMD64")
146
+ state.memory.store(target_pointer_addr, claripy.BVV(target_addr, 8 * target_pointer_size), endness="IEnd_LE")
147
+
148
+ successors = self._step_irsb(
149
+ MockIRSB(
150
+ [
151
+ OP(
152
+ OpCode.IMARK,
153
+ None,
154
+ [VN(RAM_SPACE, 0, 1)],
155
+ ),
156
+ OP(
157
+ opcode,
158
+ None,
159
+ [VN(RAM_SPACE, target_pointer_addr, target_pointer_size)],
160
+ ),
161
+ ]
162
+ ),
163
+ state,
164
+ )
165
+
166
+ assert len(successors.all_successors) == 1
167
+ state = successors.all_successors[0]
168
+ assert state.solver.eval(state.regs.pc == target_addr)
169
+
170
+ def test_branchind(self):
171
+ self._test_branchind_and_callind_common(OpCode.BRANCHIND)
172
+
173
+ def test_callind(self):
174
+ self._test_branchind_and_callind_common(OpCode.CALLIND)
175
+
176
+ def _test_cbranch_common(self, cond: claripy.BVV):
177
+ condition_addr = 0x100000
178
+ target_addr = 0x12345678
179
+ fallthru_addr = 1
180
+
181
+ state = SimState(arch="AMD64")
182
+ state.memory.store(condition_addr, cond)
183
+
184
+ successors = self._step_irsb(
185
+ MockIRSB(
186
+ [
187
+ OP(
188
+ OpCode.IMARK,
189
+ None,
190
+ [VN(RAM_SPACE, 0, fallthru_addr)],
191
+ ),
192
+ OP(
193
+ OpCode.CBRANCH,
194
+ None,
195
+ [VN(RAM_SPACE, target_addr, 8), VN(RAM_SPACE, condition_addr, 1)],
196
+ ),
197
+ ]
198
+ ),
199
+ state,
200
+ )
201
+
202
+ if cond.concrete:
203
+ if state.solver.eval(cond):
204
+ sat_pc, unsat_pc = target_addr, fallthru_addr
205
+ else:
206
+ sat_pc, unsat_pc = fallthru_addr, target_addr
207
+
208
+ assert len(successors.successors) == 1
209
+ state = successors.successors[0]
210
+ assert state.solver.eval(state.regs.pc == sat_pc)
211
+
212
+ assert len(successors.unsat_successors) == 1
213
+ state = successors.unsat_successors[0]
214
+ assert state.solver.eval(state.regs.pc == unsat_pc)
215
+ else:
216
+ assert len(successors.successors) == 2
217
+ pcs = {state.solver.eval(state.regs.pc) for state in successors.successors}
218
+ assert pcs == {target_addr, fallthru_addr}
219
+
220
+ def test_cbranch_taken(self):
221
+ self._test_cbranch_common(claripy.BVV(1, 8))
222
+ self._test_cbranch_common(claripy.BVV(2, 8))
223
+
224
+ def test_cbranch_not_taken(self):
225
+ self._test_cbranch_common(claripy.BVV(0, 8))
226
+
227
+ def test_cbranch_symbolic(self):
228
+ self._test_cbranch_common(claripy.BVS("condition", 8))
229
+
230
+ def _test_rel_cbranch_common(self, cond: claripy.BVV):
231
+ condition_addr = 0x100000
232
+ start_addr = 0
233
+ target_addr = start_addr
234
+ target_stmt = 1
235
+ instruction_len = 1
236
+ fallthru_addr = start_addr + instruction_len
237
+ cbranch_idx = 2
238
+
239
+ state = SimState(arch="AMD64")
240
+ state.memory.store(condition_addr, cond)
241
+
242
+ successors = self._step_irsb(
243
+ MockIRSB(
244
+ [
245
+ # Op 0
246
+ OP(
247
+ OpCode.IMARK,
248
+ None,
249
+ [VN(RAM_SPACE, start_addr, instruction_len)],
250
+ ),
251
+ # Op 1
252
+ OP(
253
+ OpCode.INT_ADD,
254
+ VN(UNIQUE_SPACE, 0, 8),
255
+ [VN(UNIQUE_SPACE, 0, 8), VN(CONST_SPACE, 1, 8)],
256
+ ),
257
+ # Op 2
258
+ OP(
259
+ OpCode.CBRANCH,
260
+ None,
261
+ [VN(CONST_SPACE, target_stmt - cbranch_idx, 8), VN(RAM_SPACE, condition_addr, 1)],
262
+ ),
263
+ ]
264
+ ),
265
+ state,
266
+ )
267
+
268
+ if cond.concrete:
269
+ if state.solver.eval(cond):
270
+ sat_pc, unsat_pc = target_addr, fallthru_addr
271
+ sat_stmt, unsat_stmt = target_stmt, 0
272
+ else:
273
+ sat_pc, unsat_pc = fallthru_addr, target_addr
274
+ sat_stmt, unsat_stmt = 0, target_stmt
275
+
276
+ assert len(successors.successors) == 1
277
+ state = successors.successors[0]
278
+ assert state.solver.eval(state.regs.pc == sat_pc)
279
+ assert state.scratch.statement_offset == sat_stmt
280
+
281
+ assert len(successors.unsat_successors) == 1
282
+ state = successors.unsat_successors[0]
283
+ assert state.solver.eval(state.regs.pc == unsat_pc)
284
+ assert state.scratch.statement_offset == unsat_stmt
285
+
286
+ else:
287
+ assert len(successors.successors) == 2
288
+ pcs = {
289
+ (state.solver.eval(state.regs.pc), state.scratch.statement_offset) for state in successors.successors
290
+ }
291
+ assert pcs == {(target_addr, target_stmt), (fallthru_addr, 0)}
292
+
293
+ def test_rel_cbranch_taken(self):
294
+ self._test_rel_cbranch_common(claripy.BVV(1, 8))
295
+ self._test_rel_cbranch_common(claripy.BVV(2, 8))
296
+
297
+ def test_rel_cbranch_not_taken(self):
298
+ self._test_rel_cbranch_common(claripy.BVV(0, 8))
299
+
300
+ def test_rel_cbranch_symbolic(self):
301
+ self._test_cbranch_common(claripy.BVS("condition", 8))
302
+
303
+ def test_load_store(self):
304
+ addr = 0x133700000
305
+ addr2 = 0x999900000
306
+ value = claripy.BVV(0xFEDCBA9876543210, 64)
307
+ state = SimState(arch="AMD64")
308
+ state.memory.store(addr, value)
309
+ state.regs.rax = addr
310
+
311
+ # Load value from RAM[addr] and store it into RAM[addr2]
312
+
313
+ successors = self._step_irsb(
314
+ MockIRSB(
315
+ [
316
+ OP(
317
+ OpCode.IMARK,
318
+ None,
319
+ [VN(RAM_SPACE, 0, 1)],
320
+ ),
321
+ OP(
322
+ OpCode.COPY,
323
+ VN(UNIQUE_SPACE, 0, 8),
324
+ [VN(CONST_SPACE, addr, 8)],
325
+ ),
326
+ OP(
327
+ OpCode.LOAD,
328
+ VN(UNIQUE_SPACE, 8, 8),
329
+ [VN(CONST_SPACE, 0xCACACACA, 0, space_encoded_in_offset=RAM_SPACE), VN(UNIQUE_SPACE, 0, 8)],
330
+ ),
331
+ OP(
332
+ OpCode.COPY,
333
+ VN(UNIQUE_SPACE, 0, 8),
334
+ [VN(CONST_SPACE, addr2, 8)],
335
+ ),
336
+ OP(
337
+ OpCode.STORE,
338
+ None,
339
+ [
340
+ VN(CONST_SPACE, 0xCACACACA, 0, space_encoded_in_offset=RAM_SPACE),
341
+ VN(UNIQUE_SPACE, 0, 8),
342
+ VN(UNIQUE_SPACE, 8, 8),
343
+ ],
344
+ ),
345
+ ],
346
+ ),
347
+ state,
348
+ )
349
+
350
+ new_state = successors.successors[0]
351
+ assert new_state.solver.is_true(new_state.memory.load(addr2, 8) == value)
352
+
353
+ def _test_single_arith_binary_op(self, opcode: "OpCode"):
354
+ opcode_to_operation = {
355
+ OpCode.BOOL_AND: operator.and_,
356
+ OpCode.BOOL_OR: operator.or_,
357
+ OpCode.BOOL_XOR: operator.xor,
358
+ OpCode.INT_ADD: operator.add,
359
+ OpCode.INT_AND: operator.and_,
360
+ OpCode.INT_DIV: operator.floordiv,
361
+ OpCode.INT_EQUAL: operator.eq,
362
+ OpCode.INT_LEFT: operator.lshift,
363
+ OpCode.INT_LESS: operator.lt,
364
+ OpCode.INT_LESSEQUAL: operator.le,
365
+ OpCode.INT_MULT: operator.mul,
366
+ OpCode.INT_NOTEQUAL: operator.ne,
367
+ OpCode.INT_OR: operator.or_,
368
+ OpCode.INT_REM: operator.mod,
369
+ OpCode.INT_RIGHT: claripy.LShR,
370
+ OpCode.INT_SLESS: claripy.SLT,
371
+ OpCode.INT_SLESSEQUAL: claripy.SLE,
372
+ OpCode.INT_SRIGHT: operator.rshift,
373
+ OpCode.INT_SUB: operator.sub,
374
+ OpCode.INT_XOR: operator.xor,
375
+ }
376
+
377
+ operation = opcode_to_operation.get(opcode)
378
+ assert operation is not None
379
+
380
+ is_boolean = opcode in {OpCode.BOOL_AND, OpCode.BOOL_OR, OpCode.BOOL_XOR}
381
+ is_comparison = opcode in {
382
+ OpCode.INT_EQUAL,
383
+ OpCode.INT_LESS,
384
+ OpCode.INT_LESSEQUAL,
385
+ OpCode.INT_NOTEQUAL,
386
+ OpCode.INT_SLESS,
387
+ OpCode.INT_SLESSEQUAL,
388
+ }
389
+
390
+ operand_size = 1 if is_boolean else 4
391
+
392
+ result_addr = 0x100000
393
+ result_size = 1 if is_comparison else operand_size
394
+
395
+ x_addr, x = 0, claripy.BVS("x", operand_size * 8)
396
+ y_addr, y = operand_size, claripy.BVS("y", operand_size * 8)
397
+
398
+ state = SimState(arch="AMD64", remove_options={"SIMPLIFY_MEMORY_WRITES"})
399
+ state.memory.store(x_addr, x, endness="Iend_LE")
400
+ state.memory.store(y_addr, y, endness="Iend_LE")
401
+
402
+ successors = self._step_irsb(
403
+ MockIRSB(
404
+ [
405
+ OP(
406
+ OpCode.IMARK,
407
+ None,
408
+ [VN(RAM_SPACE, 0, 1)],
409
+ ),
410
+ OP(
411
+ opcode,
412
+ VN(RAM_SPACE, result_addr, operand_size),
413
+ [VN(RAM_SPACE, x_addr, operand_size), VN(RAM_SPACE, y_addr, operand_size)],
414
+ ),
415
+ ]
416
+ ),
417
+ state,
418
+ )
419
+
420
+ assert len(successors.all_successors) == 1
421
+ state = successors.all_successors[0]
422
+ assert state.solver.eval(state.regs.pc == 1)
423
+
424
+ result = state.memory.load(result_addr, result_size, endness="Iend_LE")
425
+
426
+ if is_boolean:
427
+ booleanize = angr.engines.pcode.behavior.OpBehavior.booleanize
428
+ expected_result = operation(booleanize(x), booleanize(y)).zero_extend(7)
429
+ elif is_comparison:
430
+ expected_result = claripy.If(operation(x, y), claripy.BVV(1, 1), claripy.BVV(0, 1)).zero_extend(7)
431
+ else:
432
+ expected_result = operation(x, y)
433
+
434
+ assert claripy.backends.z3.is_true(result == expected_result)
435
+
436
+ def test_arith_binary_ops(self):
437
+ for opcode in [
438
+ OpCode.BOOL_AND,
439
+ OpCode.BOOL_OR,
440
+ OpCode.BOOL_XOR,
441
+ OpCode.INT_ADD,
442
+ OpCode.INT_AND,
443
+ OpCode.INT_DIV,
444
+ OpCode.INT_EQUAL,
445
+ OpCode.INT_LEFT,
446
+ OpCode.INT_LESS,
447
+ OpCode.INT_LESSEQUAL,
448
+ OpCode.INT_MULT,
449
+ OpCode.INT_NOTEQUAL,
450
+ OpCode.INT_OR,
451
+ OpCode.INT_REM,
452
+ OpCode.INT_RIGHT,
453
+ # OpCode.INT_SDIV, # FIXME
454
+ OpCode.INT_SLESS,
455
+ OpCode.INT_SLESSEQUAL,
456
+ OpCode.INT_SRIGHT,
457
+ OpCode.INT_SUB,
458
+ OpCode.INT_XOR,
459
+ ]:
460
+ with self.subTest(opcode):
461
+ self._test_single_arith_binary_op(opcode)
462
+
463
+ def _test_single_arith_unary_op(self, opcode: "OpCode"):
464
+ opcode_to_operation = {
465
+ OpCode.INT_NEGATE: operator.inv,
466
+ OpCode.INT_2COMP: operator.neg,
467
+ }
468
+
469
+ operation = opcode_to_operation.get(opcode)
470
+ assert operation is not None
471
+
472
+ operand_size = 4
473
+
474
+ result_size = operand_size
475
+ result_addr = 0x100000
476
+
477
+ x_addr, x = 0, claripy.BVS("x", operand_size * 8)
478
+
479
+ state = SimState(arch="AMD64", remove_options={"SIMPLIFY_MEMORY_WRITES"})
480
+ state.memory.store(x_addr, x, endness="Iend_LE")
481
+
482
+ successors = self._step_irsb(
483
+ MockIRSB(
484
+ [
485
+ OP(
486
+ OpCode.IMARK,
487
+ None,
488
+ [VN(RAM_SPACE, 0, 1)],
489
+ ),
490
+ OP(
491
+ opcode,
492
+ VN(RAM_SPACE, result_addr, operand_size),
493
+ [VN(RAM_SPACE, x_addr, operand_size)],
494
+ ),
495
+ ]
496
+ ),
497
+ state,
498
+ )
499
+
500
+ assert len(successors.all_successors) == 1
501
+ state = successors.all_successors[0]
502
+ assert state.solver.eval(state.regs.pc == 1)
503
+
504
+ result = state.memory.load(result_addr, result_size, endness="Iend_LE")
505
+ expected_result = operation(x)
506
+
507
+ assert claripy.backends.z3.is_true(result == expected_result)
508
+
509
+ def test_arith_unary_ops(self):
510
+ for opcode in [
511
+ OpCode.INT_NEGATE,
512
+ OpCode.INT_2COMP,
513
+ ]:
514
+ with self.subTest(opcode):
515
+ self._test_single_arith_unary_op(opcode)
516
+
517
+ def _test_other_unary_common(self, opcode, input_value, expected_value):
518
+ operand_addr = 0x200000
519
+ operand_size = input_value.size() // 8
520
+
521
+ result_addr = 0x100000
522
+ result_size = expected_value.size() // 8
523
+
524
+ state = SimState(arch="AMD64", remove_options={"SIMPLIFY_MEMORY_WRITES"})
525
+ state.memory.store(operand_addr, input_value, endness="Iend_LE")
526
+ state.memory.store(result_addr, claripy.BVV(b"\xCA" * result_size), endness="Iend_LE")
527
+
528
+ successors = self._step_irsb(
529
+ MockIRSB(
530
+ [
531
+ OP(
532
+ OpCode.IMARK,
533
+ None,
534
+ [VN(RAM_SPACE, 0, 1)],
535
+ ),
536
+ OP(
537
+ opcode,
538
+ VN(RAM_SPACE, result_addr, result_size),
539
+ [VN(RAM_SPACE, operand_addr, operand_size)],
540
+ ),
541
+ ],
542
+ ),
543
+ state,
544
+ )
545
+
546
+ assert len(successors.all_successors) == 1
547
+ state = successors.successors[0]
548
+ v = state.memory.load(result_addr, result_size, endness="Iend_LE")
549
+ assert state.solver.eval(v == expected_value)
550
+
551
+ def test_bool_negate(self):
552
+ # FIXME: Should values >1 be considered true? If some op only clears the 0th bit this may be incorrect
553
+ self._test_other_unary_common(OpCode.BOOL_NEGATE, claripy.BVV(0, 8), claripy.BVV(1, 8))
554
+ self._test_other_unary_common(OpCode.BOOL_NEGATE, claripy.BVV(1, 8), claripy.BVV(0, 8))
555
+ self._test_other_unary_common(OpCode.BOOL_NEGATE, claripy.BVV(0xFF, 8), claripy.BVV(0, 8))
556
+
557
+ def test_zext(self):
558
+ self._test_other_unary_common(OpCode.INT_ZEXT, claripy.BVV(0x7234, 16), claripy.BVV(0x7234, 16))
559
+ self._test_other_unary_common(OpCode.INT_ZEXT, claripy.BVV(0x7234, 16), claripy.BVV(0x0000_7234, 32))
560
+ self._test_other_unary_common(OpCode.INT_ZEXT, claripy.BVV(0x8234, 16), claripy.BVV(0x0000_8234, 32))
561
+
562
+ def test_sext(self):
563
+ self._test_other_unary_common(OpCode.INT_SEXT, claripy.BVV(0x7234, 16), claripy.BVV(0x7234, 16))
564
+ self._test_other_unary_common(OpCode.INT_SEXT, claripy.BVV(0x7234, 16), claripy.BVV(0x0000_7234, 32))
565
+ self._test_other_unary_common(OpCode.INT_SEXT, claripy.BVV(0x8234, 16), claripy.BVV(0xFFFF_8234, 32))
566
+
567
+ def test_popcount(self):
568
+ self._test_other_unary_common(OpCode.POPCOUNT, claripy.BVV(0, 32), claripy.BVV(0, 32))
569
+ self._test_other_unary_common(OpCode.POPCOUNT, claripy.BVV(0x12345678, 32), claripy.BVV(13, 32))
570
+ self._test_other_unary_common(OpCode.POPCOUNT, claripy.BVV(0xFFFFFFFF, 32), claripy.BVV(32, 32))
571
+
572
+ # TODO: Add tests for the following ops:
573
+ # * = FIXME
574
+ # ! = Not Implemented
575
+ #
576
+ # ! OpCode.CPOOLREF
577
+ # OpCode.FLOAT_ABS
578
+ # OpCode.FLOAT_ADD
579
+ # OpCode.FLOAT_CEIL
580
+ # OpCode.FLOAT_DIV
581
+ # OpCode.FLOAT_EQUAL
582
+ # OpCode.FLOAT_FLOAT2FLOAT
583
+ # OpCode.FLOAT_FLOOR
584
+ # OpCode.FLOAT_INT2FLOAT
585
+ # OpCode.FLOAT_LESS
586
+ # OpCode.FLOAT_LESSEQUAL
587
+ # OpCode.FLOAT_MULT
588
+ # OpCode.FLOAT_NAN
589
+ # OpCode.FLOAT_NEG
590
+ # OpCode.FLOAT_NOTEQUAL
591
+ # OpCode.FLOAT_ROUND
592
+ # OpCode.FLOAT_SQRT
593
+ # OpCode.FLOAT_SUB
594
+ # OpCode.FLOAT_TRUNC
595
+ # OpCode.INT_CARRY
596
+ # OpCode.INT_SBORROW
597
+ # OpCode.INT_SCARRY
598
+ # * OpCode.INT_SDIV
599
+ # * OpCode.INT_SREM
600
+ # ! OpCode.NEW
601
+ # OpCode.RETURN
602
+
603
+
604
+ if __name__ == "__main__":
605
+ log.setLevel(logging.DEBUG)
606
+ logging.getLogger("angr.engines.pcode").setLevel(logging.DEBUG)
607
+ unittest.main()