angr 9.2.158__cp310-abi3-manylinux2014_x86_64.whl → 9.2.160__cp310-abi3-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 (195) hide show
  1. angr/__init__.py +1 -1
  2. angr/ailment/__init__.py +81 -0
  3. angr/ailment/block.py +81 -0
  4. angr/ailment/block_walker.py +845 -0
  5. angr/ailment/constant.py +3 -0
  6. angr/ailment/converter_common.py +11 -0
  7. angr/ailment/converter_pcode.py +623 -0
  8. angr/ailment/converter_vex.py +798 -0
  9. angr/ailment/expression.py +1639 -0
  10. angr/ailment/manager.py +33 -0
  11. angr/ailment/statement.py +978 -0
  12. angr/ailment/tagged_object.py +61 -0
  13. angr/ailment/utils.py +114 -0
  14. angr/analyses/calling_convention/calling_convention.py +6 -2
  15. angr/analyses/decompiler/ail_simplifier.py +5 -5
  16. angr/analyses/decompiler/block_io_finder.py +4 -4
  17. angr/analyses/decompiler/block_similarity.py +2 -2
  18. angr/analyses/decompiler/block_simplifier.py +4 -4
  19. angr/analyses/decompiler/callsite_maker.py +2 -2
  20. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
  21. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
  22. angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +1 -1
  23. angr/analyses/decompiler/clinic.py +5 -2
  24. angr/analyses/decompiler/condition_processor.py +1 -1
  25. angr/analyses/decompiler/counters/boolean_counter.py +4 -4
  26. angr/analyses/decompiler/counters/call_counter.py +4 -4
  27. angr/analyses/decompiler/counters/expression_counters.py +5 -5
  28. angr/analyses/decompiler/counters/seq_cf_structure_counter.py +1 -1
  29. angr/analyses/decompiler/decompiler.py +17 -12
  30. angr/analyses/decompiler/dephication/dephication_base.py +12 -1
  31. angr/analyses/decompiler/dephication/graph_dephication.py +12 -5
  32. angr/analyses/decompiler/dephication/graph_rewriting.py +6 -10
  33. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +109 -72
  34. angr/analyses/decompiler/dephication/rewriting_engine.py +32 -9
  35. angr/analyses/decompiler/dephication/seqnode_dephication.py +32 -10
  36. angr/analyses/decompiler/empty_node_remover.py +2 -2
  37. angr/analyses/decompiler/expression_narrower.py +6 -6
  38. angr/analyses/decompiler/goto_manager.py +2 -2
  39. angr/analyses/decompiler/jump_target_collector.py +1 -1
  40. angr/analyses/decompiler/label_collector.py +1 -1
  41. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +25 -25
  42. angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +1 -1
  43. angr/analyses/decompiler/optimization_passes/code_motion.py +2 -2
  44. angr/analyses/decompiler/optimization_passes/condition_constprop.py +3 -3
  45. angr/analyses/decompiler/optimization_passes/const_derefs.py +3 -3
  46. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +4 -4
  47. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +2 -2
  48. angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +3 -3
  49. angr/analyses/decompiler/optimization_passes/div_simplifier.py +1 -1
  50. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
  51. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +4 -4
  52. angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +1 -1
  53. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +4 -4
  54. angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +3 -3
  55. angr/analyses/decompiler/optimization_passes/engine_base.py +1 -1
  56. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +3 -3
  57. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
  58. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +2 -2
  59. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +3 -3
  60. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +3 -3
  61. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +4 -4
  62. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +1 -1
  63. angr/analyses/decompiler/optimization_passes/optimization_pass.py +25 -1
  64. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +1 -1
  65. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +1 -1
  66. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +2 -2
  67. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +4 -4
  68. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +2 -2
  69. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -1
  70. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +3 -3
  71. angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +3 -3
  72. angr/analyses/decompiler/optimization_passes/tag_slicer.py +1 -1
  73. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -1
  74. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +1 -1
  75. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +1 -1
  76. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +1 -1
  77. angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +1 -1
  78. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +1 -1
  79. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +1 -1
  80. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +1 -1
  81. angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +1 -1
  82. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +1 -1
  83. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +1 -1
  84. angr/analyses/decompiler/peephole_optimizations/base.py +3 -3
  85. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +1 -1
  86. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +1 -1
  87. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +1 -1
  88. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +1 -1
  89. angr/analyses/decompiler/peephole_optimizations/bswap.py +2 -2
  90. angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +2 -2
  91. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +2 -2
  92. angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +1 -1
  93. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +2 -2
  94. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -1
  95. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -1
  96. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +1 -1
  97. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +1 -1
  98. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
  99. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +1 -1
  100. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +2 -2
  101. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +2 -2
  102. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +2 -2
  103. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +1 -1
  104. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +1 -1
  105. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +1 -1
  106. angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +2 -2
  107. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +2 -2
  108. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +1 -1
  109. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +1 -1
  110. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +1 -1
  111. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +1 -1
  112. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +1 -1
  113. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +1 -1
  114. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +1 -1
  115. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +1 -1
  116. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +1 -1
  117. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
  118. angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +1 -1
  119. angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +3 -3
  120. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +1 -1
  121. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +2 -2
  122. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -1
  123. angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +1 -1
  124. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +1 -1
  125. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +1 -1
  126. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +1 -1
  127. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +2 -2
  128. angr/analyses/decompiler/peephole_optimizations/utils.py +1 -1
  129. angr/analyses/decompiler/redundant_label_remover.py +1 -1
  130. angr/analyses/decompiler/region_identifier.py +4 -4
  131. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -1
  132. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +1 -1
  133. angr/analyses/decompiler/region_simplifiers/expr_folding.py +37 -8
  134. angr/analyses/decompiler/region_simplifiers/goto.py +1 -1
  135. angr/analyses/decompiler/region_simplifiers/if_.py +1 -1
  136. angr/analyses/decompiler/region_simplifiers/loop.py +1 -1
  137. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -1
  138. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +14 -2
  139. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +3 -3
  140. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +1 -1
  141. angr/analyses/decompiler/return_maker.py +1 -1
  142. angr/analyses/decompiler/seq_to_blocks.py +1 -1
  143. angr/analyses/decompiler/sequence_walker.py +2 -2
  144. angr/analyses/decompiler/ssailification/rewriting.py +4 -4
  145. angr/analyses/decompiler/ssailification/rewriting_engine.py +4 -4
  146. angr/analyses/decompiler/ssailification/rewriting_state.py +3 -3
  147. angr/analyses/decompiler/ssailification/ssailification.py +2 -2
  148. angr/analyses/decompiler/ssailification/traversal.py +1 -1
  149. angr/analyses/decompiler/ssailification/traversal_engine.py +11 -2
  150. angr/analyses/decompiler/structured_codegen/c.py +3 -3
  151. angr/analyses/decompiler/structuring/dream.py +1 -1
  152. angr/analyses/decompiler/structuring/phoenix.py +3 -3
  153. angr/analyses/decompiler/structuring/structurer_base.py +1 -1
  154. angr/analyses/decompiler/structuring/structurer_nodes.py +1 -2
  155. angr/analyses/decompiler/utils.py +1 -1
  156. angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +1 -1
  157. angr/analyses/deobfuscator/string_obf_opt_passes.py +3 -3
  158. angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +2 -2
  159. angr/analyses/propagator/propagator.py +1 -1
  160. angr/analyses/proximity_graph.py +2 -2
  161. angr/analyses/reaching_definitions/engine_ail.py +1 -1
  162. angr/analyses/reaching_definitions/reaching_definitions.py +1 -1
  163. angr/analyses/reaching_definitions/subject.py +1 -1
  164. angr/analyses/s_liveness.py +2 -2
  165. angr/analyses/s_propagator.py +3 -3
  166. angr/analyses/s_reaching_definitions/s_rda_model.py +1 -1
  167. angr/analyses/s_reaching_definitions/s_rda_view.py +3 -3
  168. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +3 -3
  169. angr/analyses/typehoon/simple_solver.py +231 -29
  170. angr/analyses/typehoon/typehoon.py +10 -2
  171. angr/analyses/variable_recovery/engine_ail.py +10 -22
  172. angr/analyses/variable_recovery/engine_base.py +1 -1
  173. angr/analyses/variable_recovery/variable_recovery_base.py +1 -1
  174. angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
  175. angr/engines/light/data.py +1 -1
  176. angr/engines/light/engine.py +1 -1
  177. angr/knowledge_plugins/key_definitions/atoms.py +1 -1
  178. angr/knowledge_plugins/propagations/prop_value.py +1 -1
  179. angr/knowledge_plugins/propagations/propagation_model.py +1 -1
  180. angr/knowledge_plugins/propagations/states.py +1 -1
  181. angr/knowledge_plugins/variables/variable_manager.py +1 -1
  182. angr/rustylib.abi3.so +0 -0
  183. angr/state_plugins/unicorn_engine.py +4 -4
  184. angr/utils/ail.py +4 -4
  185. angr/utils/endness.py +1 -1
  186. angr/utils/ssa/__init__.py +14 -4
  187. angr/utils/ssa/tmp_uses_collector.py +4 -4
  188. angr/utils/ssa/vvar_uses_collector.py +4 -4
  189. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/METADATA +6 -7
  190. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/RECORD +195 -183
  191. /angr/{lib/angr_native.so → unicornlib.so} +0 -0
  192. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/WHEEL +0 -0
  193. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/entry_points.txt +0 -0
  194. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/licenses/LICENSE +0 -0
  195. {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,798 @@
1
+ # pylint:disable=missing-class-docstring
2
+ from __future__ import annotations
3
+ import logging
4
+
5
+ import pyvex
6
+ from angr.utils.constants import DEFAULT_STATEMENT
7
+ from angr.engines.vex.claripy.irop import vexop_to_simop
8
+ from angr.errors import UnsupportedIROpError
9
+
10
+ from .block import Block
11
+ from .statement import Assignment, CAS, Store, Jump, Call, ConditionalJump, DirtyStatement, Return
12
+ from .expression import (
13
+ Const,
14
+ Register,
15
+ Tmp,
16
+ DirtyExpression,
17
+ UnaryOp,
18
+ Convert,
19
+ BinaryOp,
20
+ Load,
21
+ ITE,
22
+ Reinterpret,
23
+ VEXCCallExpression,
24
+ )
25
+ from .converter_common import SkipConversionNotice, Converter
26
+
27
+
28
+ log = logging.getLogger(name=__name__)
29
+
30
+
31
+ class VEXExprConverter(Converter):
32
+ @staticmethod
33
+ def simop_from_vexop(vex_op):
34
+ return vexop_to_simop(vex_op)
35
+
36
+ @staticmethod
37
+ def generic_name_from_vex_op(vex_op):
38
+ return vexop_to_simop(vex_op)._generic_name
39
+
40
+ @staticmethod
41
+ def convert(expr, manager): # pylint:disable=arguments-differ
42
+ """
43
+
44
+ :param expr:
45
+ :return:
46
+ """
47
+ if isinstance(expr, pyvex.const.IRConst):
48
+ return VEXExprConverter.const_n(expr, manager)
49
+
50
+ func = EXPRESSION_MAPPINGS.get(type(expr))
51
+ if func is not None:
52
+ # When something goes wrong, return a DirtyExpression instead of crashing the program
53
+ try:
54
+ return func(expr, manager)
55
+ except UnsupportedIROpError:
56
+ log.warning("VEXExprConverter: Unsupported IROp %s.", expr.op)
57
+ return DirtyExpression(
58
+ manager.next_atom(), f"unsupported_{expr.op}", [], bits=expr.result_size(manager.tyenv)
59
+ )
60
+
61
+ log.warning("VEXExprConverter: Unsupported VEX expression of type %s.", type(expr))
62
+ try:
63
+ bits = expr.result_size(manager.tyenv)
64
+ except ValueError:
65
+ # e.g., "ValueError: Type Ity_INVALID does not have size"
66
+ bits = 0
67
+ return DirtyExpression(manager.next_atom(), f"unsupported_{type(expr)!s}", [], bits=bits)
68
+
69
+ @staticmethod
70
+ def convert_list(exprs, manager):
71
+ converted = []
72
+ for expr in exprs:
73
+ converted.append(VEXExprConverter.convert(expr, manager))
74
+ return converted
75
+
76
+ @staticmethod
77
+ def register(offset, bits, manager):
78
+ reg_size = bits // manager.arch.byte_width
79
+ reg_name = manager.arch.translate_register_name(offset, reg_size)
80
+ return Register(
81
+ manager.next_atom(),
82
+ None,
83
+ offset,
84
+ bits,
85
+ reg_name=reg_name,
86
+ ins_addr=manager.ins_addr,
87
+ vex_block_addr=manager.block_addr,
88
+ vex_stmt_idx=manager.vex_stmt_idx,
89
+ )
90
+
91
+ @staticmethod
92
+ def tmp(tmp_idx, bits, manager):
93
+ return Tmp(
94
+ manager.next_atom(),
95
+ None,
96
+ tmp_idx,
97
+ bits,
98
+ ins_addr=manager.ins_addr,
99
+ vex_block_addr=manager.block_addr,
100
+ vex_stmt_idx=manager.vex_stmt_idx,
101
+ )
102
+
103
+ @staticmethod
104
+ def RdTmp(expr, manager):
105
+ return VEXExprConverter.tmp(expr.tmp, expr.result_size(manager.tyenv), manager)
106
+
107
+ @staticmethod
108
+ def Get(expr, manager):
109
+ return VEXExprConverter.register(expr.offset, expr.result_size(manager.tyenv), manager)
110
+
111
+ @staticmethod
112
+ def Load(expr, manager):
113
+ return Load(
114
+ manager.next_atom(),
115
+ VEXExprConverter.convert(expr.addr, manager),
116
+ expr.result_size(manager.tyenv) // 8,
117
+ expr.end,
118
+ ins_addr=manager.ins_addr,
119
+ vex_block_addr=manager.block_addr,
120
+ vex_stmt_idx=manager.vex_stmt_idx,
121
+ )
122
+
123
+ @staticmethod
124
+ def Unop(expr, manager):
125
+ op_name = VEXExprConverter.generic_name_from_vex_op(expr.op)
126
+ if op_name == "Reinterp":
127
+ simop = vexop_to_simop(expr.op)
128
+ return Reinterpret(
129
+ manager.next_atom(),
130
+ simop._from_size,
131
+ simop._from_type,
132
+ simop._to_size,
133
+ simop._to_type,
134
+ VEXExprConverter.convert(expr.args[0], manager),
135
+ ins_addr=manager.ins_addr,
136
+ vex_block_addr=manager.block_addr,
137
+ vex_stmt_idx=manager.vex_stmt_idx,
138
+ )
139
+ if op_name is None:
140
+ # is it a conversion?
141
+ simop = vexop_to_simop(expr.op)
142
+ if simop._conversion:
143
+ if simop._from_side == "HI":
144
+ # returns the high-half of the argument
145
+ inner = VEXExprConverter.convert(expr.args[0], manager)
146
+ shifted = BinaryOp(
147
+ manager.next_atom(),
148
+ "Shr",
149
+ [
150
+ inner,
151
+ Const(
152
+ manager.next_atom(),
153
+ None,
154
+ simop._to_size,
155
+ 8,
156
+ ins_addr=manager.ins_addr,
157
+ vex_block_addr=manager.block_addr,
158
+ vex_stmt_idx=manager.vex_stmt_idx,
159
+ ),
160
+ ],
161
+ False,
162
+ ins_addr=manager.ins_addr,
163
+ vex_block_addr=manager.block_addr,
164
+ vex_stmt_idx=manager.vex_stmt_idx,
165
+ )
166
+ return Convert(
167
+ manager.next_atom(),
168
+ simop._from_size,
169
+ simop._to_size,
170
+ simop.is_signed,
171
+ shifted,
172
+ ins_addr=manager.ins_addr,
173
+ vex_block_addr=manager.block_addr,
174
+ vex_stmt_idx=manager.vex_stmt_idx,
175
+ )
176
+
177
+ return Convert(
178
+ manager.next_atom(),
179
+ simop._from_size,
180
+ simop._to_size,
181
+ simop.is_signed,
182
+ VEXExprConverter.convert(expr.args[0], manager),
183
+ ins_addr=manager.ins_addr,
184
+ vex_block_addr=manager.block_addr,
185
+ vex_stmt_idx=manager.vex_stmt_idx,
186
+ )
187
+ raise NotImplementedError("Unsupported operation")
188
+ if op_name == "Not" and expr.op != "Iop_Not1":
189
+ # NotN (N != 1) is equivalent to bitwise negation
190
+ op_name = "BitwiseNeg"
191
+
192
+ return UnaryOp(
193
+ manager.next_atom(),
194
+ op_name,
195
+ VEXExprConverter.convert(expr.args[0], manager),
196
+ bits=expr.result_size(manager.tyenv),
197
+ ins_addr=manager.ins_addr,
198
+ vex_block_addr=manager.block_addr,
199
+ vex_stmt_idx=manager.vex_stmt_idx,
200
+ )
201
+
202
+ @staticmethod
203
+ def Binop(expr, manager):
204
+ op = VEXExprConverter.simop_from_vexop(expr.op)
205
+ op_name = op._generic_name
206
+ operands = VEXExprConverter.convert_list(expr.args, manager)
207
+
208
+ if op_name == "Add" and type(operands[1]) is Const and operands[1].sign_bit == 1:
209
+ # convert it to a sub
210
+ op_name = "Sub"
211
+ op1_val, op1_bits = operands[1].value, operands[1].bits
212
+ operands[1] = Const(operands[1].idx, None, (1 << op1_bits) - op1_val, op1_bits)
213
+
214
+ signed = False
215
+ vector_count = None
216
+ vector_size = None
217
+ if op._vector_count is not None and op._vector_size is not None:
218
+ # SIMD conversions
219
+ op_name += "V" # vectorized
220
+ vector_count = op._vector_count
221
+ vector_size = op._vector_size
222
+ elif op_name in {"CmpLE", "CmpLT", "CmpGE", "CmpGT", "Div", "DivMod", "Mod", "Mul", "Mull"}:
223
+ if op.is_signed:
224
+ signed = True
225
+
226
+ if op_name == "Cmp" and op._float:
227
+ # Rename Cmp to CmpF
228
+ op_name = "CmpF"
229
+
230
+ if op_name is None and op._conversion:
231
+ # conversion
232
+ # TODO: Finish this
233
+ if op._from_type == "I" and op._to_type == "F":
234
+ # integer to floating point
235
+ rm = operands[0]
236
+ operand = operands[1]
237
+ return Convert(
238
+ manager.next_atom(),
239
+ op._from_size,
240
+ op._to_size,
241
+ op.is_signed,
242
+ operand,
243
+ from_type=Convert.TYPE_INT,
244
+ to_type=Convert.TYPE_FP,
245
+ rounding_mode=rm,
246
+ ins_addr=manager.ins_addr,
247
+ vex_block_addr=manager.block_addr,
248
+ vex_stmt_idx=manager.vex_stmt_idx,
249
+ )
250
+ if op._from_side == "HL":
251
+ # Concatenating the two arguments and form a new value
252
+ op_name = "Concat"
253
+ elif op._from_type == "F" and op._to_type == "F":
254
+ # floating point to floating point
255
+ rm = operands[0]
256
+ operand = operands[1]
257
+ return Convert(
258
+ manager.next_atom(),
259
+ op._from_size,
260
+ op._to_size,
261
+ op.is_signed,
262
+ operand,
263
+ from_type=Convert.TYPE_FP,
264
+ to_type=Convert.TYPE_FP,
265
+ rounding_mode=rm,
266
+ ins_addr=manager.ins_addr,
267
+ vex_block_addr=manager.block_addr,
268
+ vex_stmt_idx=manager.vex_stmt_idx,
269
+ )
270
+ elif op._from_type == "F" and op._to_type == "I":
271
+ # floating point to integer
272
+ # floating point to floating point
273
+ rm = operands[0]
274
+ operand = operands[1]
275
+ return Convert(
276
+ manager.next_atom(),
277
+ op._from_size,
278
+ op._to_size,
279
+ op.is_signed,
280
+ operand,
281
+ from_type=Convert.TYPE_FP,
282
+ to_type=Convert.TYPE_INT,
283
+ rounding_mode=rm,
284
+ ins_addr=manager.ins_addr,
285
+ vex_block_addr=manager.block_addr,
286
+ vex_stmt_idx=manager.vex_stmt_idx,
287
+ )
288
+
289
+ bits = op._output_size_bits
290
+
291
+ if op_name == "DivMod":
292
+ op1_size = op._from_size if op._from_size is not None else operands[0].bits
293
+ op2_size = op._to_size if op._to_size is not None else operands[1].bits
294
+
295
+ if op2_size < op1_size:
296
+ # e.g., DivModU64to32
297
+ operands[1] = Convert(
298
+ manager.next_atom(),
299
+ op2_size,
300
+ op1_size,
301
+ op._from_signed != "U",
302
+ operands[1],
303
+ ins_addr=manager.ins_addr,
304
+ vex_block_addr=manager.block_addr,
305
+ vex_stmt_idx=manager.vex_stmt_idx,
306
+ )
307
+ chunk_bits = bits // 2
308
+
309
+ div = BinaryOp(
310
+ manager.next_atom(),
311
+ "Div",
312
+ operands,
313
+ signed,
314
+ ins_addr=manager.ins_addr,
315
+ vex_block_addr=manager.block_addr,
316
+ vex_stmt_idx=manager.vex_stmt_idx,
317
+ bits=op1_size,
318
+ )
319
+ truncated_div = Convert(
320
+ manager.next_atom(),
321
+ op1_size,
322
+ chunk_bits,
323
+ signed,
324
+ div,
325
+ ins_addr=manager.ins_addr,
326
+ vex_block_addr=manager.block_addr,
327
+ vex_stmt_idx=manager.vex_stmt_idx,
328
+ )
329
+ mod = BinaryOp(
330
+ manager.next_atom(),
331
+ "Mod",
332
+ operands,
333
+ signed,
334
+ ins_addr=manager.ins_addr,
335
+ vex_block_addr=manager.block_addr,
336
+ vex_stmt_idx=manager.vex_stmt_idx,
337
+ bits=op1_size,
338
+ )
339
+ truncated_mod = Convert(
340
+ manager.next_atom(),
341
+ op1_size,
342
+ chunk_bits,
343
+ signed,
344
+ mod,
345
+ ins_addr=manager.ins_addr,
346
+ vex_block_addr=manager.block_addr,
347
+ vex_stmt_idx=manager.vex_stmt_idx,
348
+ )
349
+
350
+ operands = [truncated_mod, truncated_div]
351
+ op_name = "Concat"
352
+ signed = False
353
+
354
+ return BinaryOp(
355
+ manager.next_atom(),
356
+ op_name,
357
+ operands,
358
+ signed,
359
+ ins_addr=manager.ins_addr,
360
+ vex_block_addr=manager.block_addr,
361
+ vex_stmt_idx=manager.vex_stmt_idx,
362
+ bits=bits,
363
+ vector_count=vector_count,
364
+ vector_size=vector_size,
365
+ )
366
+
367
+ @staticmethod
368
+ def Triop(expr, manager):
369
+ op = VEXExprConverter.simop_from_vexop(expr.op)
370
+ op_name = op._generic_name
371
+ operands = VEXExprConverter.convert_list(expr.args, manager)
372
+
373
+ bits = op._output_size_bits
374
+
375
+ if op._float:
376
+ # this is a floating-point operation where the first argument is the rounding mode. in fact, we have a
377
+ # BinaryOp here.
378
+ rm = operands[0]
379
+ return BinaryOp(
380
+ manager.next_atom(),
381
+ op_name,
382
+ operands[1:],
383
+ True, # all floating-point operations are signed
384
+ floating_point=True,
385
+ rounding_mode=rm,
386
+ ins_addr=manager.ins_addr,
387
+ vex_block_addr=manager.block_addr,
388
+ vex_stmt_idx=manager.vex_stmt_idx,
389
+ bits=bits,
390
+ )
391
+
392
+ raise TypeError(
393
+ "Please figure out what kind of operation this is (smart money says fused multiply) and convert it into "
394
+ "multiple binops"
395
+ )
396
+
397
+ @staticmethod
398
+ def Const(expr, manager):
399
+ # pyvex.IRExpr.Const
400
+ return Const(
401
+ manager.next_atom(),
402
+ None,
403
+ expr.con.value,
404
+ expr.result_size(manager.tyenv),
405
+ ins_addr=manager.ins_addr,
406
+ vex_block_addr=manager.block_addr,
407
+ vex_stmt_idx=manager.vex_stmt_idx,
408
+ )
409
+
410
+ @staticmethod
411
+ def const_n(expr, manager):
412
+ # pyvex.const.xxx
413
+ return Const(
414
+ manager.next_atom(),
415
+ None,
416
+ expr.value,
417
+ expr.size,
418
+ ins_addr=manager.ins_addr,
419
+ vex_block_addr=manager.block_addr,
420
+ vex_stmt_idx=manager.vex_stmt_idx,
421
+ )
422
+
423
+ @staticmethod
424
+ def ITE(expr, manager):
425
+ cond = VEXExprConverter.convert(expr.cond, manager)
426
+ iffalse = VEXExprConverter.convert(expr.iffalse, manager)
427
+ iftrue = VEXExprConverter.convert(expr.iftrue, manager)
428
+
429
+ return ITE(
430
+ manager.next_atom(),
431
+ cond,
432
+ iffalse,
433
+ iftrue,
434
+ ins_addr=manager.ins_addr,
435
+ vex_block_addr=manager.block_addr,
436
+ vex_stmt_idx=manager.vex_stmt_idx,
437
+ )
438
+
439
+ @staticmethod
440
+ def CCall(expr: pyvex.IRExpr.CCall, manager):
441
+ operands = [VEXExprConverter.convert(arg, manager) for arg in expr.args]
442
+ return VEXCCallExpression(
443
+ manager.next_atom(),
444
+ expr.cee.name,
445
+ operands,
446
+ bits=expr.result_size(manager.tyenv),
447
+ ins_addr=manager.ins_addr,
448
+ vex_block_addr=manager.block_addr,
449
+ vex_stmt_idx=manager.vex_stmt_idx,
450
+ )
451
+
452
+
453
+ EXPRESSION_MAPPINGS = {
454
+ pyvex.IRExpr.RdTmp: VEXExprConverter.RdTmp,
455
+ pyvex.IRExpr.Get: VEXExprConverter.Get,
456
+ pyvex.IRExpr.Unop: VEXExprConverter.Unop,
457
+ pyvex.IRExpr.Binop: VEXExprConverter.Binop,
458
+ pyvex.IRExpr.Triop: VEXExprConverter.Triop,
459
+ pyvex.IRExpr.Const: VEXExprConverter.Const,
460
+ pyvex.const.U32: VEXExprConverter.const_n,
461
+ pyvex.const.U64: VEXExprConverter.const_n,
462
+ pyvex.IRExpr.Load: VEXExprConverter.Load,
463
+ pyvex.IRExpr.ITE: VEXExprConverter.ITE,
464
+ pyvex.IRExpr.CCall: VEXExprConverter.CCall,
465
+ }
466
+
467
+
468
+ class VEXStmtConverter(Converter):
469
+ @staticmethod
470
+ def convert(idx, stmt, manager): # pylint:disable=arguments-differ
471
+ """
472
+
473
+ :param idx:
474
+ :param stmt:
475
+ :param manager:
476
+ :return:
477
+ """
478
+
479
+ try:
480
+ func = STATEMENT_MAPPINGS[type(stmt)]
481
+ except KeyError:
482
+ dirty = DirtyExpression(manager.next_atom(), str(stmt), [], bits=0)
483
+ return DirtyStatement(idx, dirty, ins_addr=manager.ins_addr)
484
+
485
+ return func(idx, stmt, manager)
486
+
487
+ @staticmethod
488
+ def WrTmp(idx, stmt, manager):
489
+ var = VEXExprConverter.tmp(stmt.tmp, stmt.data.result_size(manager.tyenv), manager)
490
+ reg = VEXExprConverter.convert(stmt.data, manager)
491
+
492
+ return Assignment(
493
+ idx,
494
+ var,
495
+ reg,
496
+ ins_addr=manager.ins_addr,
497
+ vex_block_addr=manager.block_addr,
498
+ vex_stmt_idx=manager.vex_stmt_idx,
499
+ )
500
+
501
+ @staticmethod
502
+ def Put(idx, stmt, manager):
503
+ data = VEXExprConverter.convert(stmt.data, manager)
504
+ reg = VEXExprConverter.register(stmt.offset, data.bits, manager)
505
+ return Assignment(
506
+ idx,
507
+ reg,
508
+ data,
509
+ ins_addr=manager.ins_addr,
510
+ vex_block_addr=manager.block_addr,
511
+ vex_stmt_idx=manager.vex_stmt_idx,
512
+ )
513
+
514
+ @staticmethod
515
+ def Store(idx, stmt, manager):
516
+ return Store(
517
+ idx,
518
+ VEXExprConverter.convert(stmt.addr, manager),
519
+ VEXExprConverter.convert(stmt.data, manager),
520
+ stmt.data.result_size(manager.tyenv) // 8,
521
+ stmt.endness,
522
+ ins_addr=manager.ins_addr,
523
+ vex_block_addr=manager.block_addr,
524
+ vex_stmt_idx=manager.vex_stmt_idx,
525
+ )
526
+
527
+ @staticmethod
528
+ def Exit(idx, stmt, manager):
529
+ if stmt.jumpkind in {
530
+ "Ijk_EmWarn",
531
+ "Ijk_NoDecode",
532
+ "Ijk_MapFail",
533
+ "Ijk_NoRedir",
534
+ "Ijk_SigTRAP",
535
+ "Ijk_SigSEGV",
536
+ "Ijk_ClientReq",
537
+ "Ijk_SigFPE_IntDiv",
538
+ }:
539
+ raise SkipConversionNotice
540
+
541
+ return ConditionalJump(
542
+ idx,
543
+ VEXExprConverter.convert(stmt.guard, manager),
544
+ VEXExprConverter.convert(stmt.dst, manager),
545
+ None, # it will be filled in right afterwards
546
+ ins_addr=manager.ins_addr,
547
+ vex_block_addr=manager.block_addr,
548
+ vex_stmt_idx=manager.vex_stmt_idx,
549
+ )
550
+
551
+ @staticmethod
552
+ def LoadG(idx, stmt: pyvex.IRStmt.LoadG, manager):
553
+ sizes = {
554
+ "ILGop_Ident32": (32, 32, False),
555
+ "ILGop_Ident64": (64, 64, False),
556
+ "ILGop_IdentV128": (128, 128, False),
557
+ "ILGop_8Uto32": (8, 32, False),
558
+ "ILGop_8Sto32": (8, 32, True),
559
+ "ILGop_16Uto32": (16, 32, False),
560
+ "ILGop_16Sto32": (16, 32, True),
561
+ }
562
+
563
+ dst = VEXExprConverter.tmp(stmt.dst, manager.tyenv.sizeof(stmt.dst), manager)
564
+ load_bits, convert_bits, signed = sizes[stmt.cvt]
565
+ src = Load(
566
+ manager.next_atom(),
567
+ VEXExprConverter.convert(stmt.addr, manager),
568
+ load_bits // 8,
569
+ stmt.end,
570
+ guard=VEXExprConverter.convert(stmt.guard, manager),
571
+ alt=VEXExprConverter.convert(stmt.alt, manager),
572
+ )
573
+ if convert_bits != load_bits:
574
+ src = Convert(manager.next_atom(), load_bits, convert_bits, signed, src)
575
+
576
+ return Assignment(
577
+ idx,
578
+ dst,
579
+ src,
580
+ ins_addr=manager.ins_addr,
581
+ vex_block_addr=manager.block_addr,
582
+ vex_stmt_idx=manager.vex_stmt_idx,
583
+ )
584
+
585
+ @staticmethod
586
+ def StoreG(idx, stmt: pyvex.IRStmt.StoreG, manager):
587
+ return Store(
588
+ idx,
589
+ VEXExprConverter.convert(stmt.addr, manager),
590
+ VEXExprConverter.convert(stmt.data, manager),
591
+ stmt.data.result_size(manager.tyenv) // 8,
592
+ stmt.endness,
593
+ guard=VEXExprConverter.convert(stmt.guard, manager),
594
+ ins_addr=manager.ins_addr,
595
+ vex_block_addr=manager.block_addr,
596
+ vex_stmt_idx=manager.vex_stmt_idx,
597
+ )
598
+
599
+ @staticmethod
600
+ def CAS(idx, stmt: pyvex.IRStmt.CAS, manager):
601
+ # addr
602
+ addr = VEXExprConverter.convert(stmt.addr, manager)
603
+ data_lo = VEXExprConverter.convert(stmt.dataLo, manager)
604
+ data_hi = VEXExprConverter.convert(stmt.dataHi, manager) if stmt.dataHi is not None else None
605
+ expd_lo = VEXExprConverter.convert(stmt.expdLo, manager)
606
+ expd_hi = VEXExprConverter.convert(stmt.expdHi, manager) if stmt.expdHi is not None else None
607
+ old_lo = VEXExprConverter.tmp(stmt.oldLo, manager.tyenv.sizeof(stmt.oldLo), manager)
608
+ old_hi = (
609
+ VEXExprConverter.tmp(stmt.oldHi, stmt.oldHi.result_size(manager.tyenv), manager)
610
+ if stmt.oldHi != 0xFFFFFFFF
611
+ else None
612
+ )
613
+ return CAS(
614
+ idx, addr, data_lo, data_hi, expd_lo, expd_hi, old_lo, old_hi, stmt.endness, ins_addr=manager.ins_addr
615
+ )
616
+
617
+ @staticmethod
618
+ def Dirty(idx, stmt: pyvex.IRStmt.Dirty, manager):
619
+ # we translate it into tmp = DirtyExpression() if possible
620
+
621
+ operands = [VEXExprConverter.convert(op, manager) for op in stmt.args]
622
+ guard = VEXExprConverter.convert(stmt.guard, manager) if stmt.guard is not None else None
623
+ bits = manager.tyenv.sizeof(stmt.tmp) if stmt.tmp != 0xFFFFFFFF else 0
624
+ maddr = VEXExprConverter.convert(stmt.mAddr, manager) if stmt.mAddr is not None else None
625
+ dirty_expr = DirtyExpression(
626
+ manager.next_atom(),
627
+ stmt.cee.name,
628
+ operands,
629
+ guard=guard,
630
+ mfx=stmt.mFx,
631
+ maddr=maddr,
632
+ msize=stmt.mSize,
633
+ bits=bits,
634
+ )
635
+
636
+ if stmt.tmp == 0xFFFFFFFF:
637
+ return DirtyStatement(
638
+ idx,
639
+ dirty_expr,
640
+ ins_addr=manager.ins_addr,
641
+ vex_block_addr=manager.block_addr,
642
+ vex_stmt_idx=manager.vex_stmt_idx,
643
+ )
644
+
645
+ tmp = VEXExprConverter.tmp(stmt.tmp, bits, manager)
646
+ return Assignment(
647
+ idx,
648
+ tmp,
649
+ dirty_expr,
650
+ ins_addr=manager.ins_addr,
651
+ vex_block_addr=manager.block_addr,
652
+ vex_stmt_idx=manager.vex_stmt_idx,
653
+ )
654
+
655
+
656
+ STATEMENT_MAPPINGS = {
657
+ pyvex.IRStmt.Put: VEXStmtConverter.Put,
658
+ pyvex.IRStmt.WrTmp: VEXStmtConverter.WrTmp,
659
+ pyvex.IRStmt.Store: VEXStmtConverter.Store,
660
+ pyvex.IRStmt.Exit: VEXStmtConverter.Exit,
661
+ pyvex.IRStmt.StoreG: VEXStmtConverter.StoreG,
662
+ pyvex.IRStmt.LoadG: VEXStmtConverter.LoadG,
663
+ pyvex.IRStmt.CAS: VEXStmtConverter.CAS,
664
+ pyvex.IRStmt.Dirty: VEXStmtConverter.Dirty,
665
+ }
666
+
667
+
668
+ class VEXIRSBConverter(Converter):
669
+ @staticmethod
670
+ def convert(irsb, manager): # pylint:disable=arguments-differ
671
+ """
672
+
673
+ :param irsb:
674
+ :param manager:
675
+ :return:
676
+ """
677
+
678
+ # convert each VEX statement into an AIL statement
679
+ statements = []
680
+ idx = 0
681
+
682
+ manager.tyenv = irsb.tyenv
683
+ manager.block_addr = irsb.addr
684
+
685
+ addr = irsb.addr
686
+ first_imark = True
687
+
688
+ conditional_jumps = []
689
+
690
+ for vex_stmt_idx, stmt in enumerate(irsb.statements):
691
+ if type(stmt) is pyvex.IRStmt.IMark:
692
+ if first_imark:
693
+ # update block address
694
+ addr = stmt.addr + stmt.delta
695
+ first_imark = False
696
+ manager.ins_addr = stmt.addr + stmt.delta
697
+ continue
698
+ if type(stmt) is pyvex.IRStmt.AbiHint:
699
+ # TODO: How can we use AbiHint?
700
+ continue
701
+
702
+ manager.vex_stmt_idx = vex_stmt_idx
703
+ try:
704
+ converted = VEXStmtConverter.convert(idx, stmt, manager)
705
+ if isinstance(converted, list):
706
+ # got multiple statements
707
+ statements.extend(converted)
708
+ idx += len(converted)
709
+ else:
710
+ # got one statement
711
+ statements.append(converted)
712
+ if type(converted) is ConditionalJump:
713
+ conditional_jumps.append(converted)
714
+ idx += 1
715
+ except SkipConversionNotice:
716
+ pass
717
+
718
+ manager.vex_stmt_idx = DEFAULT_STATEMENT
719
+ if irsb.jumpkind == "Ijk_Call" or irsb.jumpkind.startswith("Ijk_Sys"):
720
+ # FIXME: Move ret_expr and fp_ret_expr creation into angr because we cannot reliably determine which
721
+ # expressions can be returned from the call without performing further analysis
722
+ ret_reg_offset = manager.arch.ret_offset
723
+ ret_expr = Register(
724
+ manager.next_atom(),
725
+ None,
726
+ ret_reg_offset,
727
+ manager.arch.bits,
728
+ reg_name=manager.arch.translate_register_name(ret_reg_offset, size=manager.arch.bits),
729
+ ins_addr=manager.ins_addr,
730
+ vex_block_addr=manager.block_addr,
731
+ vex_stmt_idx=DEFAULT_STATEMENT,
732
+ )
733
+ fp_ret_reg_offset = manager.arch.fp_ret_offset
734
+ if fp_ret_reg_offset is not None and fp_ret_reg_offset != ret_reg_offset:
735
+ fp_ret_expr = Register(
736
+ manager.next_atom(),
737
+ None,
738
+ fp_ret_reg_offset,
739
+ manager.arch.bits,
740
+ reg_name=manager.arch.translate_register_name(fp_ret_reg_offset, size=manager.arch.bits),
741
+ ins_addr=manager.ins_addr,
742
+ vex_block_addr=manager.block_addr,
743
+ vex_stmt_idx=DEFAULT_STATEMENT,
744
+ )
745
+ else:
746
+ fp_ret_expr = None
747
+
748
+ if irsb.jumpkind == "Ijk_Call":
749
+ target = VEXExprConverter.convert(irsb.next, manager)
750
+ elif irsb.jumpkind.startswith("Ijk_Sys"):
751
+ # FIXME: This is a hack to make syscall work. We should have a better way to handle syscalls.
752
+ target = DirtyExpression(manager.next_atom(), "syscall", [], bits=manager.arch.bits)
753
+ else:
754
+ raise NotImplementedError("Unsupported jumpkind")
755
+
756
+ statements.append(
757
+ Call(
758
+ manager.next_atom(),
759
+ target,
760
+ ret_expr=ret_expr,
761
+ fp_ret_expr=fp_ret_expr,
762
+ ins_addr=manager.ins_addr,
763
+ vex_block_addr=manager.block_addr,
764
+ vex_stmt_idx=DEFAULT_STATEMENT,
765
+ )
766
+ )
767
+ elif irsb.jumpkind == "Ijk_Boring":
768
+ if conditional_jumps:
769
+ # fill in the false target
770
+ cond_jump = conditional_jumps[-1]
771
+ cond_jump.false_target = VEXExprConverter.convert(irsb.next, manager)
772
+
773
+ else:
774
+ # jump
775
+ statements.append(
776
+ Jump(
777
+ manager.next_atom(),
778
+ VEXExprConverter.convert(irsb.next, manager),
779
+ ins_addr=manager.ins_addr,
780
+ vex_block_addr=manager.block_addr,
781
+ vex_stmt_idx=DEFAULT_STATEMENT,
782
+ )
783
+ )
784
+ elif irsb.jumpkind == "Ijk_Ret":
785
+ # return
786
+ statements.append(
787
+ Return(
788
+ manager.next_atom(),
789
+ [],
790
+ ins_addr=manager.ins_addr,
791
+ vex_block_addr=manager.block_addr,
792
+ vex_stmt_idx=DEFAULT_STATEMENT,
793
+ )
794
+ )
795
+ else:
796
+ raise NotImplementedError("Unsupported jumpkind")
797
+
798
+ return Block(addr, irsb.size, statements=statements)