angr 9.2.87__py3-none-win_amd64.whl → 9.2.89__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 (249) hide show
  1. angr/__init__.py +4 -1
  2. angr/analyses/decompiler/clinic.py +16 -0
  3. angr/analyses/decompiler/decompiler.py +3 -0
  4. angr/analyses/decompiler/optimization_passes/__init__.py +5 -0
  5. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +108 -0
  6. angr/analyses/decompiler/optimization_passes/optimization_pass.py +17 -4
  7. angr/analyses/decompiler/optimization_passes/return_duplicator.py +4 -32
  8. angr/analyses/decompiler/structured_codegen/c.py +12 -2
  9. angr/analyses/decompiler/utils.py +13 -0
  10. angr/analyses/typehoon/dfa.py +108 -0
  11. angr/analyses/typehoon/lifter.py +34 -2
  12. angr/analyses/typehoon/simple_solver.py +1043 -503
  13. angr/analyses/typehoon/translator.py +13 -4
  14. angr/analyses/typehoon/typeconsts.py +117 -36
  15. angr/analyses/typehoon/typehoon.py +31 -11
  16. angr/analyses/typehoon/typevars.py +88 -21
  17. angr/analyses/typehoon/variance.py +10 -0
  18. angr/analyses/variable_recovery/engine_ail.py +28 -9
  19. angr/analyses/variable_recovery/engine_base.py +50 -43
  20. angr/analyses/variable_recovery/variable_recovery_base.py +16 -3
  21. angr/analyses/variable_recovery/variable_recovery_fast.py +14 -5
  22. angr/exploration_techniques/tracer.py +2 -0
  23. angr/lib/angr_native.dll +0 -0
  24. angr/misc/autoimport.py +26 -0
  25. angr/procedures/definitions/__init__.py +32 -3
  26. angr/utils/constants.py +1 -0
  27. angr/utils/graph.py +20 -1
  28. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/METADATA +7 -6
  29. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/RECORD +33 -245
  30. angr-9.2.89.dist-info/top_level.txt +1 -0
  31. angr/procedures/definitions/ntdll.py +0 -12
  32. angr-9.2.87.dist-info/top_level.txt +0 -2
  33. tests/__init__.py +0 -0
  34. tests/analyses/__init__.py +0 -0
  35. tests/analyses/cfg/__init__.py +0 -0
  36. tests/analyses/cfg/test_cfg_clflush.py +0 -43
  37. tests/analyses/cfg/test_cfg_get_any_node.py +0 -34
  38. tests/analyses/cfg/test_cfg_manager.py +0 -32
  39. tests/analyses/cfg/test_cfg_model.py +0 -55
  40. tests/analyses/cfg/test_cfg_patching.py +0 -378
  41. tests/analyses/cfg/test_cfg_rust_got_resolution.py +0 -36
  42. tests/analyses/cfg/test_cfg_thumb_firmware.py +0 -50
  43. tests/analyses/cfg/test_cfg_vex_postprocessor.py +0 -27
  44. tests/analyses/cfg/test_cfgemulated.py +0 -634
  45. tests/analyses/cfg/test_cfgfast.py +0 -1123
  46. tests/analyses/cfg/test_cfgfast_soot.py +0 -38
  47. tests/analyses/cfg/test_const_resolver.py +0 -38
  48. tests/analyses/cfg/test_iat_resolver.py +0 -37
  49. tests/analyses/cfg/test_jumptables.py +0 -3008
  50. tests/analyses/cfg/test_noop_blocks.py +0 -54
  51. tests/analyses/cfg_slice_to_sink/__init__.py +0 -0
  52. tests/analyses/cfg_slice_to_sink/test_cfg_slice_to_sink.py +0 -93
  53. tests/analyses/cfg_slice_to_sink/test_graph.py +0 -114
  54. tests/analyses/cfg_slice_to_sink/test_transitions.py +0 -28
  55. tests/analyses/decompiler/__init__.py +0 -0
  56. tests/analyses/decompiler/test_baseptr_save_simplifier.py +0 -80
  57. tests/analyses/decompiler/test_decompiler.py +0 -3336
  58. tests/analyses/decompiler/test_peephole_optimizations.py +0 -48
  59. tests/analyses/decompiler/test_propagator_loops.py +0 -101
  60. tests/analyses/decompiler/test_structurer.py +0 -275
  61. tests/analyses/reaching_definitions/__init__.py +0 -0
  62. tests/analyses/reaching_definitions/test_dep_graph.py +0 -432
  63. tests/analyses/reaching_definitions/test_function_handler.py +0 -131
  64. tests/analyses/reaching_definitions/test_heap_allocator.py +0 -46
  65. tests/analyses/reaching_definitions/test_rd_state.py +0 -78
  66. tests/analyses/reaching_definitions/test_reachingdefinitions.py +0 -463
  67. tests/analyses/reaching_definitions/test_subject.py +0 -76
  68. tests/analyses/test_bindiff.py +0 -52
  69. tests/analyses/test_block_simplifier.py +0 -112
  70. tests/analyses/test_boyscout.py +0 -104
  71. tests/analyses/test_calling_convention_analysis.py +0 -352
  72. tests/analyses/test_callsite_maker.py +0 -60
  73. tests/analyses/test_cdg.py +0 -165
  74. tests/analyses/test_cfb.py +0 -37
  75. tests/analyses/test_class_identifier.py +0 -46
  76. tests/analyses/test_clinic.py +0 -30
  77. tests/analyses/test_codetagging.py +0 -32
  78. tests/analyses/test_constantpropagation.py +0 -88
  79. tests/analyses/test_ddg.py +0 -95
  80. tests/analyses/test_ddg_global_var_dependencies.py +0 -83
  81. tests/analyses/test_ddg_memvar_addresses.py +0 -40
  82. tests/analyses/test_disassembly.py +0 -121
  83. tests/analyses/test_find_objects_static.py +0 -35
  84. tests/analyses/test_flirt.py +0 -49
  85. tests/analyses/test_identifier.py +0 -33
  86. tests/analyses/test_init_finder.py +0 -38
  87. tests/analyses/test_proximitygraph.py +0 -31
  88. tests/analyses/test_reassembler.py +0 -295
  89. tests/analyses/test_regionidentifier.py +0 -27
  90. tests/analyses/test_slicing.py +0 -164
  91. tests/analyses/test_stack_pointer_tracker.py +0 -74
  92. tests/analyses/test_static_hooker.py +0 -28
  93. tests/analyses/test_typehoon.py +0 -55
  94. tests/analyses/test_variablerecovery.py +0 -464
  95. tests/analyses/test_vfg.py +0 -221
  96. tests/analyses/test_vtable.py +0 -31
  97. tests/analyses/test_xrefs.py +0 -77
  98. tests/common.py +0 -128
  99. tests/engines/__init__.py +0 -0
  100. tests/engines/light/__init__.py +0 -0
  101. tests/engines/light/test_data.py +0 -17
  102. tests/engines/pcode/__init__.py +0 -0
  103. tests/engines/pcode/test_emulate.py +0 -607
  104. tests/engines/pcode/test_pcode.py +0 -84
  105. tests/engines/test_actions.py +0 -27
  106. tests/engines/test_hook.py +0 -112
  107. tests/engines/test_java.py +0 -697
  108. tests/engines/test_unicorn.py +0 -518
  109. tests/engines/vex/__init__.py +0 -0
  110. tests/engines/vex/test_lifter.py +0 -124
  111. tests/engines/vex/test_vex.py +0 -574
  112. tests/exploration_techniques/__init__.py +0 -0
  113. tests/exploration_techniques/test_cacher.py +0 -45
  114. tests/exploration_techniques/test_director.py +0 -67
  115. tests/exploration_techniques/test_driller_core.py +0 -48
  116. tests/exploration_techniques/test_loop_seer.py +0 -158
  117. tests/exploration_techniques/test_memory_watcher.py +0 -46
  118. tests/exploration_techniques/test_oppologist.py +0 -65
  119. tests/exploration_techniques/test_spiller.py +0 -82
  120. tests/exploration_techniques/test_stochastic.py +0 -40
  121. tests/exploration_techniques/test_tech_builder.py +0 -61
  122. tests/exploration_techniques/test_tracer.py +0 -856
  123. tests/exploration_techniques/test_unique.py +0 -40
  124. tests/exploration_techniques/test_veritesting.py +0 -120
  125. tests/factory/__init__.py +0 -0
  126. tests/factory/block/__init__.py +0 -0
  127. tests/factory/block/test_block_cache.py +0 -33
  128. tests/factory/block/test_keystone.py +0 -106
  129. tests/factory/test_argc.py +0 -101
  130. tests/factory/test_argc_sym.py +0 -110
  131. tests/factory/test_argv.py +0 -158
  132. tests/factory/test_callable.py +0 -266
  133. tests/factory/test_windows_args.py +0 -36
  134. tests/knowledge_plugins/__init__.py +0 -0
  135. tests/knowledge_plugins/cfg/__init__.py +0 -0
  136. tests/knowledge_plugins/cfg/test_cfg_manager.py +0 -36
  137. tests/knowledge_plugins/functions/__init__.py +0 -0
  138. tests/knowledge_plugins/functions/test_function.py +0 -91
  139. tests/knowledge_plugins/functions/test_function2.py +0 -79
  140. tests/knowledge_plugins/functions/test_function_manager.py +0 -139
  141. tests/knowledge_plugins/functions/test_prototypes.py +0 -53
  142. tests/knowledge_plugins/key_definitions/__init__.py +0 -0
  143. tests/knowledge_plugins/key_definitions/test_atoms.py +0 -24
  144. tests/knowledge_plugins/key_definitions/test_environment.py +0 -126
  145. tests/knowledge_plugins/key_definitions/test_heap_address.py +0 -27
  146. tests/knowledge_plugins/key_definitions/test_live_definitions.py +0 -72
  147. tests/knowledge_plugins/test_dwarf_variables.py +0 -240
  148. tests/knowledge_plugins/test_kb_plugins.py +0 -91
  149. tests/knowledge_plugins/test_kb_plugins_dwarf.py +0 -36
  150. tests/knowledge_plugins/test_patches.py +0 -48
  151. tests/misc/__init__.py +0 -0
  152. tests/misc/test_hookset.py +0 -57
  153. tests/perf/__init__.py +0 -0
  154. tests/perf/perf_cfgemulated.py +0 -19
  155. tests/perf/perf_cfgfast.py +0 -18
  156. tests/perf/perf_concrete_execution.py +0 -41
  157. tests/perf/perf_siminspect_nop.py +0 -36
  158. tests/perf/perf_state_copy.py +0 -33
  159. tests/perf/perf_unicorn_0.py +0 -27
  160. tests/perf/perf_unicorn_1.py +0 -23
  161. tests/procedures/__init__.py +0 -0
  162. tests/procedures/glibc/__init__.py +0 -0
  163. tests/procedures/glibc/test_ctype_locale.py +0 -164
  164. tests/procedures/libc/__init__.py +0 -0
  165. tests/procedures/libc/test_fgets.py +0 -53
  166. tests/procedures/libc/test_scanf.py +0 -205
  167. tests/procedures/libc/test_sprintf.py +0 -44
  168. tests/procedures/libc/test_sscanf.py +0 -63
  169. tests/procedures/libc/test_strcasecmp.py +0 -37
  170. tests/procedures/libc/test_string.py +0 -1102
  171. tests/procedures/libc/test_strtol.py +0 -78
  172. tests/procedures/linux_kernel/__init__.py +0 -0
  173. tests/procedures/linux_kernel/test_lseek.py +0 -174
  174. tests/procedures/posix/__init__.py +0 -0
  175. tests/procedures/posix/test_chroot.py +0 -33
  176. tests/procedures/posix/test_getenv.py +0 -78
  177. tests/procedures/posix/test_pwrite_pread.py +0 -57
  178. tests/procedures/posix/test_sim_time.py +0 -46
  179. tests/procedures/posix/test_unlink.py +0 -46
  180. tests/procedures/test_project_resolve_simproc.py +0 -43
  181. tests/procedures/test_sim_procedure.py +0 -117
  182. tests/procedures/test_stub_procedure_args.py +0 -53
  183. tests/serialization/__init__.py +0 -0
  184. tests/serialization/test_db.py +0 -197
  185. tests/serialization/test_pickle.py +0 -95
  186. tests/serialization/test_serialization.py +0 -132
  187. tests/serialization/test_vault.py +0 -169
  188. tests/sim/__init__.py +0 -3
  189. tests/sim/exec_func/__init__.py +0 -0
  190. tests/sim/exec_func/test_mem_funcs.py +0 -55
  191. tests/sim/exec_func/test_str_funcs.py +0 -93
  192. tests/sim/exec_func/test_syscall_result.py +0 -39
  193. tests/sim/exec_insn/__init__.py +0 -0
  194. tests/sim/exec_insn/test_adc.py +0 -44
  195. tests/sim/exec_insn/test_ops.py +0 -83
  196. tests/sim/exec_insn/test_rcr.py +0 -26
  197. tests/sim/exec_insn/test_rol.py +0 -51
  198. tests/sim/exec_insn/test_signed_div.py +0 -34
  199. tests/sim/exec_insn/test_sqrt.py +0 -56
  200. tests/sim/options/__init__.py +0 -0
  201. tests/sim/options/test_0div.py +0 -54
  202. tests/sim/options/test_symbolic_fd.py +0 -59
  203. tests/sim/options/test_unsupported.py +0 -34
  204. tests/sim/test_accuracy.py +0 -137
  205. tests/sim/test_checkbyte.py +0 -53
  206. tests/sim/test_echo.py +0 -36
  207. tests/sim/test_fauxware.py +0 -202
  208. tests/sim/test_self_modifying_code.py +0 -65
  209. tests/sim/test_simple_api.py +0 -36
  210. tests/sim/test_simulation_manager.py +0 -147
  211. tests/sim/test_stack_alignment.py +0 -65
  212. tests/sim/test_state.py +0 -303
  213. tests/sim/test_state_customization.py +0 -54
  214. tests/sim/test_symbol_hooked_by.py +0 -49
  215. tests/simos/__init__.py +0 -0
  216. tests/simos/windows/__init__.py +0 -0
  217. tests/simos/windows/test_windows_stack_cookie.py +0 -58
  218. tests/state_plugins/__init__.py +0 -0
  219. tests/state_plugins/inspect/__init__.py +0 -0
  220. tests/state_plugins/inspect/test_inspect.py +0 -310
  221. tests/state_plugins/inspect/test_syscall_override.py +0 -90
  222. tests/state_plugins/posix/__init__.py +0 -0
  223. tests/state_plugins/posix/test_file_struct_funcs.py +0 -56
  224. tests/state_plugins/posix/test_files.py +0 -69
  225. tests/state_plugins/posix/test_posix.py +0 -72
  226. tests/state_plugins/solver/__init__.py +0 -0
  227. tests/state_plugins/solver/test_simsolver.py +0 -58
  228. tests/state_plugins/solver/test_symbolic.py +0 -153
  229. tests/state_plugins/solver/test_variable_registration.py +0 -46
  230. tests/state_plugins/test_callstack.py +0 -54
  231. tests/state_plugins/test_gdb_plugin.py +0 -35
  232. tests/state_plugins/test_multi_open_file.py +0 -47
  233. tests/state_plugins/test_symbolization.py +0 -38
  234. tests/storage/__init__.py +0 -0
  235. tests/storage/test_memory.py +0 -960
  236. tests/storage/test_memory_merge.py +0 -114
  237. tests/storage/test_memview.py +0 -205
  238. tests/storage/test_mmap.py +0 -26
  239. tests/storage/test_multivalues.py +0 -44
  240. tests/storage/test_permissions.py +0 -32
  241. tests/storage/test_ptmalloc.py +0 -291
  242. tests/storage/test_relro_perm.py +0 -49
  243. tests/test_calling_conventions.py +0 -86
  244. tests/test_types.py +0 -329
  245. tests/utils/__init__.py +0 -0
  246. tests/utils/test_graph.py +0 -41
  247. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/LICENSE +0 -0
  248. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/WHEEL +0 -0
  249. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/entry_points.txt +0 -0
@@ -1,607 +0,0 @@
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()
@@ -1,84 +0,0 @@
1
- #!/usr/bin/env python3
2
- from unittest import TestCase, skipUnless, main
3
- import os
4
-
5
- import archinfo
6
- import angr
7
-
8
- try:
9
- import pypcode
10
- except ModuleNotFoundError:
11
- pypcode = None
12
-
13
-
14
- test_location = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "..", "..", "binaries", "tests")
15
-
16
-
17
- # pylint: disable=missing-class-docstring
18
- # pylint: disable=no-self-use
19
- @skipUnless(pypcode, "pypcode not available")
20
- class TestPcodeEngine(TestCase):
21
- def test_shellcode(self):
22
- """
23
- Test basic CFG recovery and symbolic/concrete execution paths.
24
- """
25
- base_address = 0
26
- prototype = "int node_d(long)"
27
- code = archinfo.arch_from_id("AMD64").asm(
28
- """
29
- node_a:
30
- test rdi, rdi
31
- jz node_c
32
- node_b:
33
- mov rax, 0x1234
34
- jmp node_d
35
- node_c:
36
- mov rax, 0x5678
37
- node_d:
38
- ret
39
- """,
40
- base_address,
41
- )
42
-
43
- arch = archinfo.ArchPcode("x86:LE:64:default")
44
- angr.calling_conventions.register_default_cc(arch.name, angr.calling_conventions.SimCCSystemVAMD64)
45
- p = angr.load_shellcode(code, arch=arch, load_address=base_address, engine=angr.engines.UberEnginePcode)
46
-
47
- # Recover the CFG
48
- c = p.analyses.CFGFast(normalize=True)
49
- assert len(c.model.nodes()) == 4
50
-
51
- # Execute symbolically
52
- s = p.factory.call_state(base_address, prototype=prototype)
53
- simgr = p.factory.simulation_manager(s)
54
- simgr.run()
55
- assert sum(len(i) for i in simgr.stashes.values()) == 2
56
- assert {s.solver.eval(s.regs.rax) for s in simgr.deadended} == {0x1234, 0x5678}
57
-
58
- # Execute concretely
59
- callable_func = p.factory.callable(base_address, prototype=prototype, concrete_only=True)
60
- for input_, expected_output in [(0, 0x5678), (1, 0x1234), (0xFFFFFFFFFFFFFFFF, 0x1234)]:
61
- assert (callable_func(input_) == expected_output).is_true()
62
-
63
- def test_fauxware(self):
64
- """
65
- Test basic fauxware execution.
66
- """
67
- p = angr.Project(
68
- os.path.join(test_location, "x86_64", "fauxware"), auto_load_libs=False, engine=angr.engines.UberEnginePcode
69
- )
70
- simgr = p.factory.simgr()
71
- simgr.run()
72
-
73
- assert sum(len(i) for i in simgr.stashes.values()) == len(simgr.deadended) == 3
74
-
75
- grant_paths = [s for s in simgr.deadended if b"trusted" in s.posix.dumps(1)]
76
- assert len(grant_paths) == 2
77
- assert sum(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00SOSNEAKY\x00" == s.posix.dumps(0) for s in grant_paths) == 1
78
-
79
- deny_paths = [s for s in simgr.deadended if b"Go away!" in s.posix.dumps(1)]
80
- assert len(deny_paths) == 1
81
-
82
-
83
- if __name__ == "__main__":
84
- main()