angr 9.2.78__py3-none-win_amd64.whl → 9.2.79__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 (29) hide show
  1. angr/__init__.py +1 -1
  2. angr/__main__.py +34 -0
  3. angr/analyses/cfg/cfg_fast.py +12 -0
  4. angr/analyses/decompiler/block_simplifier.py +25 -5
  5. angr/analyses/decompiler/clinic.py +27 -17
  6. angr/analyses/decompiler/optimization_passes/__init__.py +2 -0
  7. angr/analyses/decompiler/optimization_passes/engine_base.py +2 -2
  8. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -2
  9. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +105 -12
  10. angr/analyses/decompiler/peephole_optimizations/__init__.py +11 -2
  11. angr/analyses/decompiler/peephole_optimizations/base.py +29 -2
  12. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -1
  13. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +83 -0
  14. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +103 -0
  15. angr/analyses/decompiler/structured_codegen/c.py +20 -4
  16. angr/analyses/decompiler/utils.py +128 -2
  17. angr/analyses/proximity_graph.py +30 -0
  18. angr/knowledge_plugins/__init__.py +1 -0
  19. angr/knowledge_plugins/custom_strings.py +40 -0
  20. angr/knowledge_plugins/functions/function.py +29 -0
  21. angr/lib/angr_native.dll +0 -0
  22. angr/procedures/definitions/msvcr.py +0 -3
  23. angr/sim_type.py +3 -0
  24. {angr-9.2.78.dist-info → angr-9.2.79.dist-info}/METADATA +6 -6
  25. {angr-9.2.78.dist-info → angr-9.2.79.dist-info}/RECORD +29 -24
  26. {angr-9.2.78.dist-info → angr-9.2.79.dist-info}/WHEEL +1 -1
  27. angr-9.2.79.dist-info/entry_points.txt +2 -0
  28. {angr-9.2.78.dist-info → angr-9.2.79.dist-info}/LICENSE +0 -0
  29. {angr-9.2.78.dist-info → angr-9.2.79.dist-info}/top_level.txt +0 -0
angr/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=wildcard-import
2
2
  # pylint: disable=wrong-import-position
3
3
 
4
- __version__ = "9.2.78"
4
+ __version__ = "9.2.79"
5
5
 
6
6
  if bytes is str:
7
7
  raise Exception(
angr/__main__.py ADDED
@@ -0,0 +1,34 @@
1
+ import argparse
2
+
3
+ from angr.analyses.decompiler.structuring import STRUCTURER_CLASSES
4
+ from angr.analyses.decompiler.utils import decompile_functions
5
+
6
+
7
+ class COMMANDS:
8
+ """
9
+ The commands that the angr CLI supports.
10
+ """
11
+
12
+ DECOMPILE = "decompile"
13
+ ALL_COMMANDS = [DECOMPILE]
14
+
15
+
16
+ def main():
17
+ parser = argparse.ArgumentParser(description="The angr CLI allows you to decompile and analyze binaries.")
18
+ parser.add_argument("command", help="The command to run", choices=COMMANDS.ALL_COMMANDS)
19
+ parser.add_argument("binary", help="The path to the binary to analyze")
20
+ parser.add_argument("--functions", help="The functions to analyze", nargs="+")
21
+ parser.add_argument(
22
+ "--structurer", help="The structurer to use", choices=STRUCTURER_CLASSES.keys(), default="phoenix"
23
+ )
24
+
25
+ args = parser.parse_args()
26
+ if args.command == COMMANDS.DECOMPILE:
27
+ decompilation = decompile_functions(args.binary, functions=args.functions, structurer=args.structurer)
28
+ print(decompilation)
29
+ else:
30
+ parser.print_help()
31
+
32
+
33
+ if __name__ == "__main__":
34
+ main()
@@ -4586,6 +4586,18 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
4586
4586
  ):
4587
4587
  rbp_as_gpr = False
4588
4588
  break
4589
+ elif (
4590
+ insn.mnemonic == "lea"
4591
+ and len(insn.operands) == 2
4592
+ and insn.operands[0].type == capstone.x86.X86_OP_REG
4593
+ and insn.operands[1].type == capstone.x86.X86_OP_MEM
4594
+ ):
4595
+ if (
4596
+ insn.operands[0].reg == capstone.x86.X86_REG_RBP
4597
+ and insn.operands[1].mem.base == capstone.x86.X86_REG_RSP
4598
+ ):
4599
+ rbp_as_gpr = False
4600
+ break
4589
4601
  func = self.kb.functions.get_by_addr(func_addr)
4590
4602
  func.info["bp_as_gpr"] = rbp_as_gpr
4591
4603
 
@@ -15,8 +15,15 @@ from ...analyses.propagator import PropagatorAnalysis
15
15
  from ...analyses.reaching_definitions import ReachingDefinitionsAnalysis
16
16
  from ...errors import SimMemoryMissingError
17
17
  from .. import Analysis, register_analysis
18
- from .peephole_optimizations import STMT_OPTS, EXPR_OPTS, PeepholeOptimizationStmtBase, PeepholeOptimizationExprBase
19
- from .utils import peephole_optimize_exprs, peephole_optimize_stmts
18
+ from .peephole_optimizations import (
19
+ MULTI_STMT_OPTS,
20
+ STMT_OPTS,
21
+ EXPR_OPTS,
22
+ PeepholeOptimizationStmtBase,
23
+ PeepholeOptimizationExprBase,
24
+ PeepholeOptimizationMultiStmtBase,
25
+ )
26
+ from .utils import peephole_optimize_exprs, peephole_optimize_stmts, peephole_optimize_multistmts
20
27
 
21
28
  if TYPE_CHECKING:
22
29
  from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
@@ -78,6 +85,7 @@ class BlockSimplifier(Analysis):
78
85
  if peephole_optimizations is None:
79
86
  self._expr_peephole_opts = [cls(self.project, self.kb, self.func_addr) for cls in EXPR_OPTS]
80
87
  self._stmt_peephole_opts = [cls(self.project, self.kb, self.func_addr) for cls in STMT_OPTS]
88
+ self._multistmt_peephole_opts = [cls(self.project, self.kb, self.func_addr) for cls in MULTI_STMT_OPTS]
81
89
  else:
82
90
  self._expr_peephole_opts = [
83
91
  cls(self.project, self.kb, self.func_addr)
@@ -89,6 +97,11 @@ class BlockSimplifier(Analysis):
89
97
  for cls in peephole_optimizations
90
98
  if issubclass(cls, PeepholeOptimizationStmtBase)
91
99
  ]
100
+ self._multistmt_peephole_opts = [
101
+ cls(self.project, self.kb, self.func_addr)
102
+ for cls in peephole_optimizations
103
+ if issubclass(cls, PeepholeOptimizationMultiStmtBase)
104
+ ]
92
105
 
93
106
  self.result_block = None
94
107
 
@@ -404,9 +417,16 @@ class BlockSimplifier(Analysis):
404
417
  # run statement-level optimizations
405
418
  statements, stmts_updated = peephole_optimize_stmts(block, self._stmt_peephole_opts)
406
419
 
407
- if not stmts_updated:
408
- return block
409
- new_block = block.copy(statements=statements)
420
+ if stmts_updated:
421
+ new_block = block.copy(statements=statements)
422
+ else:
423
+ new_block = block
424
+
425
+ statements, multi_stmts_updated = peephole_optimize_multistmts(new_block, self._multistmt_peephole_opts)
426
+
427
+ if not multi_stmts_updated:
428
+ return new_block
429
+ new_block = new_block.copy(statements=statements)
410
430
  return new_block
411
431
 
412
432
 
@@ -20,6 +20,7 @@ from ...sim_type import (
20
20
  SimTypeFunction,
21
21
  SimTypeBottom,
22
22
  SimTypeFloat,
23
+ SimTypePointer,
23
24
  )
24
25
  from ...sim_variable import SimVariable, SimStackVariable, SimRegisterVariable, SimMemoryVariable
25
26
  from ...knowledge_plugins.key_definitions.constants import OP_BEFORE
@@ -1247,23 +1248,32 @@ class Clinic(Analysis):
1247
1248
  expr.variable_offset = offset
1248
1249
 
1249
1250
  elif isinstance(expr, ailment.Expr.Const):
1250
- # global variable?
1251
- global_vars = global_variables.get_global_variables(expr.value)
1252
- if not global_vars:
1253
- # detect if there is a related symbol
1254
- if self.project.loader.find_object_containing(expr.value):
1255
- symbol = self.project.loader.find_symbol(expr.value)
1256
- if symbol is not None:
1257
- # Create a new global variable if there isn't one already
1258
- global_vars = global_variables.get_global_variables(symbol.rebased_addr)
1259
- if not global_vars:
1260
- global_var = SimMemoryVariable(symbol.rebased_addr, symbol.size, name=symbol.name)
1261
- global_variables.add_variable("global", global_var.addr, global_var)
1262
- global_vars = {global_var}
1263
- if global_vars:
1264
- global_var = next(iter(global_vars))
1265
- expr.tags["reference_variable"] = global_var
1266
- expr.tags["reference_variable_offset"] = 0
1251
+ # custom string?
1252
+ if hasattr(expr, "custom_string") and expr.custom_string is True:
1253
+ s = self.kb.custom_strings[expr.value]
1254
+ expr.tags["reference_values"] = {
1255
+ SimTypePointer(SimTypeChar().with_arch(self.project.arch)).with_arch(self.project.arch): s.decode(
1256
+ "ascii"
1257
+ ),
1258
+ }
1259
+ else:
1260
+ # global variable?
1261
+ global_vars = global_variables.get_global_variables(expr.value)
1262
+ if not global_vars:
1263
+ # detect if there is a related symbol
1264
+ if self.project.loader.find_object_containing(expr.value):
1265
+ symbol = self.project.loader.find_symbol(expr.value)
1266
+ if symbol is not None:
1267
+ # Create a new global variable if there isn't one already
1268
+ global_vars = global_variables.get_global_variables(symbol.rebased_addr)
1269
+ if not global_vars:
1270
+ global_var = SimMemoryVariable(symbol.rebased_addr, symbol.size, name=symbol.name)
1271
+ global_variables.add_variable("global", global_var.addr, global_var)
1272
+ global_vars = {global_var}
1273
+ if global_vars:
1274
+ global_var = next(iter(global_vars))
1275
+ expr.tags["reference_variable"] = global_var
1276
+ expr.tags["reference_variable_offset"] = 0
1267
1277
 
1268
1278
  elif isinstance(expr, ailment.Stmt.Call):
1269
1279
  self._link_variables_on_call(variable_manager, global_variables, block, stmt_idx, expr, is_expr=True)
@@ -50,6 +50,8 @@ def get_optimization_passes(arch, platform):
50
50
 
51
51
  if platform is not None:
52
52
  platform = platform.lower()
53
+ if platform == "win32":
54
+ platform = "windows" # sigh
53
55
 
54
56
  passes = []
55
57
  for pass_, _ in _all_optimization_passes:
@@ -89,7 +89,7 @@ class SimplifierAILEngine(
89
89
  if hasattr(self, handler):
90
90
  return getattr(self, handler)(stmt)
91
91
  else:
92
- _l.warning("Unsupported statement type %s.", type(stmt).__name__)
92
+ _l.debug("Unsupported statement type %s.", type(stmt).__name__)
93
93
  return stmt
94
94
 
95
95
  def _ail_handle_Assignment(self, stmt):
@@ -176,7 +176,7 @@ class SimplifierAILEngine(
176
176
  if v is None:
177
177
  return expr
178
178
  return v
179
- _l.warning("Unsupported expression type %s.", type(expr).__name__)
179
+ _l.debug("Unsupported expression type %s.", type(expr).__name__)
180
180
  return expr
181
181
 
182
182
  def _ail_handle_StackBaseOffset(self, expr): # pylint:disable=no-self-use
@@ -84,9 +84,9 @@ class ITERegionConverter(OptimizationPass):
84
84
 
85
85
  true_child, false_child = None, None
86
86
  for child in children:
87
- if child.addr == if_stmt.true_target.value:
87
+ if if_stmt.true_target is not None and child.addr == if_stmt.true_target.value:
88
88
  true_child = child
89
- elif child.addr == if_stmt.false_target.value:
89
+ elif if_stmt.false_target is not None and child.addr == if_stmt.false_target.value:
90
90
  false_child = child
91
91
 
92
92
  if (
@@ -3,6 +3,7 @@ from typing import Set, Dict
3
3
  from collections import defaultdict
4
4
  import logging
5
5
 
6
+ import capstone
6
7
  import ailment
7
8
  import cle
8
9
 
@@ -48,24 +49,24 @@ class WinStackCanarySimplifier(OptimizationPass):
48
49
  return False, None
49
50
 
50
51
  # Check the first block and see if there is any statement reading data from _security_cookie
51
- init_stmt = self._find_canary_init_stmt()
52
+ init_stmts = self._find_canary_init_stmt()
52
53
 
53
- return init_stmt is not None, {"init_stmt": init_stmt}
54
+ return init_stmts is not None, {"init_stmts": init_stmts}
54
55
 
55
56
  def _analyze(self, cache=None):
56
- init_stmt = None
57
+ init_stmts = None
57
58
  if cache is not None:
58
- init_stmt = cache.get("init_stmt", None)
59
+ init_stmts = cache.get("init_stmts", None)
59
60
 
60
- if init_stmt is None:
61
- init_stmt = self._find_canary_init_stmt()
61
+ if init_stmts is None:
62
+ init_stmts = self._find_canary_init_stmt()
62
63
 
63
- if init_stmt is None:
64
+ if init_stmts is None:
64
65
  return
65
66
 
66
67
  # Look for the statement that loads back canary value from the stack
67
- first_block, canary_init_stmt_idx = init_stmt
68
- canary_init_stmt = first_block.statements[canary_init_stmt_idx]
68
+ first_block, canary_init_stmt_ids = init_stmts
69
+ canary_init_stmt = first_block.statements[canary_init_stmt_ids[-1]]
69
70
  # where is the stack canary stored?
70
71
  if not isinstance(canary_init_stmt.addr, ailment.Expr.StackBaseOffset):
71
72
  _l.debug(
@@ -142,7 +143,8 @@ class WinStackCanarySimplifier(OptimizationPass):
142
143
  if found_endpoints:
143
144
  # Remove the statement that loads the stack canary from fs
144
145
  first_block_copy = first_block.copy()
145
- first_block_copy.statements.pop(canary_init_stmt_idx)
146
+ for stmt_idx in sorted(canary_init_stmt_ids, reverse=True):
147
+ first_block_copy.statements.pop(stmt_idx)
146
148
  self._update_block(first_block, first_block_copy)
147
149
 
148
150
  def _find_canary_init_stmt(self):
@@ -150,7 +152,13 @@ class WinStackCanarySimplifier(OptimizationPass):
150
152
  if first_block is None:
151
153
  return None
152
154
 
155
+ load_stmt_idx = None
156
+ load_reg = None
157
+ xor_stmt_idx = None
158
+ xored_reg = None
159
+
153
160
  for idx, stmt in enumerate(first_block.statements):
161
+ # if we are lucky and things get folded into one statement:
154
162
  if (
155
163
  isinstance(stmt, ailment.Stmt.Store)
156
164
  and isinstance(stmt.addr, ailment.Expr.StackBaseOffset)
@@ -163,13 +171,51 @@ class WinStackCanarySimplifier(OptimizationPass):
163
171
  # Check addr: must be __security_cookie
164
172
  load_addr = stmt.data.operands[0].addr.value
165
173
  if load_addr == self._security_cookie_addr:
166
- return first_block, idx
174
+ return first_block, [idx]
175
+ # or if we are unlucky and the load and the xor are two different statements
176
+ if (
177
+ isinstance(stmt, ailment.Stmt.Assignment)
178
+ and isinstance(stmt.dst, ailment.Expr.Register)
179
+ and isinstance(stmt.src, ailment.Expr.Load)
180
+ and isinstance(stmt.src.addr, ailment.Expr.Const)
181
+ ):
182
+ load_addr = stmt.src.addr.value
183
+ if load_addr == self._security_cookie_addr:
184
+ load_stmt_idx = idx
185
+ load_reg = stmt.dst.reg_offset
186
+ if load_stmt_idx is not None and idx == load_stmt_idx + 1:
187
+ if (
188
+ isinstance(stmt, ailment.Stmt.Assignment)
189
+ and isinstance(stmt.dst, ailment.Expr.Register)
190
+ and isinstance(stmt.src, ailment.Expr.BinaryOp)
191
+ and stmt.src.op == "Xor"
192
+ and isinstance(stmt.src.operands[0], ailment.Expr.Register)
193
+ and stmt.src.operands[0].reg_offset == load_reg
194
+ and isinstance(stmt.src.operands[1], ailment.Expr.StackBaseOffset)
195
+ ):
196
+ xor_stmt_idx = idx
197
+ xored_reg = stmt.dst.reg_offset
198
+ else:
199
+ break
200
+ if xor_stmt_idx is not None and idx == xor_stmt_idx + 1:
201
+ if (
202
+ isinstance(stmt, ailment.Stmt.Store)
203
+ and isinstance(stmt.addr, ailment.Expr.StackBaseOffset)
204
+ and isinstance(stmt.data, ailment.Expr.Register)
205
+ and stmt.data.reg_offset == xored_reg
206
+ ):
207
+ return first_block, [load_stmt_idx, xor_stmt_idx, idx]
208
+ else:
209
+ break
167
210
 
168
211
  return None
169
212
 
170
213
  @staticmethod
171
214
  def _find_amd64_canary_storing_stmt(block, canary_value_stack_offset):
215
+ load_stmt_idx = None
216
+
172
217
  for idx, stmt in enumerate(block.statements):
218
+ # when we are lucky, we have one instruction
173
219
  if (
174
220
  isinstance(stmt, ailment.Stmt.Assignment)
175
221
  and isinstance(stmt.dst, ailment.Expr.Register)
@@ -185,7 +231,29 @@ class WinStackCanarySimplifier(OptimizationPass):
185
231
  if isinstance(op1, ailment.Expr.StackBaseOffset):
186
232
  # found it
187
233
  return idx
188
-
234
+ # or when we are unlucky, we have two instructions...
235
+ if (
236
+ isinstance(stmt, ailment.Stmt.Assignment)
237
+ and isinstance(stmt.dst, ailment.Expr.Register)
238
+ and stmt.dst.reg_name == "rcx"
239
+ and isinstance(stmt.src, ailment.Expr.Load)
240
+ and isinstance(stmt.src.addr, ailment.Expr.StackBaseOffset)
241
+ and stmt.src.addr.offset == canary_value_stack_offset
242
+ ):
243
+ load_stmt_idx = idx
244
+ if load_stmt_idx is not None and idx == load_stmt_idx + 1:
245
+ if (
246
+ isinstance(stmt, ailment.Stmt.Assignment)
247
+ and isinstance(stmt.dst, ailment.Expr.Register)
248
+ and isinstance(stmt.src, ailment.Expr.BinaryOp)
249
+ and stmt.src.op == "Xor"
250
+ ):
251
+ if (
252
+ isinstance(stmt.src.operands[0], ailment.Expr.Register)
253
+ and stmt.src.operands[0].reg_name == "rcx"
254
+ and isinstance(stmt.src.operands[1], ailment.Expr.StackBaseOffset)
255
+ ):
256
+ return idx
189
257
  return None
190
258
 
191
259
  @staticmethod
@@ -200,6 +268,29 @@ class WinStackCanarySimplifier(OptimizationPass):
200
268
  return idx
201
269
  return None
202
270
 
271
+ def _is_function_likely_security_check_cookie(self, func) -> bool:
272
+ # disassemble the first instruction
273
+ if func.is_plt or func.is_syscall or func.is_simprocedure:
274
+ return False
275
+ block = self.project.factory.block(func.addr)
276
+ if block.instructions != 2:
277
+ return False
278
+ ins0 = block.capstone.insns[0]
279
+ if (
280
+ ins0.mnemonic == "cmp"
281
+ and len(ins0.operands) == 2
282
+ and ins0.operands[0].type == capstone.x86.X86_OP_REG
283
+ and ins0.operands[0].reg == capstone.x86.X86_REG_RCX
284
+ and ins0.operands[1].type == capstone.x86.X86_OP_MEM
285
+ and ins0.operands[1].mem.base == capstone.x86.X86_REG_RIP
286
+ and ins0.operands[1].mem.index == 0
287
+ and ins0.operands[1].mem.disp + ins0.address + ins0.size == self._security_cookie_addr
288
+ ):
289
+ ins1 = block.capstone.insns[1]
290
+ if ins1.mnemonic == "jne":
291
+ return True
292
+ return False
293
+
203
294
  def _find_stmt_calling_security_check_cookie(self, node):
204
295
  for idx, stmt in enumerate(node.statements):
205
296
  if isinstance(stmt, ailment.Stmt.Call) and isinstance(stmt.target, ailment.Expr.Const):
@@ -208,5 +299,7 @@ class WinStackCanarySimplifier(OptimizationPass):
208
299
  func = self.kb.functions.function(addr=const_target)
209
300
  if func.name == "_security_check_cookie":
210
301
  return idx
302
+ elif self._is_function_likely_security_check_cookie(func):
303
+ return idx
211
304
 
212
305
  return None
@@ -40,10 +40,12 @@ from .sar_to_signed_div import SarToSignedDiv
40
40
  from .tidy_stack_addr import TidyStackAddr
41
41
  from .invert_negated_logical_conjuction_disjunction import InvertNegatedLogicalConjunctionsAndDisjunctions
42
42
  from .rol_ror import RolRorRewriter
43
+ from .inlined_strcpy import InlinedStrcpy
44
+ from .inlined_strcpy_consolidation import InlinedStrcpyConsolidation
43
45
 
44
- from .base import PeepholeOptimizationExprBase, PeepholeOptimizationStmtBase
45
-
46
+ from .base import PeepholeOptimizationExprBase, PeepholeOptimizationStmtBase, PeepholeOptimizationMultiStmtBase
46
47
 
48
+ MULTI_STMT_OPTS: List[Type[PeepholeOptimizationMultiStmtBase]] = []
47
49
  STMT_OPTS: List[Type[PeepholeOptimizationStmtBase]] = []
48
50
  EXPR_OPTS: List[Type[PeepholeOptimizationExprBase]] = []
49
51
 
@@ -55,4 +57,11 @@ for v in _g.values():
55
57
  if isinstance(v, type) and issubclass(v, PeepholeOptimizationStmtBase) and v is not PeepholeOptimizationStmtBase:
56
58
  STMT_OPTS.append(v)
57
59
 
60
+ if (
61
+ isinstance(v, type)
62
+ and issubclass(v, PeepholeOptimizationMultiStmtBase)
63
+ and v is not PeepholeOptimizationMultiStmtBase
64
+ ):
65
+ MULTI_STMT_OPTS.append(v)
66
+
58
67
  _g = None
@@ -1,7 +1,7 @@
1
- from typing import Optional
1
+ from typing import List, Optional
2
2
 
3
3
  from ailment.expression import BinaryOp, UnaryOp, Expression
4
- from ailment.statement import Assignment
4
+ from ailment.statement import Statement, Assignment
5
5
  from ailment import Block
6
6
  from angr.project import Project
7
7
  from angr.knowledge_base import KnowledgeBase
@@ -34,6 +34,33 @@ class PeepholeOptimizationStmtBase:
34
34
  raise NotImplementedError("_optimize() is not implemented.")
35
35
 
36
36
 
37
+ class PeepholeOptimizationMultiStmtBase:
38
+ """
39
+ The base class for all peephole optimizations that are applied on multiple AIL statements at once.
40
+ """
41
+
42
+ __slots__ = (
43
+ "project",
44
+ "kb",
45
+ "func_addr",
46
+ )
47
+ project: Optional[Project]
48
+ kb: Optional[KnowledgeBase]
49
+ func_addr: Optional[int]
50
+
51
+ NAME = "Peephole Optimization - Multi-statement"
52
+ DESCRIPTION = "Peephole Optimization - Multi-statement"
53
+ stmt_classes = None
54
+
55
+ def __init__(self, project: Optional[Project], kb: Optional[KnowledgeBase], func_addr: Optional[int] = None):
56
+ self.project = project
57
+ self.kb = kb
58
+ self.func_addr = func_addr
59
+
60
+ def optimize(self, stmts: List[Statement], stmt_idx: Optional[int] = None, block=None, **kwargs):
61
+ raise NotImplementedError("_optimize() is not implemented.")
62
+
63
+
37
64
  class PeepholeOptimizationExprBase:
38
65
  """
39
66
  The base class for all peephole optimizations that are applied on AIL expressions.
@@ -20,7 +20,7 @@ class ConstantDereferences(PeepholeOptimizationExprBase):
20
20
  if sec is not None and sec.is_readable and (not sec.is_writable or "got" in sec.name):
21
21
  # do we know the value that it's reading?
22
22
  try:
23
- val = self.project.loader.memory.unpack_word(expr.addr.value, size=self.project.arch.bytes)
23
+ val = self.project.loader.memory.unpack_word(expr.addr.value, size=expr.size)
24
24
  except KeyError:
25
25
  return expr
26
26
 
@@ -0,0 +1,83 @@
1
+ # pylint:disable=arguments-differ
2
+ from typing import Tuple, Optional
3
+ import string
4
+
5
+ from archinfo import Endness
6
+
7
+ from ailment.expression import Const
8
+ from ailment.statement import Call, Store
9
+
10
+ from .base import PeepholeOptimizationStmtBase
11
+
12
+
13
+ ASCII_PRINTABLES = set(string.printable)
14
+ ASCII_DIGITS = set(string.digits)
15
+
16
+
17
+ class InlinedStrcpy(PeepholeOptimizationStmtBase):
18
+ """
19
+ Simplifies inlined string copying logic into calls to strcpy.
20
+ """
21
+
22
+ __slots__ = ()
23
+
24
+ NAME = "Simplifying inlined strcpy"
25
+ stmt_classes = (Store,)
26
+
27
+ def optimize(self, stmt: Store, **kwargs):
28
+ if isinstance(stmt.data, Const):
29
+ r, s = self.is_integer_likely_a_string(stmt.data.value, stmt.data.size, stmt.endness)
30
+ if r:
31
+ # replace it with a call to strncpy
32
+ str_id = self.kb.custom_strings.allocate(s.encode("ascii"))
33
+ return Call(
34
+ stmt.idx,
35
+ "strncpy",
36
+ args=[
37
+ stmt.addr,
38
+ Const(None, None, str_id, stmt.addr.bits, custom_string=True),
39
+ Const(None, None, len(s), self.project.arch.bits),
40
+ ],
41
+ **stmt.tags,
42
+ )
43
+
44
+ return None
45
+
46
+ @staticmethod
47
+ def is_integer_likely_a_string(
48
+ v: int, size: int, endness: Endness, min_length: int = 4
49
+ ) -> Tuple[bool, Optional[str]]:
50
+ # we need at least four bytes of printable characters
51
+
52
+ chars = []
53
+ if endness == Endness.LE:
54
+ while v != 0:
55
+ byt = v & 0xFF
56
+ if chr(byt) not in ASCII_PRINTABLES:
57
+ return False, None
58
+ chars.append(chr(byt))
59
+ v >>= 8
60
+
61
+ elif endness == Endness.BE:
62
+ first_non_zero = False
63
+ for _ in range(size):
64
+ byt = v & 0xFF
65
+ v >>= 8
66
+ if byt == 0:
67
+ if first_non_zero:
68
+ return False, None
69
+ continue
70
+ first_non_zero = True # this is the first non-zero byte
71
+ if chr(byt) not in ASCII_PRINTABLES:
72
+ return False, None
73
+ chars.append(chr(byt))
74
+ chars = chars[::-1]
75
+ else:
76
+ # unsupported endness
77
+ return False, None
78
+
79
+ if len(chars) >= min_length:
80
+ if len(chars) <= 4 and all(ch in ASCII_DIGITS for ch in chars):
81
+ return False, None
82
+ return True, "".join(chars)
83
+ return False, None
@@ -0,0 +1,103 @@
1
+ # pylint:disable=arguments-differ
2
+ from typing import List, Tuple, Optional
3
+
4
+ from ailment.expression import Expression, BinaryOp, Const, Register, StackBaseOffset
5
+ from ailment.statement import Call, Store
6
+
7
+ from .base import PeepholeOptimizationMultiStmtBase
8
+ from .inlined_strcpy import InlinedStrcpy
9
+
10
+
11
+ class InlinedStrcpyConsolidation(PeepholeOptimizationMultiStmtBase):
12
+ """
13
+ Consolidate multiple inlined strcpy calls.
14
+ """
15
+
16
+ __slots__ = ()
17
+
18
+ NAME = "Consolidate multiple inlined strcpy calls"
19
+ stmt_classes = ((Call, Call), (Call, Store))
20
+
21
+ def optimize(self, stmts: List[Call], **kwargs):
22
+ last_stmt, stmt = stmts
23
+ if InlinedStrcpyConsolidation._is_inlined_strcpy(last_stmt):
24
+ s_last: bytes = self.kb.custom_strings[last_stmt.args[1].value]
25
+ addr_last = last_stmt.args[0]
26
+ new_str = None # will be set if consolidation should happen
27
+
28
+ if isinstance(stmt, Call) and InlinedStrcpyConsolidation._is_inlined_strcpy(stmt):
29
+ # consolidating two calls
30
+ s_curr: bytes = self.kb.custom_strings[stmt.args[1].value]
31
+ addr_curr = stmt.args[0]
32
+ # determine if the two addresses are consecutive
33
+ delta = self._get_delta(addr_last, addr_curr)
34
+ if delta is not None and delta == len(s_last):
35
+ # consolidate both calls!
36
+ new_str = s_last + s_curr
37
+ elif isinstance(stmt, Store) and isinstance(stmt.data, Const):
38
+ # consolidating a call and a store, in case the store statement is storing the suffix of a string (but
39
+ # the suffix is too short to qualify an inlined strcpy optimization)
40
+ addr_curr = stmt.addr
41
+ delta = self._get_delta(addr_last, addr_curr)
42
+ if delta is not None and delta == len(s_last):
43
+ if stmt.size == 1 and stmt.data.value == 0:
44
+ # it's probably the terminating null byte
45
+ r, s = True, "\x00"
46
+ else:
47
+ r, s = InlinedStrcpy.is_integer_likely_a_string(
48
+ stmt.data.value, stmt.size, stmt.endness, min_length=1
49
+ )
50
+ if r:
51
+ new_str = s_last + s.encode("ascii")
52
+
53
+ if new_str is not None:
54
+ if new_str.endswith(b"\x00"):
55
+ call_name = "strcpy"
56
+ new_str_idx = self.kb.custom_strings.allocate(new_str[:-1])
57
+ args = [
58
+ last_stmt.args[0],
59
+ Const(None, None, new_str_idx, last_stmt.args[0].bits, custom_string=True),
60
+ ]
61
+ else:
62
+ call_name = "strncpy"
63
+ new_str_idx = self.kb.custom_strings.allocate(new_str)
64
+ args = [
65
+ last_stmt.args[0],
66
+ Const(None, None, new_str_idx, last_stmt.args[0].bits, custom_string=True),
67
+ Const(None, None, len(new_str), self.project.arch.bits),
68
+ ]
69
+
70
+ return [Call(stmt.idx, call_name, args=args, **stmt.tags)]
71
+
72
+ return None
73
+
74
+ @staticmethod
75
+ def _is_inlined_strcpy(stmt: Call):
76
+ if isinstance(stmt.target, str) and stmt.target == "strncpy":
77
+ if len(stmt.args) == 3 and isinstance(stmt.args[1], Const) and hasattr(stmt.args[1], "custom_string"):
78
+ return True
79
+ return False
80
+
81
+ @staticmethod
82
+ def _parse_addr(addr: Expression) -> Tuple[Expression, int]:
83
+ if isinstance(addr, Register):
84
+ return addr, 0
85
+ if isinstance(addr, StackBaseOffset):
86
+ return StackBaseOffset(None, addr.bits, 0), addr.offset
87
+ if isinstance(addr, BinaryOp):
88
+ if addr.op == "Add" and isinstance(addr.operands[1], Const):
89
+ base_0, offset_0 = InlinedStrcpyConsolidation._parse_addr(addr.operands[0])
90
+ return base_0, offset_0 + addr.operands[1].value
91
+ if addr.op == "Sub" and isinstance(addr.operands[1], Const):
92
+ base_0, offset_0 = InlinedStrcpyConsolidation._parse_addr(addr.operands[0])
93
+ return base_0, offset_0 - addr.operands[1].value
94
+
95
+ return addr, 0
96
+
97
+ @staticmethod
98
+ def _get_delta(addr_0: Expression, addr_1: Expression) -> Optional[int]:
99
+ base_0, offset_0 = InlinedStrcpyConsolidation._parse_addr(addr_0)
100
+ base_1, offset_1 = InlinedStrcpyConsolidation._parse_addr(addr_1)
101
+ if base_0.likes(base_1):
102
+ return offset_1 - offset_0
103
+ return None
@@ -2037,11 +2037,22 @@ class CConstant(CExpression):
2037
2037
  return
2038
2038
  yield hex(self.reference_values[self._type]), self
2039
2039
  elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeChar):
2040
- refval = self.reference_values[self._type] # angr.knowledge_plugin.cfg.MemoryData
2041
- yield CConstant.str_to_c_str(refval.content.decode("utf-8")), self
2040
+ refval = self.reference_values[self._type]
2041
+ if isinstance(refval, MemoryData):
2042
+ v = refval.content.decode("utf-8")
2043
+ else:
2044
+ # it's a string
2045
+ assert isinstance(v, str)
2046
+ v = refval
2047
+ yield CConstant.str_to_c_str(v), self
2042
2048
  elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeWideChar):
2043
- refval = self.reference_values[self._type] # angr.knowledge_plugin.cfg.MemoryData
2044
- yield CConstant.str_to_c_str(refval.content.decode("utf_16_le"), prefix="L"), self
2049
+ refval = self.reference_values[self._type]
2050
+ if isinstance(refval, MemoryData):
2051
+ v = refval.content.decode("utf_16_le")
2052
+ else:
2053
+ # it's a string
2054
+ v = refval
2055
+ yield CConstant.str_to_c_str(v, prefix="L"), self
2045
2056
  else:
2046
2057
  if isinstance(self.reference_values[self._type], int):
2047
2058
  yield self.fmt_int(self.reference_values[self._type]), self
@@ -3199,6 +3210,11 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3199
3210
  inline_string = False
3200
3211
  function_pointer = False
3201
3212
 
3213
+ if reference_values is None and hasattr(expr, "reference_values"):
3214
+ reference_values = expr.reference_values.copy()
3215
+ if reference_values:
3216
+ type_ = next(iter(reference_values))
3217
+
3202
3218
  if reference_values is None:
3203
3219
  reference_values = {}
3204
3220
  type_ = unpack_typeref(type_)
@@ -1,9 +1,14 @@
1
- # pylint:disable=wrong-import-position
2
- from typing import Optional, Tuple, Any, Union, List
1
+ import pathlib
2
+ from typing import Optional, Tuple, Any, Union, List, Iterable
3
+ import logging
3
4
 
4
5
  import networkx
6
+ from rich.progress import track
5
7
 
6
8
  import ailment
9
+ import angr
10
+
11
+ _l = logging.getLogger(__name__)
7
12
 
8
13
 
9
14
  def remove_last_statement(node):
@@ -533,6 +538,127 @@ def peephole_optimize_stmts(block, stmt_opts):
533
538
  return statements, any_update
534
539
 
535
540
 
541
+ def match_stmt_classes(all_stmts: List, idx: int, stmt_class_seq: Iterable[type]) -> bool:
542
+ for i, cls in enumerate(stmt_class_seq):
543
+ if idx + i >= len(all_stmts):
544
+ return False
545
+ if not isinstance(all_stmts[idx + i], cls):
546
+ return False
547
+ return True
548
+
549
+
550
+ def peephole_optimize_multistmts(block, stmt_opts):
551
+ any_update = False
552
+ statements = block.statements[::]
553
+
554
+ # run multi-statement optimizers
555
+ stmt_idx = 0
556
+ while stmt_idx < len(statements):
557
+ redo = True
558
+ while redo and stmt_idx < len(statements):
559
+ redo = False
560
+ for opt in stmt_opts:
561
+ matched = False
562
+ stmt_seq_len = None
563
+ for stmt_class_seq in opt.stmt_classes:
564
+ if match_stmt_classes(statements, stmt_idx, stmt_class_seq):
565
+ stmt_seq_len = len(stmt_class_seq)
566
+ matched = True
567
+ break
568
+
569
+ if matched:
570
+ matched_stmts = statements[stmt_idx : stmt_idx + stmt_seq_len]
571
+ r = opt.optimize(matched_stmts, stmt_idx=stmt_idx, block=block)
572
+ if r is not None:
573
+ # update statements
574
+ statements = statements[:stmt_idx] + r + statements[stmt_idx + stmt_seq_len :]
575
+ any_update = True
576
+ redo = True
577
+ break
578
+
579
+ # move on to the next statement
580
+ stmt_idx += 1
581
+
582
+ return statements, any_update
583
+
584
+
585
+ def decompile_functions(path, functions=None, structurer=None, catch_errors=True) -> Optional[str]:
586
+ """
587
+ Decompile a binary into a set of functions.
588
+
589
+ :param path: The path to the binary to decompile.
590
+ :param functions: The functions to decompile. If None, all functions will be decompiled.
591
+ :param structurer: The structuring algorithms to use.
592
+ :param catch_errors: The structuring algorithms to use.
593
+ :return: The decompilation of all functions appended in order.
594
+ """
595
+ # delayed imports to avoid circular imports
596
+ from angr.analyses.decompiler.decompilation_options import PARAM_TO_OPTION
597
+
598
+ structurer = structurer or "phoenix"
599
+ path = pathlib.Path(path).resolve().absolute()
600
+ proj = angr.Project(path, auto_load_libs=False)
601
+ cfg = proj.analyses.CFG(normalize=True, data_references=True)
602
+ proj.analyses.CompleteCallingConventions(recover_variables=True, analyze_callsites=True)
603
+
604
+ # collect all functions when None are provided
605
+ if functions is None:
606
+ functions = cfg.functions.values()
607
+
608
+ # normalize the functions that could be ints as names
609
+ normalized_functions = []
610
+ for func in functions:
611
+ try:
612
+ normalized_name = int(func, 0)
613
+ except ValueError:
614
+ normalized_name = func
615
+ normalized_functions.append(normalized_name)
616
+ functions = normalized_functions
617
+
618
+ # verify that all functions exist
619
+ for func in functions:
620
+ if func not in cfg.functions:
621
+ raise ValueError(f"Function {func} does not exist in the CFG.")
622
+
623
+ # decompile all functions
624
+ decompilation = ""
625
+ dec_options = [
626
+ (PARAM_TO_OPTION["structurer_cls"], structurer),
627
+ ]
628
+ for func in track(functions, description="Decompiling functions", transient=True):
629
+ f = cfg.functions[func]
630
+ if f is None or f.is_plt:
631
+ continue
632
+
633
+ exception_string = ""
634
+ if not catch_errors:
635
+ dec = proj.analyses.Decompiler(f, cfg=cfg, options=dec_options)
636
+ else:
637
+ try:
638
+ # TODO: add a timeout
639
+ dec = proj.analyses.Decompiler(f, cfg=cfg, options=dec_options)
640
+ except Exception as e:
641
+ exception_string = str(e).replace("\n", " ")
642
+ dec = None
643
+
644
+ # do sanity checks on decompilation, skip checks if we already errored
645
+ if not exception_string:
646
+ if dec is None or not dec.codegen or not dec.codegen.text:
647
+ exception_string = "Decompilation had no code output (failed in Dec)"
648
+ elif "{\n}" in dec.codegen.text:
649
+ exception_string = "Decompilation outputted an empty function (failed in structuring)"
650
+ elif structurer in ["dream", "combing"] and "goto" in dec.codegen.text:
651
+ exception_string = "Decompilation outputted a goto for a Gotoless algorithm (failed in structuring)"
652
+
653
+ if exception_string:
654
+ _l.critical("Failed to decompile %s because %s", str(func), exception_string)
655
+ decompilation += f"// [error: {func} | {exception_string}]\n"
656
+ else:
657
+ decompilation += dec.codegen.text + "\n"
658
+
659
+ return decompilation
660
+
661
+
536
662
  # delayed import
537
663
  from .structuring.structurer_nodes import (
538
664
  MultiNode,
@@ -180,6 +180,33 @@ class ProximityGraphAnalysis(Analysis):
180
180
 
181
181
  self._work()
182
182
 
183
+ def _condense_blank_nodes(self, graph: networkx.DiGraph) -> None:
184
+ nodes = list(graph.nodes)
185
+ blank_nodes: List[BaseProxiNode] = []
186
+
187
+ for node in nodes:
188
+ if isinstance(node, BaseProxiNode) and node.type_ == ProxiNodeTypes.Empty:
189
+ blank_nodes.append(node)
190
+ else:
191
+ if blank_nodes:
192
+ self._merge_nodes(graph, blank_nodes)
193
+ blank_nodes = []
194
+
195
+ if blank_nodes:
196
+ self._merge_nodes(graph, blank_nodes)
197
+
198
+ def _merge_nodes(self, graph: networkx.DiGraph, nodes: List[BaseProxiNode]) -> None:
199
+ for node in nodes:
200
+ predecessors = set(graph.predecessors(node))
201
+ successors = set(graph.successors(node))
202
+
203
+ for pred in predecessors:
204
+ for succ in successors:
205
+ edge_data = graph.get_edge_data(pred, node) or {}
206
+ graph.add_edge(pred, succ, **edge_data)
207
+
208
+ graph.remove_node(node)
209
+
183
210
  def _work(self):
184
211
  self.graph = networkx.DiGraph()
185
212
 
@@ -210,6 +237,9 @@ class ProximityGraphAnalysis(Analysis):
210
237
  self.graph.add_nodes_from(subgraph.nodes())
211
238
  self.graph.add_edges_from(subgraph.edges())
212
239
 
240
+ # condense blank nodes after the graph has been constructed
241
+ self._condense_blank_nodes(self.graph)
242
+
213
243
  def _endnode_connector(self, func: "Function", subgraph: networkx.DiGraph):
214
244
  """
215
245
  Properly connect expanded function call's to proximity graph.
@@ -15,3 +15,4 @@ from .propagations import PropagationManager
15
15
  from .structured_code import StructuredCodeManager
16
16
  from .types import TypesStore
17
17
  from .callsite_prototypes import CallsitePrototypes
18
+ from .custom_strings import CustomStrings
@@ -0,0 +1,40 @@
1
+ from typing import Dict
2
+
3
+ from .plugin import KnowledgeBasePlugin
4
+
5
+
6
+ class CustomStrings(KnowledgeBasePlugin):
7
+ """
8
+ Store new strings that are recovered during various analysis. Each string has a unique ID associated.
9
+ """
10
+
11
+ def __init__(self, kb):
12
+ super().__init__()
13
+ self._kb = kb
14
+
15
+ self.string_id = 0
16
+ self.strings: Dict[int, bytes] = {}
17
+
18
+ def allocate(self, s: bytes) -> int:
19
+ # de-duplication
20
+ # TODO: Use a reverse map if this becomes a bottle-neck in the future
21
+ for idx, string in self.strings.items():
22
+ if string == s:
23
+ return idx
24
+
25
+ string_id = self.string_id
26
+ self.strings[string_id] = s
27
+ self.string_id += 1
28
+ return string_id
29
+
30
+ def __getitem__(self, idx):
31
+ return self.strings[idx]
32
+
33
+ def copy(self):
34
+ o = CustomStrings(self._kb)
35
+ o.strings = self.strings.copy()
36
+ o.string_id = self.string_id
37
+ return o
38
+
39
+
40
+ KnowledgeBasePlugin.register_default("custom_strings", CustomStrings)
@@ -80,6 +80,7 @@ class Function(Serializable):
80
80
  "is_alignment",
81
81
  "is_prototype_guessed",
82
82
  "ran_cca",
83
+ "_cyclomatic_complexity",
83
84
  )
84
85
 
85
86
  def __init__(
@@ -161,6 +162,9 @@ class Function(Serializable):
161
162
  self.info = {} # storing special information, like $gp values for MIPS32
162
163
  self.tags = () # store function tags. can be set manually by performing CodeTagging analysis.
163
164
 
165
+ # Initialize _cyclomatic_complexity to None
166
+ self._cyclomatic_complexity = None
167
+
164
168
  # TODO: Can we remove the following two members?
165
169
  # Register offsets of those arguments passed in registers
166
170
  self._argument_registers = []
@@ -302,6 +306,30 @@ class Function(Serializable):
302
306
  except (SimEngineError, SimMemoryError):
303
307
  pass
304
308
 
309
+ @property
310
+ def cyclomatic_complexity(self):
311
+ """
312
+ The cyclomatic complexity of the function.
313
+
314
+ Cyclomatic complexity is a software metric used to indicate the complexity of a program.
315
+ It is a quantitative measure of the number of linearly independent paths through a program's source code.
316
+ It is computed using the formula: M = E - N + 2P, where
317
+ E = the number of edges in the graph,
318
+ N = the number of nodes in the graph,
319
+ P = the number of connected components.
320
+
321
+ The cyclomatic complexity value is lazily computed and cached for future use.
322
+ Initially this value is None until it is computed for the first time
323
+
324
+ :return: The cyclomatic complexity of the function.
325
+ :rtype: int
326
+ """
327
+ if self._cyclomatic_complexity is None:
328
+ self._cyclomatic_complexity = (
329
+ self.transition_graph.number_of_edges() - self.transition_graph.number_of_nodes() + 2
330
+ )
331
+ return self._cyclomatic_complexity
332
+
305
333
  @property
306
334
  def xrefs(self):
307
335
  """
@@ -565,6 +593,7 @@ class Function(Serializable):
565
593
  s += " Alignment: %s\n" % (self.alignment)
566
594
  s += f" Arguments: reg: {self._argument_registers}, stack: {self._argument_stack_variables}\n"
567
595
  s += " Blocks: [%s]\n" % ", ".join(["%#x" % i for i in self.block_addrs])
596
+ s += " Cyclomatic Complexity: %s\n" % self.cyclomatic_complexity
568
597
  s += " Calling convention: %s" % self.calling_convention
569
598
  return s
570
599
 
angr/lib/angr_native.dll CHANGED
Binary file
@@ -13,6 +13,3 @@ libc.set_non_returning('_exit', 'abort', 'exit', '_invoke_watson')
13
13
  libc.add_alias('_initterm', '_initterm_e')
14
14
 
15
15
  libc.set_default_cc('AMD64', SimCCMicrosoftAMD64)
16
-
17
- for name, procedure in libc.procedures.items():
18
- libc.set_prototype(name, procedure.prototype)
angr/sim_type.py CHANGED
@@ -908,6 +908,9 @@ class SimTypeFunction(SimType):
908
908
  self.arg_names = arg_names if arg_names else ()
909
909
  self.variadic = variadic
910
910
 
911
+ def __hash__(self):
912
+ return hash(type(self)) ^ hash(tuple(self.args)) ^ hash(self.returnty)
913
+
911
914
  def __repr__(self):
912
915
  argstrs = [str(a) for a in self.args]
913
916
  if self.variadic:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: angr
3
- Version: 9.2.78
3
+ Version: 9.2.79
4
4
  Summary: A multi-architecture binary analysis toolkit, with the ability to perform dynamic symbolic execution and various static analyses on binaries
5
5
  Home-page: https://github.com/angr/angr
6
6
  License: BSD-2-Clause
@@ -17,13 +17,13 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: CppHeaderParser
19
19
  Requires-Dist: GitPython
20
- Requires-Dist: ailment ==9.2.78
21
- Requires-Dist: archinfo ==9.2.78
20
+ Requires-Dist: ailment ==9.2.79
21
+ Requires-Dist: archinfo ==9.2.79
22
22
  Requires-Dist: cachetools
23
23
  Requires-Dist: capstone ==5.0.0.post1
24
24
  Requires-Dist: cffi >=1.14.0
25
- Requires-Dist: claripy ==9.2.78
26
- Requires-Dist: cle ==9.2.78
25
+ Requires-Dist: claripy ==9.2.79
26
+ Requires-Dist: cle ==9.2.79
27
27
  Requires-Dist: dpkt
28
28
  Requires-Dist: itanium-demangler
29
29
  Requires-Dist: mulpyplexer
@@ -32,7 +32,7 @@ Requires-Dist: networkx !=2.8.1,>=2.0
32
32
  Requires-Dist: protobuf >=3.19.0
33
33
  Requires-Dist: psutil
34
34
  Requires-Dist: pycparser >=2.18
35
- Requires-Dist: pyvex ==9.2.78
35
+ Requires-Dist: pyvex ==9.2.79
36
36
  Requires-Dist: rich >=13.1.0
37
37
  Requires-Dist: rpyc
38
38
  Requires-Dist: sortedcontainers
@@ -1,4 +1,5 @@
1
- angr/__init__.py,sha256=lOMPCK4EHkY1X2WOKEcuVn-SA30QQJCJR14H3iJUmjM,3851
1
+ angr/__init__.py,sha256=1hDKCHV5WU-92kCqJB-WuVkZO28N6APe3LTVIuMzl7g,3851
2
+ angr/__main__.py,sha256=kdqGysHrVO1vaW6VC6v_OTmlCO7R1-eZpiEhArmi978,1095
2
3
  angr/annocfg.py,sha256=dK5JAdN4Ig_jgxTBZeZXwk3kAS4-IQUvE6T02GBZTDQ,10818
3
4
  angr/blade.py,sha256=YySrLqj2Y3-td9FJnkjDqYyFvAeGhc5a5lrGoHKOT2A,15562
4
5
  angr/block.py,sha256=FnsFukbXhLzYPW5zJRXMxNmvCRU4LFlFIaJwo5sAqkY,14468
@@ -19,7 +20,7 @@ angr/sim_options.py,sha256=OuT01xS_F3ifBD9MAfZmNCnfjtTg0HulZlrKcs1LNSY,18057
19
20
  angr/sim_procedure.py,sha256=TpYn5z6YMKjugyH_Lw9XcEaQc8cpTxtyorBKrRYMewA,26073
20
21
  angr/sim_state.py,sha256=BhAKyfvoGfqpgAPYYT4j7drrkOdPy03ucBO7LKMz0s0,37826
21
22
  angr/sim_state_options.py,sha256=lfP7ygngjGe0AGV5rkE24tvBazJBZG-RTdrKj4rL9XE,12530
22
- angr/sim_type.py,sha256=illcZU3EM_fQLlphIcNSCP-6rWtXYsIq47cxs3dLHZc,116952
23
+ angr/sim_type.py,sha256=ZU4uHgFcJyjvVMGza8_JluHKmAWbpT9S1Xb41qdydHU,117056
23
24
  angr/sim_variable.py,sha256=VIpKm4lguu_bKokjq4UB6Q_30Ogz9J7XRBJuH62lW60,17228
24
25
  angr/slicer.py,sha256=kbLKMAjf2kC6ov-OiGb95BqLmgV0QRl5mmEANcvzuAk,10640
25
26
  angr/state_hierarchy.py,sha256=w_5Tl-7h9xUXBsIKZRAWw8Xh0we8GIAaN6nbKgYH_Qo,8467
@@ -48,7 +49,7 @@ angr/analyses/flirt.py,sha256=-n6GShXV6PLKDHr4nML49ZwAAlmMIP5SDeF2KmJVKOM,7847
48
49
  angr/analyses/init_finder.py,sha256=hFHPsHipF4QkWzVqcDeTgL6YIaYi8bAyaURZBksS4KI,8531
49
50
  angr/analyses/loop_analysis.py,sha256=nIbDIzvys-FRtJYnoZYNbMWH5V88qrhoMtrMRCTbkLY,9412
50
51
  angr/analyses/loopfinder.py,sha256=X8F4Dcu2UHDXt6JifK6EfROAeeczyca6V7zxx9z7GpQ,7122
51
- angr/analyses/proximity_graph.py,sha256=Sm9oo8h9wtnP1hojsrjaAbkysqEHFjQQCSfZiET9244,15207
52
+ angr/analyses/proximity_graph.py,sha256=y30caPk5N4zOzkf8TF7AEOo0AR_yDhEFJrQB89_CTnM,16323
52
53
  angr/analyses/reassembler.py,sha256=b4EnHx36yS2DNq8nes7zr2_9SozqXbeTTx2538TCm84,100415
53
54
  angr/analyses/soot_class_hierarchy.py,sha256=Cs_LRV1RLXH6sF_E49tJWg9Inxvv_o5mB-VaIBcbQJg,8941
54
55
  angr/analyses/stack_pointer_tracker.py,sha256=rL8wF12Fe3P-RXAzk4caMYapB63tYX_qs-EO6E5l1n8,26228
@@ -64,7 +65,7 @@ angr/analyses/cfg/cfg.py,sha256=1JpPGlqXXRFwE0tk26xjabT_-dq-kqAxMv7o6-DUhp4,3146
64
65
  angr/analyses/cfg/cfg_arch_options.py,sha256=YONHg6y-h6BCsBkJK9tuxb94DDfeOoy9CUS-LVyyDyg,3112
65
66
  angr/analyses/cfg/cfg_base.py,sha256=o3mAO3ha5DPWFiE_TeUll38ldal-p0IUOyXY4lNnncc,121889
66
67
  angr/analyses/cfg/cfg_emulated.py,sha256=Fi3rDN5ByxhO-H4Y7qn-3WZgBG12JGyvxcWmrD_FnFQ,152842
67
- angr/analyses/cfg/cfg_fast.py,sha256=IwIsPNxbIAGfHOHKf0s_X-MnBZT1mbmlgFKIXHTk51A,209786
68
+ angr/analyses/cfg/cfg_fast.py,sha256=jaF4UXjld_GX9JdN87noJhaD5c0vvo8lcURv3xHa2RI,210389
68
69
  angr/analyses/cfg/cfg_fast_soot.py,sha256=eA_P-OY3gRRNj2BBgSPMsB_llGyFFCNW3VyGZ2uiMoM,26047
69
70
  angr/analyses/cfg/cfg_job_base.py,sha256=3IQE_Iy17xtGfsIkrKc2ERIakAYiNdLtRb_jwOGQtHU,5989
70
71
  angr/analyses/cfg/segment_list.py,sha256=XM-rcLHkl008U5xu9pkVCenhcHWAFBKwVdDLa-kGFgY,20467
@@ -91,10 +92,10 @@ angr/analyses/data_dep/sim_act_location.py,sha256=4f8jp-ahitxoHCCOSSFGJ1olvNWuHy
91
92
  angr/analyses/decompiler/__init__.py,sha256=RkTvvTwAGpaLdGSTgXxVrKmGEDRxqLCNSB-b8fM6fBM,540
92
93
  angr/analyses/decompiler/ail_simplifier.py,sha256=ZHXNxaR9yLRFbYaczolSbc1vQ1s__EhTi9fumkv8AcM,59030
93
94
  angr/analyses/decompiler/ailgraph_walker.py,sha256=sBz9Cn0GtdpuFt7R9y3oX6NFvETQTZRh6N80eM9ZdJQ,1595
94
- angr/analyses/decompiler/block_simplifier.py,sha256=zHHJU2ssQScZNd7_Ccxla6xe3hT_5K7iuYeA3aNyxCA,16476
95
+ angr/analyses/decompiler/block_simplifier.py,sha256=X5kO97A1bEwSUfbwgj1cSO56qkhwPQZnIFi1DKMZQoo,17199
95
96
  angr/analyses/decompiler/call_counter.py,sha256=V3TIaSvLUy9vLEWErnvlCS--_ubGWQAeU0tqq6XYeOU,1205
96
97
  angr/analyses/decompiler/callsite_maker.py,sha256=B2lajS20_cTDWvUc-Py-2rP6UybNLd-qAjkuDJMIlX8,14938
97
- angr/analyses/decompiler/clinic.py,sha256=5l8QbXdI3UPah0uhiyZrwQCR4hNraMqvXm3YPhJjJQA,72021
98
+ angr/analyses/decompiler/clinic.py,sha256=F2mcZKD0xuEFFXxQAlVQ8dnOTAP-YVCPW8pFeq8YwEo,72531
98
99
  angr/analyses/decompiler/condition_processor.py,sha256=ts7-dM1ckqDRh28Vv3YhKhNYUHdsavJah4Ta3_tb-uo,48658
99
100
  angr/analyses/decompiler/decompilation_cache.py,sha256=NveTVs6IY3TTdgsLvTb3ktftM4n0NrAJIkqjXqQ3550,1119
100
101
  angr/analyses/decompiler/decompilation_options.py,sha256=EtLBv9XG3chXmceT3irru3K7jJhguv8JilWYCHdTWyQ,7668
@@ -110,20 +111,20 @@ angr/analyses/decompiler/redundant_label_remover.py,sha256=kDGGFWWV61I5fbASiTQTH
110
111
  angr/analyses/decompiler/region_identifier.py,sha256=SQEhgXy5nHkQl6WRDTLZTtbRhxkXzT1IiBCzvP1K-p8,44389
111
112
  angr/analyses/decompiler/region_walker.py,sha256=lTfweYbY4_a2f2yGztTKG6JtU1jXf-kaz-NHbX9nkXE,717
112
113
  angr/analyses/decompiler/sequence_walker.py,sha256=mw4RG-Act5_no_RyQcsxWZwva-n7FdH2a7w_uItGUpI,8428
113
- angr/analyses/decompiler/utils.py,sha256=UH-9xmrI7MCBVmzQUm3U7qztqP-7AH8xuDZOeGF8hXI,19535
114
+ angr/analyses/decompiler/utils.py,sha256=jzODnWygARpEdPLBRfgcWzEjsYS6X5W-aa_-tSODj7k,24386
114
115
  angr/analyses/decompiler/ccall_rewriters/__init__.py,sha256=wbWqZ8xG6ZvzEApkAwMsNQFC-iwF3swG1YJsaf1cIrQ,102
115
116
  angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py,sha256=PjfduEkFVcSBKUfGouVM5dekA4kO4OBUses58ewJnCk,20488
116
117
  angr/analyses/decompiler/ccall_rewriters/rewriter_base.py,sha256=gWezEKB7A_YnlfUDs8V8D5syoYAyIXSIme1BKQRoouM,498
117
- angr/analyses/decompiler/optimization_passes/__init__.py,sha256=x2T9gR0OHaAupuAwhKIVf8zYdQxF1BOdkF2WeZx1CQY,2729
118
+ angr/analyses/decompiler/optimization_passes/__init__.py,sha256=inyWh1QXeFfA9JBnFsK6E-3PrCBTKuNJT8O_70Pz2KE,2794
118
119
  angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py,sha256=bjpEMW-Lqj5XW9NWUikGPcRn5scKNc8VvEjVMXxAuq8,5289
119
120
  angr/analyses/decompiler/optimization_passes/const_derefs.py,sha256=FEoiprXxns-3S0nFaIWm2DBW_aDMq3GZ-VOG3CIqcMw,10593
120
121
  angr/analyses/decompiler/optimization_passes/div_simplifier.py,sha256=1yTI1mmFHBMxADbrKxk9IAf3TpuNCaTLVQqWveyIx1I,17364
121
122
  angr/analyses/decompiler/optimization_passes/eager_returns.py,sha256=rSIjiTf1IzeplmACjAH99ZqebXUeJvvP_jHHmKLoMXk,11250
122
- angr/analyses/decompiler/optimization_passes/engine_base.py,sha256=Q920CTvgxX4ueuRJVNvN30SYC-oH5_TreKVgQ2yJcq4,10392
123
+ angr/analyses/decompiler/optimization_passes/engine_base.py,sha256=7nnNZkVMqvikHCy9X11M8KLWbL8lF0DoLYPemETWP4c,10388
123
124
  angr/analyses/decompiler/optimization_passes/expr_op_swapper.py,sha256=vlPhWDyvuEmbGcd1ka8rS68F72Ty6Hw3J00KM3tWCus,4701
124
125
  angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py,sha256=DjkPSAI9Z_X6YXW3Emzc1s3CzIvh45HDhBihh63UuIw,3448
125
126
  angr/analyses/decompiler/optimization_passes/ite_expr_converter.py,sha256=-6znFCAXS7Z3cn5CTqr3mg4r1G_jJgDFJHk2PzMVwtE,7756
126
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py,sha256=rZauCx835hRDr8OQBb45oSLqnikiEIcrkEA0bY4qpzE,6689
127
+ angr/analyses/decompiler/optimization_passes/ite_region_converter.py,sha256=l571GUDoCt4hZ2RHBNVUraLl-ODmP_kb11bLKwbCIB0,6762
127
128
  angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py,sha256=MQNtGU8paXdhTcfvYvBeTplX-htqs0WI6o-72me8fmg,34328
128
129
  angr/analyses/decompiler/optimization_passes/mod_simplifier.py,sha256=A9pPly7otXJlLkSbItU0wvjGGu6rUsNpcFw3bzy4DjY,3046
129
130
  angr/analyses/decompiler/optimization_passes/multi_simplifier.py,sha256=Ez7ye4j2VUfELxRPkNQQIY-gF9Q9SkTZxH5jt301Rx8,10968
@@ -132,9 +133,9 @@ angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py,sh
132
133
  angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py,sha256=_sTaGMQMFa5ATQIvNyL05UK8gCi_SaOckrZKyHZ2vfs,6470
133
134
  angr/analyses/decompiler/optimization_passes/ret_deduplicator.py,sha256=CAOGRra4PB-FCjTxQs2e-lEQ6z_CMvHsrubpbyahv0M,7797
134
135
  angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py,sha256=diqUO-k1hq9OzuC7OLMyJJODhy3i1c5Tb7d9f7lx6mU,12147
135
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py,sha256=F-X7Ww40BXDlnj7Ja2SjY6-u7hLubxMkjMOIwX45j50,8779
136
+ angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py,sha256=BRl9s9DzEMSKugR7-N5OBukyNcoN2Y_vWbziXqF4nmE,13231
136
137
  angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py,sha256=lwLc9QpOCTdSIb-0SK0hdxi2gzpABTk2kzdwBY20UOo,2980
137
- angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=0nu8k34LJeFCUeh08QiUIcey8icL_LXIwrSl-bdS1CU,2800
138
+ angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=pe_zErF540hOybDNC0ij9B3ASQOck9PYNa64hzSEp3U,3208
138
139
  angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py,sha256=Whptbt1qujPPRsNX8kJaobHTwgvym7SPu-tC2wBynBs,1727
139
140
  angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py,sha256=xuLPEVN1QdQT_5U9K4-WIdVdHTogCBOmJPWlnDW8Cz8,1365
140
141
  angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py,sha256=tEr_XcYoOXcFm5paY_CEzgSOjrksz20utMZa6smF9TU,988
@@ -142,7 +143,7 @@ angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py,sha256=ocLn_4eLty
142
143
  angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py,sha256=gvPg4KkQcammW4sviu272RLf7S0ASmcYfa5GAXGQX30,2050
143
144
  angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py,sha256=KajKgL00mHXpEZewbwKgnZKLbZTnSB00-CGbed12uNU,619
144
145
  angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py,sha256=ShdDtwrhqxUzPW2MwM98xufHo7OSL8GfNYQQCGYXrVQ,9333
145
- angr/analyses/decompiler/peephole_optimizations/base.py,sha256=lpcTqDJSHz4lWlolrATHG3PBWrWj9oy9XeneHSgc48A,2676
146
+ angr/analyses/decompiler/peephole_optimizations/base.py,sha256=os9bEPHDm2p5EA4h5eoA7Uso2nAjBYySwJ9gjp5p44Q,3538
146
147
  angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py,sha256=OzchLk1a0CV2ggHm6-TLpa6f_b7fj7K3Z3l6gFCUEJc,1056
147
148
  angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py,sha256=eiUgxcBVAL6PiI3ZuR6xZMNrWGDHKXO6SZSjUbM_BVw,1065
148
149
  angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py,sha256=oocs8xmntUNzI7UUG8UFPCDheda3xAb99REPAkD7ins,1298
@@ -150,11 +151,13 @@ angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py,sha256=QANf71
150
151
  angr/analyses/decompiler/peephole_optimizations/bswap.py,sha256=Nrdf5f47NduOc59CjmQbmsVmys1e79HxniPExdd3NRg,3663
151
152
  angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py,sha256=9ogHTcP4vhFfwDzxccnjfhkizKGvM_7tK3y6PqyG5Hg,1020
152
153
  angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py,sha256=KLdhgU_e1OglEeC7IHipql9UzYpatJc0LydXJJIakL4,3691
153
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py,sha256=JksMps_XeJGGtM2qlqIDRzUsEOOhUCn3D8aPx4bPClg,998
154
+ angr/analyses/decompiler/peephole_optimizations/constant_derefs.py,sha256=SjSE3kTrPYPjsoY_pW3nZPk9IXrJwNR4lfQ9nV-QVKg,984
154
155
  angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py,sha256=vzROAUvKUrQQmwUXJ-0WyFr1v5f8EPBgjeXIpWhtDak,2578
155
156
  angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py,sha256=0IHIk7uxIC70140k3VcXlnx4QcunAeoETXF1ZgJi2Pk,2070
156
157
  angr/analyses/decompiler/peephole_optimizations/eager_eval.py,sha256=9FXjKuBWC2oDo3tPkNOhiSOD0C_P7vA83DAp7qJfnIU,8684
157
158
  angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py,sha256=ymP9tDU4NipGOdFWsmLHrR6dKVcEFiaTgM1-L_dfmOM,2015
159
+ angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py,sha256=x8ZS-ThnUiJPBacRFpOZ3gBqixamrHSCCZSR-L5jyC8,2601
160
+ angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py,sha256=vrXAaYKT99LJK5BLKlyQ7xtzQx6hIujqTAv0-Ur1CWo,4676
158
161
  angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py,sha256=a0IDp0kKBrPwhDVejPFhcNseZdprF_5EZRZs7KTR4gA,2084
159
162
  angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py,sha256=kW8AbWfMqFzI1CVFp79TFX60IZxaQhRG8XUckuc-vGI,1136
160
163
  angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py,sha256=3a1ZoTq66HTU68y5DCC2sLvItPmqF_Kv05uvOacxsRM,591
@@ -190,7 +193,7 @@ angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py,sha256=
190
193
  angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py,sha256=HGIiC6c3C91VfcqxUHe9aTsRohwmMXOHZH_G_dbwwx4,3327
191
194
  angr/analyses/decompiler/structured_codegen/__init__.py,sha256=Glc4jBCr7lZckltN9XZdSvMrGHf0swXFyKTr_QQKdWE,290
192
195
  angr/analyses/decompiler/structured_codegen/base.py,sha256=nJPOoeJCbewchYdXjSE4S2b1-WN6pT3TxmCQMDO0azw,3845
193
- angr/analyses/decompiler/structured_codegen/c.py,sha256=q0HM-IesR-S9SJ6eAXeMzT0Kaa8ejZ7kvbjQ-cDsMLg,128216
196
+ angr/analyses/decompiler/structured_codegen/c.py,sha256=rJyXVUmXuzFA10jfiewfINB5WfisUIadhqje-kXTz40,128736
194
197
  angr/analyses/decompiler/structured_codegen/dummy.py,sha256=IVfmtcWpTgNCRVsuW3GdQgDnuPmvodX85V0bBYtF_BI,535
195
198
  angr/analyses/decompiler/structured_codegen/dwarf_import.py,sha256=TMz65TkF_ID_Ipocj0aFDb84H6slolN90wq0tzhY2Rk,6773
196
199
  angr/analyses/decompiler/structuring/__init__.py,sha256=eSiT6xUpv9K5-enK3OZj2lNzxwowS9_5OTrjHiPgfFs,371
@@ -418,9 +421,10 @@ angr/flirt/__init__.py,sha256=UTjDOlVPnvb5u1zYOvSrI_8F-RllvA_rWCEF1XGEswk,4428
418
421
  angr/flirt/build_sig.py,sha256=QnBVAjmBms6GiDK1v13dNE-YQ2i95qazDh0lYX5nKEs,10109
419
422
  angr/knowledge_base/__init__.py,sha256=G2QiJKD3Q1dgpSjaHwZi0FMDRI8aeu2x2Lyn9FSgS54,42
420
423
  angr/knowledge_base/knowledge_base.py,sha256=V_RDvf-VOizrB9a-FYrsuYd_bAfyPoEhxAKmZb1Z2Gc,4623
421
- angr/knowledge_plugins/__init__.py,sha256=4I2Xws0q8PNLPWYm5tMpg4TMbAIf4uEBEowQMApistA,655
424
+ angr/knowledge_plugins/__init__.py,sha256=UIjrxZHnr-EaYe5tSNQ1DVE6yRJtMlJzNXGLK6ARPhw,697
422
425
  angr/knowledge_plugins/callsite_prototypes.py,sha256=nEJhJxuH_xivJRcRsFbeQ0KJuncHShfwk9WhChcMScA,1614
423
426
  angr/knowledge_plugins/comments.py,sha256=Zc8_5Y7ThGsVetdfLeI7OQSrKjmu9tSkzq_qQMcDDjE,315
427
+ angr/knowledge_plugins/custom_strings.py,sha256=5uy6QZb40BNkLlttpgTflTQj_mPUt6v2iFSiHBns69c,1044
424
428
  angr/knowledge_plugins/data.py,sha256=iKviVL-_lqqdw_7YECDpoSmrtUSj6oKfbCYVu40T6kE,260
425
429
  angr/knowledge_plugins/debug_variables.py,sha256=N3vltNKykTsuQ3zVvxHz00Y_0_UvjZuIL47FhBrP0Kk,8223
426
430
  angr/knowledge_plugins/indirect_jumps.py,sha256=puJnKhp11eRDNZ-swEXKtZk04DJ48uM1F8gBiz5xbAs,971
@@ -435,7 +439,7 @@ angr/knowledge_plugins/cfg/cfg_node.py,sha256=Q_qqQ1LisCzTWROOQAfvyaBjS86zxcMw6I
435
439
  angr/knowledge_plugins/cfg/indirect_jump.py,sha256=yzPf1jjUNPgGP7D7IamqX6KF-EJX-heZjDEr4SRUWDA,2145
436
440
  angr/knowledge_plugins/cfg/memory_data.py,sha256=FzRUFltXrN0G3OeMZEbb3xc7I-W8AaomtCTSXUQlJ0g,5040
437
441
  angr/knowledge_plugins/functions/__init__.py,sha256=6IerJjMKKvM70mcJQhmXJYiipePOQ9ZSTmavTIUgg5Q,77
438
- angr/knowledge_plugins/functions/function.py,sha256=o7X2JiWUw4RmX5_3Bk8L2AxisOudC02gPMztBsJLyuI,64156
442
+ angr/knowledge_plugins/functions/function.py,sha256=NyAznn7LnJ9QIIANsEdpjJS8hwG955ve4YHtiznpK6A,65399
439
443
  angr/knowledge_plugins/functions/function_manager.py,sha256=Nbk97zc3GCW6BzpMdZha7e8zhCOH9lD3Avw1XYZV778,17558
440
444
  angr/knowledge_plugins/functions/function_parser.py,sha256=cb_AD5oFqoyXapDBawnJV1D9XVRMBGa9GwwDudNSc3M,11916
441
445
  angr/knowledge_plugins/functions/soot_function.py,sha256=2zwz_tdKbEnF8eUkOEmpNr7AUeooun2-SiIoY_xIdMw,4971
@@ -469,7 +473,7 @@ angr/knowledge_plugins/xrefs/__init__.py,sha256=-5A2h048WTRu6Et7q7bqlc-AyBXNuJ9A
469
473
  angr/knowledge_plugins/xrefs/xref.py,sha256=w4wjDFl4xtJYOtJplp9s1AIX3wI1RE71po3ufh1M4aY,4963
470
474
  angr/knowledge_plugins/xrefs/xref_manager.py,sha256=GYF9N1t4JxkDNGAwrVLo4_NF51P4gqiuQ21F0IbloF0,4026
471
475
  angr/knowledge_plugins/xrefs/xref_types.py,sha256=VR3xLQQ-gUg25oX0OL3BJHyQRlZh2A8syBac9ZMS9n4,271
472
- angr/lib/angr_native.dll,sha256=iR_xY3eXAHzI6rFPt8WI36s6YBoXrYS_IB3uGXz6sJU,19209728
476
+ angr/lib/angr_native.dll,sha256=wNtDTQv01n7sYKMAYCufrdKLyTZyoryGhAPUwdKyW8Y,19209728
473
477
  angr/misc/__init__.py,sha256=Ct-Q6-c-Frdz5Ihkqmou3j_1jyJi8WJXlQxs-gPQg0Y,237
474
478
  angr/misc/ansi.py,sha256=TKrx7d_MViChHh5RBR2VLufNrujTUioJWsZS5ugk8k4,807
475
479
  angr/misc/autoimport.py,sha256=6WT-Z6wf5NiacQhKZmR4d2bPOvNrokA7Wg0g2MUXSuw,2371
@@ -501,7 +505,7 @@ angr/procedures/definitions/gnulib.py,sha256=fH8KbaUj6bVOG_cv-JiaffWkVN-YHFbWwvR
501
505
  angr/procedures/definitions/libstdcpp.py,sha256=lhV3EGR45spEo_vNFNw2vIdPJWdByqar_sP9dFZMvKs,700
502
506
  angr/procedures/definitions/linux_kernel.py,sha256=uaTTlulqv2eeUmIkQ70-pvLT2-ay7rqMBjPazhh5RbQ,238887
503
507
  angr/procedures/definitions/linux_loader.py,sha256=sW7eQ7Dk2co_9x0ql-YsWYB8JYs0YQjGz-IM_ukp5c4,219
504
- angr/procedures/definitions/msvcr.py,sha256=NGJe7BRcj5XBLQmLGIAKSNTCfVuXPk2Nn1HxfKDCJ5U,700
508
+ angr/procedures/definitions/msvcr.py,sha256=9Wvo9U8ARM93oYmID5pBSCAr9Yg0TxjXAj7Gi_Lks2s,601
505
509
  angr/procedures/definitions/ntdll.py,sha256=2X_f1WvpBncRS6nN6PwatRKtgdn6cMYb4AnvLEhCYN0,404
506
510
  angr/procedures/definitions/parse_syscalls_from_local_system.py,sha256=9OcLLDNrNb6CifvveD_yTzfhMYEN2iK46nNNjMyz3I0,1795
507
511
  angr/procedures/definitions/parse_win32json.py,sha256=zFfq0SpBjgzIDUisbzA4zTvISGslOEPHe4V2zDbqepE,84681
@@ -1406,8 +1410,9 @@ tests/storage/test_multivalues.py,sha256=x82duiIMsU9nE-6vhm-eEsofshKfbVy5d9CNgdC
1406
1410
  tests/storage/test_permissions.py,sha256=-Gsd1CUO7xZv7NTieiuikm33xfl33MyzIkembL3CuIw,883
1407
1411
  tests/storage/test_ptmalloc.py,sha256=WwORhRoN0SYC8R9aJ_RITbVKlB6JQnLyINTWbT4PidU,10592
1408
1412
  tests/storage/test_relro_perm.py,sha256=gqNbkYfAYr0wM-oSijS3HYi0-cbtplMDCSWQqRCqEb4,1406
1409
- angr-9.2.78.dist-info/LICENSE,sha256=cgL_ho5B1NH8UxwtBuqThRWdjear8b7hktycaS1sz6g,1327
1410
- angr-9.2.78.dist-info/METADATA,sha256=Iu2vpxa2607f2PY13YsRu46ImINPEmS9i15LH9wuTBo,4856
1411
- angr-9.2.78.dist-info/WHEEL,sha256=daufdGbLJ8QgaD3d1tPsLa1xxR8oqf4qd0_Ms_reCKM,98
1412
- angr-9.2.78.dist-info/top_level.txt,sha256=EGgw8HjaUI9JWd6w70Tzkn1AcyKTMJTVJ9OpWyaOewk,11
1413
- angr-9.2.78.dist-info/RECORD,,
1413
+ angr-9.2.79.dist-info/LICENSE,sha256=cgL_ho5B1NH8UxwtBuqThRWdjear8b7hktycaS1sz6g,1327
1414
+ angr-9.2.79.dist-info/METADATA,sha256=LxvGZly4vzhzSGI_nGL-0XEZlf03uAge8ivhIgT3w4A,4856
1415
+ angr-9.2.79.dist-info/WHEEL,sha256=6iYPr8vTHsyDK75jr9X0V3I9wPSVmtwr_8fdATBciGk,98
1416
+ angr-9.2.79.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1417
+ angr-9.2.79.dist-info/top_level.txt,sha256=EGgw8HjaUI9JWd6w70Tzkn1AcyKTMJTVJ9OpWyaOewk,11
1418
+ angr-9.2.79.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.3)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-win_amd64
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ angr = angr.__main__:main
File without changes