angr 9.2.87__py3-none-manylinux2014_x86_64.whl → 9.2.89__py3-none-manylinux2014_x86_64.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 (248) 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/misc/autoimport.py +26 -0
  24. angr/procedures/definitions/__init__.py +32 -3
  25. angr/utils/constants.py +1 -0
  26. angr/utils/graph.py +20 -1
  27. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/METADATA +7 -6
  28. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/RECORD +32 -244
  29. angr-9.2.89.dist-info/top_level.txt +1 -0
  30. angr/procedures/definitions/ntdll.py +0 -12
  31. angr-9.2.87.dist-info/top_level.txt +0 -2
  32. tests/__init__.py +0 -0
  33. tests/analyses/__init__.py +0 -0
  34. tests/analyses/cfg/__init__.py +0 -0
  35. tests/analyses/cfg/test_cfg_clflush.py +0 -43
  36. tests/analyses/cfg/test_cfg_get_any_node.py +0 -34
  37. tests/analyses/cfg/test_cfg_manager.py +0 -32
  38. tests/analyses/cfg/test_cfg_model.py +0 -55
  39. tests/analyses/cfg/test_cfg_patching.py +0 -378
  40. tests/analyses/cfg/test_cfg_rust_got_resolution.py +0 -36
  41. tests/analyses/cfg/test_cfg_thumb_firmware.py +0 -50
  42. tests/analyses/cfg/test_cfg_vex_postprocessor.py +0 -27
  43. tests/analyses/cfg/test_cfgemulated.py +0 -634
  44. tests/analyses/cfg/test_cfgfast.py +0 -1123
  45. tests/analyses/cfg/test_cfgfast_soot.py +0 -38
  46. tests/analyses/cfg/test_const_resolver.py +0 -38
  47. tests/analyses/cfg/test_iat_resolver.py +0 -37
  48. tests/analyses/cfg/test_jumptables.py +0 -3008
  49. tests/analyses/cfg/test_noop_blocks.py +0 -54
  50. tests/analyses/cfg_slice_to_sink/__init__.py +0 -0
  51. tests/analyses/cfg_slice_to_sink/test_cfg_slice_to_sink.py +0 -93
  52. tests/analyses/cfg_slice_to_sink/test_graph.py +0 -114
  53. tests/analyses/cfg_slice_to_sink/test_transitions.py +0 -28
  54. tests/analyses/decompiler/__init__.py +0 -0
  55. tests/analyses/decompiler/test_baseptr_save_simplifier.py +0 -80
  56. tests/analyses/decompiler/test_decompiler.py +0 -3336
  57. tests/analyses/decompiler/test_peephole_optimizations.py +0 -48
  58. tests/analyses/decompiler/test_propagator_loops.py +0 -101
  59. tests/analyses/decompiler/test_structurer.py +0 -275
  60. tests/analyses/reaching_definitions/__init__.py +0 -0
  61. tests/analyses/reaching_definitions/test_dep_graph.py +0 -432
  62. tests/analyses/reaching_definitions/test_function_handler.py +0 -131
  63. tests/analyses/reaching_definitions/test_heap_allocator.py +0 -46
  64. tests/analyses/reaching_definitions/test_rd_state.py +0 -78
  65. tests/analyses/reaching_definitions/test_reachingdefinitions.py +0 -463
  66. tests/analyses/reaching_definitions/test_subject.py +0 -76
  67. tests/analyses/test_bindiff.py +0 -52
  68. tests/analyses/test_block_simplifier.py +0 -112
  69. tests/analyses/test_boyscout.py +0 -104
  70. tests/analyses/test_calling_convention_analysis.py +0 -352
  71. tests/analyses/test_callsite_maker.py +0 -60
  72. tests/analyses/test_cdg.py +0 -165
  73. tests/analyses/test_cfb.py +0 -37
  74. tests/analyses/test_class_identifier.py +0 -46
  75. tests/analyses/test_clinic.py +0 -30
  76. tests/analyses/test_codetagging.py +0 -32
  77. tests/analyses/test_constantpropagation.py +0 -88
  78. tests/analyses/test_ddg.py +0 -95
  79. tests/analyses/test_ddg_global_var_dependencies.py +0 -83
  80. tests/analyses/test_ddg_memvar_addresses.py +0 -40
  81. tests/analyses/test_disassembly.py +0 -121
  82. tests/analyses/test_find_objects_static.py +0 -35
  83. tests/analyses/test_flirt.py +0 -49
  84. tests/analyses/test_identifier.py +0 -33
  85. tests/analyses/test_init_finder.py +0 -38
  86. tests/analyses/test_proximitygraph.py +0 -31
  87. tests/analyses/test_reassembler.py +0 -295
  88. tests/analyses/test_regionidentifier.py +0 -27
  89. tests/analyses/test_slicing.py +0 -164
  90. tests/analyses/test_stack_pointer_tracker.py +0 -74
  91. tests/analyses/test_static_hooker.py +0 -28
  92. tests/analyses/test_typehoon.py +0 -55
  93. tests/analyses/test_variablerecovery.py +0 -464
  94. tests/analyses/test_vfg.py +0 -221
  95. tests/analyses/test_vtable.py +0 -31
  96. tests/analyses/test_xrefs.py +0 -77
  97. tests/common.py +0 -128
  98. tests/engines/__init__.py +0 -0
  99. tests/engines/light/__init__.py +0 -0
  100. tests/engines/light/test_data.py +0 -17
  101. tests/engines/pcode/__init__.py +0 -0
  102. tests/engines/pcode/test_emulate.py +0 -607
  103. tests/engines/pcode/test_pcode.py +0 -84
  104. tests/engines/test_actions.py +0 -27
  105. tests/engines/test_hook.py +0 -112
  106. tests/engines/test_java.py +0 -697
  107. tests/engines/test_unicorn.py +0 -518
  108. tests/engines/vex/__init__.py +0 -0
  109. tests/engines/vex/test_lifter.py +0 -124
  110. tests/engines/vex/test_vex.py +0 -574
  111. tests/exploration_techniques/__init__.py +0 -0
  112. tests/exploration_techniques/test_cacher.py +0 -45
  113. tests/exploration_techniques/test_director.py +0 -67
  114. tests/exploration_techniques/test_driller_core.py +0 -48
  115. tests/exploration_techniques/test_loop_seer.py +0 -158
  116. tests/exploration_techniques/test_memory_watcher.py +0 -46
  117. tests/exploration_techniques/test_oppologist.py +0 -65
  118. tests/exploration_techniques/test_spiller.py +0 -82
  119. tests/exploration_techniques/test_stochastic.py +0 -40
  120. tests/exploration_techniques/test_tech_builder.py +0 -61
  121. tests/exploration_techniques/test_tracer.py +0 -856
  122. tests/exploration_techniques/test_unique.py +0 -40
  123. tests/exploration_techniques/test_veritesting.py +0 -120
  124. tests/factory/__init__.py +0 -0
  125. tests/factory/block/__init__.py +0 -0
  126. tests/factory/block/test_block_cache.py +0 -33
  127. tests/factory/block/test_keystone.py +0 -106
  128. tests/factory/test_argc.py +0 -101
  129. tests/factory/test_argc_sym.py +0 -110
  130. tests/factory/test_argv.py +0 -158
  131. tests/factory/test_callable.py +0 -266
  132. tests/factory/test_windows_args.py +0 -36
  133. tests/knowledge_plugins/__init__.py +0 -0
  134. tests/knowledge_plugins/cfg/__init__.py +0 -0
  135. tests/knowledge_plugins/cfg/test_cfg_manager.py +0 -36
  136. tests/knowledge_plugins/functions/__init__.py +0 -0
  137. tests/knowledge_plugins/functions/test_function.py +0 -91
  138. tests/knowledge_plugins/functions/test_function2.py +0 -79
  139. tests/knowledge_plugins/functions/test_function_manager.py +0 -139
  140. tests/knowledge_plugins/functions/test_prototypes.py +0 -53
  141. tests/knowledge_plugins/key_definitions/__init__.py +0 -0
  142. tests/knowledge_plugins/key_definitions/test_atoms.py +0 -24
  143. tests/knowledge_plugins/key_definitions/test_environment.py +0 -126
  144. tests/knowledge_plugins/key_definitions/test_heap_address.py +0 -27
  145. tests/knowledge_plugins/key_definitions/test_live_definitions.py +0 -72
  146. tests/knowledge_plugins/test_dwarf_variables.py +0 -240
  147. tests/knowledge_plugins/test_kb_plugins.py +0 -91
  148. tests/knowledge_plugins/test_kb_plugins_dwarf.py +0 -36
  149. tests/knowledge_plugins/test_patches.py +0 -48
  150. tests/misc/__init__.py +0 -0
  151. tests/misc/test_hookset.py +0 -57
  152. tests/perf/__init__.py +0 -0
  153. tests/perf/perf_cfgemulated.py +0 -19
  154. tests/perf/perf_cfgfast.py +0 -18
  155. tests/perf/perf_concrete_execution.py +0 -41
  156. tests/perf/perf_siminspect_nop.py +0 -36
  157. tests/perf/perf_state_copy.py +0 -33
  158. tests/perf/perf_unicorn_0.py +0 -27
  159. tests/perf/perf_unicorn_1.py +0 -23
  160. tests/procedures/__init__.py +0 -0
  161. tests/procedures/glibc/__init__.py +0 -0
  162. tests/procedures/glibc/test_ctype_locale.py +0 -164
  163. tests/procedures/libc/__init__.py +0 -0
  164. tests/procedures/libc/test_fgets.py +0 -53
  165. tests/procedures/libc/test_scanf.py +0 -205
  166. tests/procedures/libc/test_sprintf.py +0 -44
  167. tests/procedures/libc/test_sscanf.py +0 -63
  168. tests/procedures/libc/test_strcasecmp.py +0 -37
  169. tests/procedures/libc/test_string.py +0 -1102
  170. tests/procedures/libc/test_strtol.py +0 -78
  171. tests/procedures/linux_kernel/__init__.py +0 -0
  172. tests/procedures/linux_kernel/test_lseek.py +0 -174
  173. tests/procedures/posix/__init__.py +0 -0
  174. tests/procedures/posix/test_chroot.py +0 -33
  175. tests/procedures/posix/test_getenv.py +0 -78
  176. tests/procedures/posix/test_pwrite_pread.py +0 -57
  177. tests/procedures/posix/test_sim_time.py +0 -46
  178. tests/procedures/posix/test_unlink.py +0 -46
  179. tests/procedures/test_project_resolve_simproc.py +0 -43
  180. tests/procedures/test_sim_procedure.py +0 -117
  181. tests/procedures/test_stub_procedure_args.py +0 -53
  182. tests/serialization/__init__.py +0 -0
  183. tests/serialization/test_db.py +0 -197
  184. tests/serialization/test_pickle.py +0 -95
  185. tests/serialization/test_serialization.py +0 -132
  186. tests/serialization/test_vault.py +0 -169
  187. tests/sim/__init__.py +0 -3
  188. tests/sim/exec_func/__init__.py +0 -0
  189. tests/sim/exec_func/test_mem_funcs.py +0 -55
  190. tests/sim/exec_func/test_str_funcs.py +0 -93
  191. tests/sim/exec_func/test_syscall_result.py +0 -39
  192. tests/sim/exec_insn/__init__.py +0 -0
  193. tests/sim/exec_insn/test_adc.py +0 -44
  194. tests/sim/exec_insn/test_ops.py +0 -83
  195. tests/sim/exec_insn/test_rcr.py +0 -26
  196. tests/sim/exec_insn/test_rol.py +0 -51
  197. tests/sim/exec_insn/test_signed_div.py +0 -34
  198. tests/sim/exec_insn/test_sqrt.py +0 -56
  199. tests/sim/options/__init__.py +0 -0
  200. tests/sim/options/test_0div.py +0 -54
  201. tests/sim/options/test_symbolic_fd.py +0 -59
  202. tests/sim/options/test_unsupported.py +0 -34
  203. tests/sim/test_accuracy.py +0 -137
  204. tests/sim/test_checkbyte.py +0 -53
  205. tests/sim/test_echo.py +0 -36
  206. tests/sim/test_fauxware.py +0 -202
  207. tests/sim/test_self_modifying_code.py +0 -65
  208. tests/sim/test_simple_api.py +0 -36
  209. tests/sim/test_simulation_manager.py +0 -147
  210. tests/sim/test_stack_alignment.py +0 -65
  211. tests/sim/test_state.py +0 -303
  212. tests/sim/test_state_customization.py +0 -54
  213. tests/sim/test_symbol_hooked_by.py +0 -49
  214. tests/simos/__init__.py +0 -0
  215. tests/simos/windows/__init__.py +0 -0
  216. tests/simos/windows/test_windows_stack_cookie.py +0 -58
  217. tests/state_plugins/__init__.py +0 -0
  218. tests/state_plugins/inspect/__init__.py +0 -0
  219. tests/state_plugins/inspect/test_inspect.py +0 -310
  220. tests/state_plugins/inspect/test_syscall_override.py +0 -90
  221. tests/state_plugins/posix/__init__.py +0 -0
  222. tests/state_plugins/posix/test_file_struct_funcs.py +0 -56
  223. tests/state_plugins/posix/test_files.py +0 -69
  224. tests/state_plugins/posix/test_posix.py +0 -72
  225. tests/state_plugins/solver/__init__.py +0 -0
  226. tests/state_plugins/solver/test_simsolver.py +0 -58
  227. tests/state_plugins/solver/test_symbolic.py +0 -153
  228. tests/state_plugins/solver/test_variable_registration.py +0 -46
  229. tests/state_plugins/test_callstack.py +0 -54
  230. tests/state_plugins/test_gdb_plugin.py +0 -35
  231. tests/state_plugins/test_multi_open_file.py +0 -47
  232. tests/state_plugins/test_symbolization.py +0 -38
  233. tests/storage/__init__.py +0 -0
  234. tests/storage/test_memory.py +0 -960
  235. tests/storage/test_memory_merge.py +0 -114
  236. tests/storage/test_memview.py +0 -205
  237. tests/storage/test_mmap.py +0 -26
  238. tests/storage/test_multivalues.py +0 -44
  239. tests/storage/test_permissions.py +0 -32
  240. tests/storage/test_ptmalloc.py +0 -291
  241. tests/storage/test_relro_perm.py +0 -49
  242. tests/test_calling_conventions.py +0 -86
  243. tests/test_types.py +0 -329
  244. tests/utils/__init__.py +0 -0
  245. tests/utils/test_graph.py +0 -41
  246. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/LICENSE +0 -0
  247. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/WHEEL +0 -0
  248. {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/entry_points.txt +0 -0
@@ -1,634 +0,0 @@
1
- #!/usr/bin/env python3
2
- __package__ = __package__ or "tests.analyses.cfg" # pylint:disable=redefined-builtin
3
-
4
- import time
5
- import pickle
6
- import networkx
7
-
8
- import logging
9
- import os
10
- import unittest
11
-
12
- import angr
13
- from angr import options as o
14
-
15
- from ...common import bin_location, broken
16
-
17
- l = logging.getLogger("angr.tests.test_cfgemulated")
18
-
19
- test_location = os.path.join(bin_location, "tests")
20
-
21
-
22
- # pylint: disable=missing-class-docstring
23
- # pylint: disable=no-self-use
24
- class TestCfgemulate(unittest.TestCase):
25
- def compare_cfg(self, standard, g, function_list):
26
- """
27
- Standard graph comes with addresses only, and it is based on instructions, not on basic blocks
28
- """
29
-
30
- def get_function_name(addr):
31
- start = 0
32
- end = len(function_list) - 1
33
-
34
- while start <= end:
35
- mid = (start + end) / 2
36
- f = function_list[mid]
37
- if addr < f["start"]:
38
- end = mid - 1
39
- elif addr > f["end"]:
40
- start = mid + 1
41
- else:
42
- return f["name"]
43
-
44
- return None
45
-
46
- # Sort function list
47
- function_list = sorted(function_list, key=lambda x: x["start"])
48
-
49
- # Convert the IDA-style CFG into VEX-style CFG
50
- s_graph = networkx.DiGraph()
51
- all_nodes = sorted(standard.nodes())
52
- addr_to_basicblock = {}
53
- last_basicblock = None
54
- for n in all_nodes:
55
- if last_basicblock is None:
56
- last_basicblock = (n, n)
57
-
58
- block = last_basicblock
59
- successors = standard.successors(n)
60
- if len(successors) == 1 and successors[0] >= block[0]:
61
- last_basicblock = (block[0], successors[0])
62
- else:
63
- # Save the existing block
64
- addr_to_basicblock[block[0]] = block
65
-
66
- # Create edges
67
- for s in successors:
68
- s_graph.add_edge(block[0], s)
69
-
70
- # Clear last_basicblock so that we create a new basicblock next time
71
- last_basicblock = None
72
-
73
- graph = networkx.DiGraph()
74
- for src, dst in g.edges():
75
- graph.add_edge(src.addr, dst.addr)
76
-
77
- # Graph comparison
78
- for src, dst in s_graph.edges():
79
- if graph.has_edge(src, dst):
80
- continue
81
- else:
82
- # Edge doesn't exist in our CFG
83
- l.error(
84
- "Edge (%s-0x%x, %s-0x%x) only exists in IDA CFG.",
85
- get_function_name(src),
86
- src,
87
- get_function_name(dst),
88
- dst,
89
- )
90
-
91
- for src, dst in graph.edges():
92
- if s_graph.has_edge(src, dst):
93
- continue
94
- else:
95
- # Edge doesn't exist in our CFG
96
- l.error(
97
- "Edge (%s-0x%x, %s-0x%x) only exists in angr's CFG.",
98
- get_function_name(src),
99
- src,
100
- get_function_name(dst),
101
- dst,
102
- )
103
-
104
- def perform_single(self, binary_path, cfg_path=None):
105
- proj = angr.Project(
106
- binary_path,
107
- use_sim_procedures=True,
108
- default_analysis_mode="symbolic",
109
- load_options={"auto_load_libs": False},
110
- )
111
- start = time.time()
112
- cfg = proj.analyses.CFGEmulated(context_sensitivity_level=1, fail_fast=True)
113
- end = time.time()
114
- duration = end - start
115
- bbl_dict = cfg.nodes()
116
-
117
- l.info("CFG generated in %f seconds.", duration)
118
- l.info("Contains %d members in BBL dict.", len(bbl_dict))
119
-
120
- if cfg_path is not None and os.path.isfile(cfg_path):
121
- # Compare the graph with a predefined CFG
122
- info = pickle.load(open(cfg_path, "rb"))
123
- standard = info["cfg"]
124
- functions = info["functions"]
125
- graph = cfg.graph
126
-
127
- self.compare_cfg(standard, graph, functions)
128
- else:
129
- l.warning("No standard CFG specified.")
130
-
131
- @broken
132
- def test_cfg_0(self):
133
- binary_path = os.path.join(test_location, "x86_64", "cfg_0")
134
- cfg_path = binary_path + ".cfg"
135
- self.perform_single(binary_path, cfg_path)
136
-
137
- @broken
138
- def test_cfg_1(self):
139
- binary_path = os.path.join(test_location, "x86_64", "cfg_1")
140
- cfg_path = binary_path + ".cfg"
141
- self.perform_single(binary_path, cfg_path)
142
-
143
- @broken
144
- def test_cfg_2(self):
145
- binary_path = os.path.join(test_location, "armel", "test_division")
146
- cfg_path = binary_path + ".cfg"
147
- self.perform_single(binary_path, cfg_path)
148
-
149
- @broken
150
- def test_cfg_3(self):
151
- binary_path = os.path.join(test_location, "mips", "test_arrays")
152
- cfg_path = binary_path + ".cfg"
153
- self.perform_single(binary_path, cfg_path)
154
-
155
- @broken
156
- def test_cfg_4(self):
157
- binary_path = os.path.join(test_location, "mipsel", "darpa_ping")
158
- cfg_path = binary_path + ".cfg"
159
- self.perform_single(binary_path, cfg_path)
160
-
161
- def test_additional_edges(self):
162
- # Test the `additional_edges` parameter for CFG generation
163
-
164
- binary_path = os.path.join(test_location, "x86_64", "switch")
165
- proj = angr.Project(
166
- binary_path,
167
- use_sim_procedures=True,
168
- default_analysis_mode="symbolic",
169
- load_options={"auto_load_libs": False},
170
- )
171
- additional_edges = {0x400573: [0x400580, 0x40058F, 0x40059E]}
172
- cfg = proj.analyses.CFGEmulated(
173
- context_sensitivity_level=0,
174
- additional_edges=additional_edges,
175
- fail_fast=True,
176
- resolve_indirect_jumps=False, # For this test case, we need to disable the
177
- # jump table resolving, otherwise CFGEmulated
178
- # can automatically find the node 0x4005ad.
179
- )
180
-
181
- assert cfg.get_any_node(0x400580) is not None
182
- assert cfg.get_any_node(0x40058F) is not None
183
- assert cfg.get_any_node(0x40059E) is not None
184
- assert cfg.get_any_node(0x4005AD) is None
185
-
186
- def test_not_returning(self):
187
- # Make sure we are properly labeling functions that do not return in function manager
188
-
189
- binary_path = os.path.join(test_location, "x86_64", "not_returning")
190
- proj = angr.Project(binary_path, use_sim_procedures=True, load_options={"auto_load_libs": False})
191
- proj.analyses.CFGEmulated(context_sensitivity_level=0, fail_fast=True) # pylint:disable=unused-variable
192
-
193
- # function_a returns
194
- assert proj.kb.functions.function(name="function_a") is not None
195
- assert proj.kb.functions.function(name="function_a").returning
196
-
197
- # function_b does not return
198
- assert proj.kb.functions.function(name="function_b") is not None
199
- assert not proj.kb.functions.function(name="function_b").returning
200
-
201
- # function_c does not return
202
- assert proj.kb.functions.function(name="function_c") is not None
203
- assert not proj.kb.functions.function(name="function_c").returning
204
-
205
- # main does not return
206
- assert proj.kb.functions.function(name="main") is not None
207
- assert not proj.kb.functions.function(name="main").returning
208
-
209
- # function_d should not be reachable
210
- assert proj.kb.functions.function(name="function_d") is None
211
-
212
- @broken
213
- def test_cfg_5(self):
214
- binary_path = os.path.join(test_location, "mipsel", "busybox")
215
- cfg_path = binary_path + ".cfg"
216
-
217
- self.perform_single(binary_path, cfg_path)
218
-
219
- def test_cfg_6(self):
220
- function_addresses = [
221
- 0xFA630,
222
- 0xFA683,
223
- 0xFA6D4,
224
- 0xFA707,
225
- 0xFA754,
226
- 0xFA779,
227
- 0xFA7A9,
228
- 0xFA7D6,
229
- 0xFA844,
230
- 0xFA857,
231
- 0xFA8D9,
232
- 0xFA92F,
233
- 0xFA959,
234
- 0xFA9FB,
235
- 0xFABD6,
236
- 0xFAC61,
237
- 0xFACC2,
238
- 0xFAD29,
239
- 0xFAF94,
240
- 0xFBD07,
241
- 0xFC100,
242
- 0xFC101,
243
- 0xFC14F,
244
- 0xFC18E,
245
- 0xFC25E,
246
- 0xFC261,
247
- 0xFC3C6,
248
- 0xFC42F,
249
- 0xFC4A3,
250
- 0xFC4CF,
251
- 0xFC4DB,
252
- 0xFC5BA,
253
- 0xFC5EF,
254
- 0xFC5FE,
255
- 0xFC611,
256
- 0xFC682,
257
- 0xFC6B7,
258
- 0xFC7FC,
259
- 0xFC8A8,
260
- 0xFC8E7,
261
- 0xFCB42,
262
- 0xFCB50,
263
- 0xFCB72,
264
- 0xFCC3B,
265
- 0xFCC7A,
266
- 0xFCC8B,
267
- 0xFCCDC,
268
- 0xFD1A3,
269
- 0xFF06E,
270
- ]
271
-
272
- # We need to add DO_CCALLS to resolve long jmp and support real mode
273
- o.modes["fastpath"] |= {o.DO_CCALLS}
274
- binary_path = test_location + "/i386/bios.bin.elf"
275
- proj = angr.Project(binary_path, use_sim_procedures=True, page_size=1, auto_load_libs=False)
276
- proj.analyses.CFGEmulated(context_sensitivity_level=1, fail_fast=True) # pylint:disable=unused-variable
277
- assert {f for f in proj.kb.functions} >= set(function_addresses)
278
- o.modes["fastpath"] ^= {o.DO_CCALLS}
279
-
280
- def test_fauxware(self):
281
- binary_path = os.path.join(test_location, "x86_64", "fauxware")
282
- cfg_path = binary_path + ".cfg"
283
-
284
- self.perform_single(binary_path, cfg_path)
285
-
286
- @broken
287
- def test_loop_unrolling(self):
288
- binary_path = os.path.join(test_location, "x86_64", "cfg_loop_unrolling")
289
-
290
- p = angr.Project(binary_path, auto_load_libs=True)
291
- cfg = p.analyses.CFGEmulated(fail_fast=True)
292
-
293
- cfg.normalize()
294
- cfg.unroll_loops(5)
295
-
296
- assert len(cfg.get_all_nodes(0x400636)) == 7
297
-
298
- def test_thumb_mode(self):
299
- # In thumb mode, all addresses of instructions and in function manager should be odd numbers, which loyally
300
- # reflect VEX's trick to encode the THUMB state in the address.
301
-
302
- binary_path = os.path.join(test_location, "armhf", "test_arrays")
303
- p = angr.Project(binary_path, auto_load_libs=False)
304
- cfg = p.analyses.CFGEmulated(fail_fast=True)
305
-
306
- def check_addr(a):
307
- if a % 2 == 1:
308
- assert cfg.is_thumb_addr(a)
309
- else:
310
- assert not cfg.is_thumb_addr(a)
311
-
312
- # CFGNodes
313
- cfg_node_addrs = [n.addr for n in cfg.graph.nodes() if not n.is_simprocedure]
314
- for a in cfg_node_addrs:
315
- check_addr(a)
316
-
317
- # Functions in function manager
318
- for f_addr, f in p.kb.functions.items():
319
- if f.is_simprocedure:
320
- continue
321
- check_addr(f_addr)
322
- if f.startpoint is not None:
323
- check_addr(f.startpoint.addr)
324
-
325
- def test_fakeret_edges_0(self):
326
- # Test the bug where a fakeret edge can be missing in certain cases
327
- # Reported by Attila Axt (GitHub: @axt)
328
- # Ref: https://github.com/angr/angr/issues/72
329
-
330
- binary_path = os.path.join(test_location, "x86_64", "cfg_3")
331
-
332
- p = angr.Project(binary_path, auto_load_libs=False)
333
- cfg = p.analyses.CFGEmulated(context_sensitivity_level=3, fail_fast=True)
334
-
335
- putchar_plt = cfg.functions.function(name="putchar", plt=True)
336
- assert putchar_plt.returning
337
-
338
- putchar = cfg.functions.function(name="putchar", plt=False)
339
- assert putchar.returning
340
-
341
- # Since context sensitivity is 3, there should be two different putchar nodes
342
- putchar_cfgnodes = cfg.get_all_nodes(putchar.addr)
343
- assert len(putchar_cfgnodes) == 2
344
-
345
- # Each putchar node has a different predecessor as their PLT entry
346
- plt_entry_0 = cfg.get_predecessors(putchar_cfgnodes[0])
347
- assert len(plt_entry_0) == 1
348
- plt_entry_0 = plt_entry_0[0]
349
-
350
- plt_entry_1 = cfg.get_predecessors(putchar_cfgnodes[1])
351
- assert len(plt_entry_1) == 1
352
- plt_entry_1 = plt_entry_1[0]
353
-
354
- assert plt_entry_0 is not plt_entry_1
355
-
356
- # Each PLT entry should have a FakeRet edge
357
- preds_0 = cfg.get_predecessors(plt_entry_0)
358
- assert len(preds_0) == 1
359
- preds_1 = cfg.get_predecessors(plt_entry_1)
360
- assert len(preds_1) == 1
361
-
362
- # Each predecessor must have a call edge and a FakeRet edge
363
- edges_0 = cfg.get_successors_and_jumpkind(preds_0[0], excluding_fakeret=False)
364
- assert len(edges_0) == 2
365
- jumpkinds = {jumpkind for _, jumpkind in edges_0}
366
- assert jumpkinds == {"Ijk_Call", "Ijk_FakeRet"}
367
-
368
- edges_1 = cfg.get_successors_and_jumpkind(preds_1[0], excluding_fakeret=False)
369
- assert len(edges_1) == 2
370
- jumpkinds = {jumpkind for _, jumpkind in edges_1}
371
- assert jumpkinds == {"Ijk_Call", "Ijk_FakeRet"}
372
-
373
- def test_string_references(self):
374
- # Test AttributeError on 'addr' which occurs when searching for string
375
- # references
376
-
377
- binary_path = os.path.join(test_location, "i386", "ctf_nuclear")
378
- b = angr.Project(binary_path, load_options={"auto_load_libs": False})
379
- cfg = b.analyses.CFGEmulated(keep_state=True, fail_fast=True)
380
-
381
- string_references = []
382
- for f in cfg.functions.values():
383
- string_references.append(list(f.string_references()))
384
-
385
- # test passes if hasn't thrown an exception
386
-
387
- def test_arrays(self):
388
- binary_path = os.path.join(test_location, "armhf", "test_arrays")
389
- b = angr.Project(binary_path, load_options={"auto_load_libs": False})
390
- cfg = b.analyses.CFGEmulated(fail_fast=True)
391
-
392
- node = cfg.model.get_any_node(0x10415)
393
- assert node is not None
394
-
395
- successors = cfg.model.get_successors(node)
396
- assert len(successors) == 2
397
-
398
- def test_max_steps(self):
399
- binary_path = os.path.join(test_location, "x86_64", "fauxware")
400
- b = angr.Project(binary_path, load_options={"auto_load_libs": False})
401
- cfg = b.analyses.CFGEmulated(max_steps=5, fail_fast=True)
402
-
403
- dfs_edges = networkx.dfs_edges(cfg.graph)
404
-
405
- depth_map = {}
406
- for src, dst in dfs_edges:
407
- if src not in depth_map:
408
- depth_map[src] = 0
409
- if dst not in depth_map:
410
- depth_map[dst] = depth_map[src] + 1
411
- depth_map[dst] = max(depth_map[src] + 1, depth_map[dst])
412
-
413
- assert max(depth_map.values()) <= 5
414
-
415
- def test_armel_final_missing_block(self):
416
- # Due to a stupid bug in CFGEmulated, the last block of a function might go missing in the function graph if the
417
- # only entry edge to that block is an Ijk_Ret edge. See #475 on GitHub.
418
- # Thank @gergo for reporting and providing this test binary.
419
-
420
- binary_path = os.path.join(test_location, "armel", "last_block")
421
- b = angr.Project(binary_path, auto_load_libs=False)
422
- cfg = b.analyses.CFGEmulated(fail_fast=True)
423
-
424
- blocks = list(cfg.kb.functions[0x8000].blocks)
425
-
426
- assert len(blocks) == 3
427
- assert {block.addr for block in blocks} == {0x8000, 0x8014, 0x8020}
428
-
429
- def test_armel_final_missing_block_b(self):
430
- # When _pending_jobs is not sorted, it is possible that we first process a pending job created earlier and then
431
- # process another pending job created later. Ideally, we hope that jobs are always processed in a topological
432
- # order, and the unsorted pending jobs break this assumption. In this test binary, at one point there can be two
433
- # pending jobs, 0x10b05/0x10ac5(Ijk_FakeRet) and 0x10bbe(Ijk_FakeRet). If 0x10bbe is processed before 0x10b05,
434
- # we do not # know whether the function 0x10a29(aes) returns or not. As a result, the final block of the main
435
- # function is not confirmed, and is not added to the function graph of function main.
436
- #
437
- # In fact, this also hints a different bug. We should always "confirm" that a function returns if its FakeRet
438
- # job are processed for whatever reason.
439
- #
440
- # Fixing either bug will resolve the issue that the final block does not show up in the function graph of main.
441
- # To stay on the safe side, both of them are fixed. Thanks @tyb0807 for reporting this issue and providing a
442
- # test binary.
443
- # EDG says: This binary is compiled incorrectly.
444
- # The binary's app code was compiled as CortexM, but linked against ARM libraries.
445
- # This is illegal, and does not actually execute on a real CortexM.
446
- # Somebody should recompile it....
447
- binary_path = os.path.join(test_location, "armel", "aes")
448
- b = angr.Project(binary_path, arch="ARMEL", auto_load_libs=False)
449
-
450
- function = b.loader.main_object.get_symbol("main").rebased_addr
451
- cfg = b.analyses.CFGEmulated(
452
- starts=[function],
453
- context_sensitivity_level=0,
454
- normalize=True,
455
- fail_fast=True,
456
- )
457
-
458
- blocks = list(cfg.kb.functions["main"].blocks)
459
-
460
- assert len(blocks) == 2
461
- assert {block.addr for block in blocks} == {0x10B79, 0x10BBF}
462
-
463
- def test_armel_incorrect_function_detection_caused_by_branch(self):
464
- # GitHub issue #685
465
- binary_path = os.path.join(test_location, "armel", "RTOSDemo.axf.issue_685")
466
- b = angr.Project(binary_path, auto_load_libs=False)
467
-
468
- cfg = b.analyses.CFGEmulated()
469
-
470
- # The Main function should be identified as a single function
471
- assert 0x80A1 in cfg.functions
472
- main_func = cfg.functions[0x80A1]
473
-
474
- # All blocks should be there
475
- block_addrs = sorted([b.addr for b in main_func.blocks])
476
- assert block_addrs == [0x80A1, 0x80B1, 0x80BB, 0x80CD, 0x80DF, 0x80E3, 0x80ED]
477
-
478
- # The ResetISR function should be identified as a single function, too
479
- assert 0x8009 in cfg.functions
480
- resetisr_func = cfg.functions[0x8009]
481
-
482
- # All blocks should be there
483
- block_addrs = sorted([b.addr for b in resetisr_func.blocks])
484
- assert block_addrs == [0x8009, 0x8011, 0x801F, 0x8027]
485
-
486
- def test_cfg_switches(self):
487
- # logging.getLogger('angr.analyses.cfg.cfg_fast').setLevel(logging.INFO)
488
- # logging.getLogger('angr.analyses.cfg.indirect_jump_resolvers.jumptable').setLevel(logging.DEBUG)
489
-
490
- filename = "cfg_switches"
491
-
492
- edges = {
493
- "x86_64": {
494
- # jump table 0 in func_0
495
- (0x40053A, 0x400547),
496
- (0x40053A, 0x400552),
497
- (0x40053A, 0x40055D),
498
- (0x40053A, 0x400568),
499
- (0x40053A, 0x400573),
500
- (0x40053A, 0x400580),
501
- (0x40053A, 0x40058D),
502
- # jump table 0 in func_1
503
- (0x4005BC, 0x4005C9),
504
- (0x4005BC, 0x4005D8),
505
- (0x4005BC, 0x4005E7),
506
- (0x4005BC, 0x4005F6),
507
- (0x4005BC, 0x400605),
508
- (0x4005BC, 0x400614),
509
- (0x4005BC, 0x400623),
510
- (0x4005BC, 0x400632),
511
- (0x4005BC, 0x40063E),
512
- (0x4005BC, 0x40064A),
513
- (0x4005BC, 0x4006B0),
514
- # jump table 1 in func_1
515
- (0x40065A, 0x400667),
516
- (0x40065A, 0x400673),
517
- (0x40065A, 0x40067F),
518
- (0x40065A, 0x40068B),
519
- (0x40065A, 0x400697),
520
- (0x40065A, 0x4006A3),
521
- # jump table 0 in main
522
- (0x4006E1, 0x4006EE),
523
- (0x4006E1, 0x4006FA),
524
- (0x4006E1, 0x40070B),
525
- (0x4006E1, 0x40071C),
526
- (0x4006E1, 0x40072D),
527
- (0x4006E1, 0x40073E),
528
- (0x4006E1, 0x40074F),
529
- (0x4006E1, 0x40075B),
530
- },
531
- }
532
-
533
- arches = edges.keys()
534
-
535
- for arch in arches:
536
- path = os.path.join(test_location, arch, filename)
537
- proj = angr.Project(path, load_options={"auto_load_libs": False})
538
-
539
- cfg = proj.analyses.CFGEmulated()
540
-
541
- for src, dst in edges[arch]:
542
- src_node = cfg.get_any_node(src)
543
- dst_node = cfg.get_any_node(dst)
544
- assert dst_node in src_node.successors, "CFG edge {}-{} is not found.".format(
545
- src_node,
546
- dst_node,
547
- )
548
-
549
- class CFGEmulatedAborted(angr.analyses.cfg.cfg_emulated.CFGEmulated): # pylint:disable=abstract-method
550
- """
551
- Only used in the test_abort_and_resume test case.
552
- """
553
-
554
- should_abort = False
555
-
556
- def _intra_analysis(self):
557
- if self.should_abort:
558
- self.abort()
559
- else:
560
- super()._intra_analysis()
561
-
562
- def test_abort_and_resume(self):
563
- angr.analyses.AnalysesHub.register_default("CFGEmulatedAborted", self.CFGEmulatedAborted)
564
-
565
- self.CFGEmulatedAborted.should_abort = False
566
- binary_path = os.path.join(test_location, "x86_64", "fauxware")
567
- b = angr.Project(binary_path, auto_load_libs=False)
568
-
569
- self.CFGEmulatedAborted.should_abort = True
570
- cfg = b.analyses.CFGEmulatedAborted()
571
- assert len(list(cfg.jobs)) > 0 # there should be left-over jobs
572
-
573
- self.CFGEmulatedAborted.should_abort = False
574
- cfg.resume()
575
-
576
- assert len(list(cfg.jobs)) == 0
577
-
578
- def test_base_graph(self):
579
- path = os.path.join(test_location, "x86_64", "test_cfgemulated_base_graph")
580
-
581
- func_addr = 0x401129
582
-
583
- edges = {
584
- (0x401129, 0x401144),
585
- (0x401129, 0x40114D),
586
- (0x401144, 0x401154),
587
- (0x40114D, 0x401154),
588
- }
589
-
590
- final_states_info = {
591
- 0x401129: 2,
592
- 0x40114D: 1,
593
- 0x401144: 1,
594
- 0x401154: 1,
595
- }
596
-
597
- proj = angr.Project(path, load_options={"auto_load_libs": False})
598
-
599
- cfg_fast = proj.analyses.CFGFast(normalize=True)
600
- target_function = cfg_fast.kb.functions[func_addr]
601
- target_function.normalize()
602
-
603
- target_function_cfg_emulated = proj.analyses.CFGEmulated(
604
- keep_state=True,
605
- state_add_options=angr.options.refs,
606
- base_graph=target_function.graph,
607
- starts=(func_addr,),
608
- normalize=True,
609
- )
610
- for src, dst in edges:
611
- src_node = target_function_cfg_emulated.get_any_node(src)
612
- dst_node = target_function_cfg_emulated.get_any_node(dst)
613
- assert dst_node in src_node.successors, "CFG edge {}-{} is not found.".format(
614
- src_node,
615
- dst_node,
616
- )
617
-
618
- for node_addr, final_states_number in final_states_info.items():
619
- node = target_function_cfg_emulated.get_any_node(node_addr)
620
- assert final_states_number == len(node.final_states), (
621
- "CFG node 0x%x has incorrect final states." % node_addr
622
- )
623
-
624
-
625
- if __name__ == "__main__":
626
- logging.getLogger("angr.state_plugins.abstract_memory").setLevel(logging.DEBUG)
627
- # logging.getLogger("angr.state_plugins.symbolic_memory").setLevel(logging.DEBUG)
628
- # logging.getLogger("angr.analyses.cfg.cfg_emulated").setLevel(logging.DEBUG)
629
- # logging.getLogger("s_irsb").setLevel(logging.DEBUG)
630
- # Temporarily disable the warnings of claripy backend
631
- # logging.getLogger("claripy.backends.backend").setLevel(logging.ERROR)
632
- # logging.getLogger("claripy.claripy").setLevel(logging.ERROR)
633
-
634
- unittest.main()