angr 9.2.172__cp310-abi3-manylinux_2_28_x86_64.whl → 9.2.173__cp310-abi3-manylinux_2_28_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.
- angr/__init__.py +1 -1
- angr/analyses/calling_convention/fact_collector.py +6 -1
- angr/analyses/cfg/cfg_fast.py +12 -10
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +132 -9
- angr/analyses/decompiler/block_simplifier.py +23 -5
- angr/analyses/decompiler/clinic.py +2 -3
- angr/analyses/decompiler/peephole_optimizations/__init__.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +15 -5
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +162 -84
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy_consolidation.py +113 -0
- angr/analyses/decompiler/structured_codegen/c.py +57 -41
- angr/analyses/s_reaching_definitions/s_rda_view.py +3 -0
- angr/knowledge_plugins/cfg/indirect_jump.py +74 -8
- angr/rustylib.abi3.so +0 -0
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/METADATA +5 -5
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/RECORD +20 -19
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/WHEEL +0 -0
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/entry_points.txt +0 -0
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/licenses/LICENSE +0 -0
- {angr-9.2.172.dist-info → angr-9.2.173.dist-info}/top_level.txt +0 -0
angr/__init__.py
CHANGED
|
@@ -622,10 +622,15 @@ class FactCollector(Analysis):
|
|
|
622
622
|
|
|
623
623
|
stack_offset_created = set()
|
|
624
624
|
ret_addr_offset = 0 if not self.project.arch.call_pushes_ret else self.project.arch.bytes
|
|
625
|
+
# handle shadow stack args
|
|
626
|
+
cc_cls = default_cc(
|
|
627
|
+
self.project.arch.name, platform=self.project.simos.name if self.project.simos is not None else None
|
|
628
|
+
)
|
|
629
|
+
stackarg_sp_buff = cc_cls.STACKARG_SP_BUFF if cc_cls is not None else 0
|
|
625
630
|
for state in end_states:
|
|
626
631
|
for offset, size in state.stack_reads.items():
|
|
627
632
|
offset = u2s(offset, self.project.arch.bits)
|
|
628
|
-
if offset - ret_addr_offset >
|
|
633
|
+
if offset - ret_addr_offset > stackarg_sp_buff:
|
|
629
634
|
if offset in stack_offset_created or offset in callee_saved_reg_stack_offsets:
|
|
630
635
|
continue
|
|
631
636
|
stack_offset_created.add(offset)
|
angr/analyses/cfg/cfg_fast.py
CHANGED
|
@@ -3237,22 +3237,24 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
3237
3237
|
# Fill in the jump_tables dict
|
|
3238
3238
|
self.jump_tables[jump.addr] = jump
|
|
3239
3239
|
# occupy the jump table region
|
|
3240
|
-
|
|
3241
|
-
|
|
3240
|
+
for jumptable_info in jump.jumptables:
|
|
3241
|
+
if jumptable_info.addr is None:
|
|
3242
|
+
continue
|
|
3243
|
+
self._seg_list.occupy(jumptable_info.addr, jumptable_info.size, "data")
|
|
3242
3244
|
if self._collect_data_ref:
|
|
3243
|
-
if
|
|
3244
|
-
memory_data = self._memory_data[
|
|
3245
|
-
memory_data.size =
|
|
3246
|
-
memory_data.max_size =
|
|
3245
|
+
if jumptable_info.addr in self._memory_data:
|
|
3246
|
+
memory_data = self._memory_data[jumptable_info.addr]
|
|
3247
|
+
memory_data.size = jumptable_info.size
|
|
3248
|
+
memory_data.max_size = jumptable_info.size
|
|
3247
3249
|
memory_data.sort = MemoryDataSort.Unknown
|
|
3248
3250
|
else:
|
|
3249
3251
|
memory_data = MemoryData(
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
+
jumptable_info.addr,
|
|
3253
|
+
jumptable_info.size,
|
|
3252
3254
|
MemoryDataSort.Unknown,
|
|
3253
|
-
max_size=
|
|
3255
|
+
max_size=jumptable_info.size,
|
|
3254
3256
|
)
|
|
3255
|
-
self._memory_data[
|
|
3257
|
+
self._memory_data[jumptable_info.addr] = memory_data
|
|
3256
3258
|
|
|
3257
3259
|
jump.resolved_targets = targets
|
|
3258
3260
|
all_targets = set(targets)
|
|
@@ -780,7 +780,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
780
780
|
self._find_bss_region()
|
|
781
781
|
|
|
782
782
|
def filter(self, cfg, addr, func_addr, block, jumpkind):
|
|
783
|
-
if pcode is not None and isinstance(block.vex, pcode.lifter.IRSB):
|
|
783
|
+
if pcode is not None and isinstance(block.vex, pcode.lifter.IRSB): # type:ignore
|
|
784
784
|
if once("pcode__indirect_jump_resolver"):
|
|
785
785
|
l.warning("JumpTableResolver does not support P-Code IR yet; CFG may be incomplete.")
|
|
786
786
|
return False
|
|
@@ -1049,6 +1049,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1049
1049
|
|
|
1050
1050
|
# Get the jumping targets
|
|
1051
1051
|
for r in simgr.found:
|
|
1052
|
+
jt2, jt2_addr, jt2_entrysize, jt2_size = None, None, None, None
|
|
1052
1053
|
if load_stmt is not None:
|
|
1053
1054
|
ret = self._try_resolve_targets_load(
|
|
1054
1055
|
r,
|
|
@@ -1064,7 +1065,18 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1064
1065
|
if ret is None:
|
|
1065
1066
|
# Try the next state
|
|
1066
1067
|
continue
|
|
1067
|
-
|
|
1068
|
+
(
|
|
1069
|
+
jump_table,
|
|
1070
|
+
jumptable_addr,
|
|
1071
|
+
entry_size,
|
|
1072
|
+
jumptable_size,
|
|
1073
|
+
all_targets,
|
|
1074
|
+
sort,
|
|
1075
|
+
jt2,
|
|
1076
|
+
jt2_addr,
|
|
1077
|
+
jt2_entrysize,
|
|
1078
|
+
jt2_size,
|
|
1079
|
+
) = ret
|
|
1068
1080
|
if sort == "jumptable":
|
|
1069
1081
|
ij_type = IndirectJumpType.Jumptable_AddressLoadedFromMemory
|
|
1070
1082
|
elif sort == "vtable":
|
|
@@ -1116,15 +1128,14 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1116
1128
|
ij.jumptable = True
|
|
1117
1129
|
else:
|
|
1118
1130
|
ij.jumptable = False
|
|
1119
|
-
ij.jumptable_addr =
|
|
1120
|
-
ij.jumptable_size = jumptable_size
|
|
1121
|
-
ij.jumptable_entry_size = entry_size
|
|
1131
|
+
ij.add_jumptable(jumptable_addr, jumptable_size, entry_size, jump_table, is_primary=True)
|
|
1122
1132
|
ij.resolved_targets = set(jump_table)
|
|
1123
|
-
ij.jumptable_entries = jump_table
|
|
1124
1133
|
ij.type = ij_type
|
|
1125
1134
|
else:
|
|
1126
1135
|
ij.jumptable = False
|
|
1127
1136
|
ij.resolved_targets = set(jump_table)
|
|
1137
|
+
if jt2 is not None and jt2_addr is not None and jt2_size is not None and jt2_entrysize is not None:
|
|
1138
|
+
ij.add_jumptable(jt2_addr, jt2_size, jt2_entrysize, jt2, is_primary=False)
|
|
1128
1139
|
|
|
1129
1140
|
return True, all_targets
|
|
1130
1141
|
|
|
@@ -1560,7 +1571,9 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1560
1571
|
stmt_whitelist = annotatedcfg.get_whitelisted_statements(block_addr)
|
|
1561
1572
|
assert isinstance(stmt_whitelist, list)
|
|
1562
1573
|
try:
|
|
1563
|
-
engine.process(
|
|
1574
|
+
engine.process(
|
|
1575
|
+
state, block=block, whitelist=set(stmt_whitelist) if stmt_whitelist is not None else None
|
|
1576
|
+
)
|
|
1564
1577
|
except (claripy.ClaripyError, SimError, AngrError):
|
|
1565
1578
|
# anything can happen
|
|
1566
1579
|
break
|
|
@@ -1789,7 +1802,18 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1789
1802
|
)
|
|
1790
1803
|
else:
|
|
1791
1804
|
l.debug("Table at %#x has %d plausible targets", table_base_addr, num_targets)
|
|
1792
|
-
return
|
|
1805
|
+
return (
|
|
1806
|
+
jump_table,
|
|
1807
|
+
table_base_addr,
|
|
1808
|
+
load_size,
|
|
1809
|
+
num_targets * load_size,
|
|
1810
|
+
jump_table,
|
|
1811
|
+
sort,
|
|
1812
|
+
None,
|
|
1813
|
+
None,
|
|
1814
|
+
None,
|
|
1815
|
+
None,
|
|
1816
|
+
)
|
|
1793
1817
|
|
|
1794
1818
|
# We resolved too many targets for this indirect jump. Something might have gone wrong.
|
|
1795
1819
|
l.debug(
|
|
@@ -1848,6 +1872,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1848
1872
|
# Adjust entries inside the jump table
|
|
1849
1873
|
mask = (2**self.project.arch.bits) - 1
|
|
1850
1874
|
transformation_list = list(reversed([v for v in transformations.values() if not v.first_load]))
|
|
1875
|
+
jt_2nd_memloads: dict[int, int] = {}
|
|
1851
1876
|
if transformation_list:
|
|
1852
1877
|
|
|
1853
1878
|
def handle_signed_ext(a):
|
|
@@ -1872,6 +1897,10 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1872
1897
|
return (a + con) & mask
|
|
1873
1898
|
|
|
1874
1899
|
def handle_load(size, a):
|
|
1900
|
+
if a not in jt_2nd_memloads:
|
|
1901
|
+
jt_2nd_memloads[a] = size
|
|
1902
|
+
else:
|
|
1903
|
+
jt_2nd_memloads[a] = max(jt_2nd_memloads[a], size)
|
|
1875
1904
|
return cfg._fast_memory_load_pointer(a, size=size)
|
|
1876
1905
|
|
|
1877
1906
|
invert_conversion_ops = []
|
|
@@ -1936,6 +1965,31 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1936
1965
|
l.debug("Could not recover jump table")
|
|
1937
1966
|
return None
|
|
1938
1967
|
|
|
1968
|
+
# there might be a secondary jumptable
|
|
1969
|
+
jt_2nd = self._get_secondary_jumptable_from_transformations(transformation_list)
|
|
1970
|
+
jt_2nd_entries: list[int] | None = None
|
|
1971
|
+
jt_2nd_baseaddr: int | None = None
|
|
1972
|
+
jt_2nd_entrysize: int | None = None
|
|
1973
|
+
jt_2nd_size: int | None = None
|
|
1974
|
+
if jt_2nd is not None and jt_2nd_memloads:
|
|
1975
|
+
# determine the size of the secondary jump table
|
|
1976
|
+
jt_2nd_baseaddr, jt_2nd_entrysize = jt_2nd
|
|
1977
|
+
if jt_2nd_baseaddr in jt_2nd_memloads:
|
|
1978
|
+
jt_2nd_size = max(jt_2nd_memloads) - jt_2nd_baseaddr + jt_2nd_entrysize
|
|
1979
|
+
if jt_2nd_size % jt_2nd_entrysize == 0:
|
|
1980
|
+
jt_2nd_entrycount = jt_2nd_size // jt_2nd_entrysize
|
|
1981
|
+
if jt_2nd_entrycount <= len(all_targets):
|
|
1982
|
+
# we found it!
|
|
1983
|
+
jt_2nd_entries = []
|
|
1984
|
+
for i in range(jt_2nd_entrycount):
|
|
1985
|
+
target = cfg._fast_memory_load_pointer(
|
|
1986
|
+
jt_2nd_baseaddr + i * jt_2nd_entrysize,
|
|
1987
|
+
size=jt_2nd_entrysize,
|
|
1988
|
+
)
|
|
1989
|
+
if target is None:
|
|
1990
|
+
break
|
|
1991
|
+
jt_2nd_entries.append(target)
|
|
1992
|
+
|
|
1939
1993
|
# Finally... all targets are ready
|
|
1940
1994
|
illegal_target_found = False
|
|
1941
1995
|
for target in all_targets:
|
|
@@ -1953,7 +2007,18 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1953
2007
|
if illegal_target_found:
|
|
1954
2008
|
return None
|
|
1955
2009
|
|
|
1956
|
-
return
|
|
2010
|
+
return (
|
|
2011
|
+
jump_table,
|
|
2012
|
+
min_jumptable_addr,
|
|
2013
|
+
load_size,
|
|
2014
|
+
total_cases * load_size,
|
|
2015
|
+
all_targets,
|
|
2016
|
+
sort,
|
|
2017
|
+
jt_2nd_entries,
|
|
2018
|
+
jt_2nd_baseaddr,
|
|
2019
|
+
jt_2nd_entrysize,
|
|
2020
|
+
jt_2nd_size,
|
|
2021
|
+
)
|
|
1957
2022
|
|
|
1958
2023
|
def _try_resolve_targets_ite(
|
|
1959
2024
|
self, r, addr, cfg, annotatedcfg, ite_stmt: pyvex.IRStmt.WrTmp
|
|
@@ -2279,6 +2344,64 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
2279
2344
|
return None
|
|
2280
2345
|
return jump_addr
|
|
2281
2346
|
|
|
2347
|
+
def _get_secondary_jumptable_from_transformations(
|
|
2348
|
+
self, transformations: list[AddressTransformation]
|
|
2349
|
+
) -> tuple[int, int] | None:
|
|
2350
|
+
"""
|
|
2351
|
+
Find the potential secondary "jump table" from a list of transformations.
|
|
2352
|
+
|
|
2353
|
+
:param transformations: A list of address transformations.
|
|
2354
|
+
:return: A tuple of [jump_table_addr, entry_size] if a secondary jump table is found. None otherwise.
|
|
2355
|
+
"""
|
|
2356
|
+
|
|
2357
|
+
# find all add-(add-)load sequence
|
|
2358
|
+
|
|
2359
|
+
for i in range(len(transformations) - 1):
|
|
2360
|
+
prev_tran = transformations[i - 1] if i - 1 >= 0 else None
|
|
2361
|
+
tran = transformations[i]
|
|
2362
|
+
if not (
|
|
2363
|
+
tran.op == AddressTransformationTypes.Add
|
|
2364
|
+
and (prev_tran is None or prev_tran.op != AddressTransformationTypes.Add)
|
|
2365
|
+
):
|
|
2366
|
+
continue
|
|
2367
|
+
next_tran = transformations[i + 1]
|
|
2368
|
+
add_tran, load_tran = None, None
|
|
2369
|
+
if next_tran.op == AddressTransformationTypes.Load:
|
|
2370
|
+
add_tran = None
|
|
2371
|
+
load_tran = next_tran
|
|
2372
|
+
elif next_tran.op == AddressTransformationTypes.Add:
|
|
2373
|
+
next2_tran = transformations[i + 2] if i + 2 < len(transformations) else None
|
|
2374
|
+
if next2_tran is not None and next2_tran.op == AddressTransformationTypes.Load:
|
|
2375
|
+
add_tran = next_tran
|
|
2376
|
+
load_tran = next2_tran
|
|
2377
|
+
|
|
2378
|
+
if load_tran is None:
|
|
2379
|
+
continue
|
|
2380
|
+
# we have found an add-(add-)load sequence
|
|
2381
|
+
jumptable_base_addr = None
|
|
2382
|
+
if isinstance(tran.operands[0], AddressOperand) and isinstance(tran.operands[1], int):
|
|
2383
|
+
jumptable_base_addr = tran.operands[1]
|
|
2384
|
+
elif isinstance(tran.operands[1], AddressOperand) and isinstance(tran.operands[0], int):
|
|
2385
|
+
jumptable_base_addr = tran.operands[0]
|
|
2386
|
+
else:
|
|
2387
|
+
# unsupported first add
|
|
2388
|
+
continue
|
|
2389
|
+
|
|
2390
|
+
if add_tran is not None:
|
|
2391
|
+
mask = (1 << self.project.arch.bits) - 1
|
|
2392
|
+
if isinstance(add_tran.operands[0], AddressOperand) and isinstance(add_tran.operands[1], int):
|
|
2393
|
+
jumptable_base_addr = (jumptable_base_addr + add_tran.operands[1]) & mask
|
|
2394
|
+
elif isinstance(add_tran.operands[1], AddressOperand) and isinstance(add_tran.operands[0], int):
|
|
2395
|
+
jumptable_base_addr = (jumptable_base_addr + add_tran.operands[0]) & mask
|
|
2396
|
+
else:
|
|
2397
|
+
# unsupported second add
|
|
2398
|
+
continue
|
|
2399
|
+
|
|
2400
|
+
load_size = load_tran.operands[1]
|
|
2401
|
+
# we have a potential secondary jump table!
|
|
2402
|
+
return jumptable_base_addr, load_size
|
|
2403
|
+
return None
|
|
2404
|
+
|
|
2282
2405
|
def _sp_moved_up(self, block) -> bool:
|
|
2283
2406
|
"""
|
|
2284
2407
|
Examine if the stack pointer moves up (if any values are popped out of the stack) within a single block.
|
|
@@ -303,6 +303,23 @@ class BlockSimplifier(Analysis):
|
|
|
303
303
|
return block.copy(statements=new_statements)
|
|
304
304
|
|
|
305
305
|
def _eliminate_dead_assignments(self, block):
|
|
306
|
+
|
|
307
|
+
def _statement_has_calls(stmt: Statement) -> bool:
|
|
308
|
+
"""
|
|
309
|
+
Check if a statement has any Call expressions.
|
|
310
|
+
"""
|
|
311
|
+
walker = HasCallExprWalker()
|
|
312
|
+
walker.walk_statement(stmt)
|
|
313
|
+
return walker.has_call_expr
|
|
314
|
+
|
|
315
|
+
def _expression_has_calls(expr: Expression) -> bool:
|
|
316
|
+
"""
|
|
317
|
+
Check if an expression has any Call expressions.
|
|
318
|
+
"""
|
|
319
|
+
walker = HasCallExprWalker()
|
|
320
|
+
walker.walk_expression(expr)
|
|
321
|
+
return walker.has_call_expr
|
|
322
|
+
|
|
306
323
|
new_statements = []
|
|
307
324
|
if not block.statements:
|
|
308
325
|
return block
|
|
@@ -325,8 +342,11 @@ class BlockSimplifier(Analysis):
|
|
|
325
342
|
# micro optimization: if all statements that use a tmp are going to be removed, we remove this tmp as well
|
|
326
343
|
for tmp, used_locs in rd.all_tmp_uses[block_loc].items():
|
|
327
344
|
used_at = {stmt_idx for _, stmt_idx in used_locs}
|
|
328
|
-
if used_at.issubset(dead_defs_stmt_idx):
|
|
329
|
-
|
|
345
|
+
if used_at.issubset(dead_defs_stmt_idx): # noqa:SIM102
|
|
346
|
+
# cannot remove this tmp if any use sites involve call expressions; this is basically a duplicate of
|
|
347
|
+
# the logic in the larger loop below
|
|
348
|
+
if all(not _statement_has_calls(block.statements[i]) for i in used_at):
|
|
349
|
+
continue
|
|
330
350
|
used_tmps.add(tmp.tmp_idx)
|
|
331
351
|
|
|
332
352
|
# Remove dead assignments
|
|
@@ -337,9 +357,7 @@ class BlockSimplifier(Analysis):
|
|
|
337
357
|
# is it assigning to an unused tmp or a dead virgin?
|
|
338
358
|
|
|
339
359
|
# does .src involve any Call expressions? if so, we cannot remove it
|
|
340
|
-
|
|
341
|
-
walker.walk_expression(stmt.src)
|
|
342
|
-
if not walker.has_call_expr:
|
|
360
|
+
if not _expression_has_calls(stmt.src):
|
|
343
361
|
continue
|
|
344
362
|
|
|
345
363
|
if type(stmt.dst) is Tmp and isinstance(stmt.src, Call):
|
|
@@ -2158,10 +2158,9 @@ class Clinic(Analysis):
|
|
|
2158
2158
|
# custom string?
|
|
2159
2159
|
if hasattr(expr, "custom_string") and expr.custom_string is True:
|
|
2160
2160
|
s = self.kb.custom_strings[expr.value]
|
|
2161
|
+
ty = expr.type if hasattr(expr, "type") else SimTypePointer(SimTypeChar()).with_arch(self.project.arch)
|
|
2161
2162
|
expr.tags["reference_values"] = {
|
|
2162
|
-
|
|
2163
|
-
"latin-1"
|
|
2164
|
-
),
|
|
2163
|
+
ty: s,
|
|
2165
2164
|
}
|
|
2166
2165
|
else:
|
|
2167
2166
|
# global variable?
|
|
@@ -47,6 +47,7 @@ from .inlined_memcpy import InlinedMemcpy
|
|
|
47
47
|
from .inlined_strcpy import InlinedStrcpy
|
|
48
48
|
from .inlined_strcpy_consolidation import InlinedStrcpyConsolidation
|
|
49
49
|
from .inlined_wstrcpy import InlinedWstrcpy
|
|
50
|
+
from .inlined_wstrcpy_consolidation import InlinedWstrcpyConsolidation
|
|
50
51
|
from .cmpord_rewriter import CmpORDRewriter
|
|
51
52
|
from .coalesce_adjacent_shrs import CoalesceAdjacentShiftRights
|
|
52
53
|
from .a_mul_const_sub_a import AMulConstSubA
|
|
@@ -104,6 +105,7 @@ ALL_PEEPHOLE_OPTS: list[type[PeepholeOptimizationExprBase]] = [
|
|
|
104
105
|
InlinedStrcpy,
|
|
105
106
|
InlinedStrcpyConsolidation,
|
|
106
107
|
InlinedWstrcpy,
|
|
108
|
+
InlinedWstrcpyConsolidation,
|
|
107
109
|
CmpORDRewriter,
|
|
108
110
|
CoalesceAdjacentShiftRights,
|
|
109
111
|
ShlToMul,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# pylint:disable=arguments-differ,too-many-boolean-expressions
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
from angr.ailment.expression import BinaryOp, Load
|
|
4
|
+
from angr.ailment.expression import BinaryOp, Load, Expression, Tmp
|
|
5
5
|
from angr.ailment.statement import CAS, ConditionalJump, Statement, Assignment, Call
|
|
6
6
|
|
|
7
7
|
from .base import PeepholeOptimizationMultiStmtBase
|
|
@@ -60,11 +60,13 @@ class CASIntrinsics(PeepholeOptimizationMultiStmtBase):
|
|
|
60
60
|
and next_stmt.ins_addr == cas_stmt.ins_addr
|
|
61
61
|
):
|
|
62
62
|
addr = cas_stmt.addr
|
|
63
|
+
expd_lo = self._resolve_tmp_expr(cas_stmt.expd_lo, block)
|
|
64
|
+
next_stmt_cond_op1 = self._resolve_tmp_expr(next_stmt.condition.operands[1], block)
|
|
63
65
|
if (
|
|
64
|
-
isinstance(
|
|
65
|
-
and
|
|
66
|
-
and isinstance(
|
|
67
|
-
and
|
|
66
|
+
isinstance(expd_lo, Load)
|
|
67
|
+
and expd_lo.addr.likes(addr)
|
|
68
|
+
and isinstance(next_stmt_cond_op1, Load)
|
|
69
|
+
and next_stmt_cond_op1.addr.likes(addr)
|
|
68
70
|
and cas_stmt.old_lo.likes(next_stmt.condition.operands[0])
|
|
69
71
|
and cas_stmt.old_hi is None
|
|
70
72
|
):
|
|
@@ -113,3 +115,11 @@ class CASIntrinsics(PeepholeOptimizationMultiStmtBase):
|
|
|
113
115
|
os = "Linux"
|
|
114
116
|
return _INTRINSICS_NAMES[mnemonic][os]
|
|
115
117
|
return mnemonic
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def _resolve_tmp_expr(expr: Expression, block) -> Expression:
|
|
121
|
+
if isinstance(expr, Tmp):
|
|
122
|
+
for stmt in block.statements:
|
|
123
|
+
if isinstance(stmt, Assignment) and stmt.dst.likes(expr):
|
|
124
|
+
return stmt.src
|
|
125
|
+
return expr
|
|
@@ -4,15 +4,17 @@ import string
|
|
|
4
4
|
|
|
5
5
|
from archinfo import Endness
|
|
6
6
|
|
|
7
|
+
from angr.ailment import BinaryOp
|
|
7
8
|
from angr.ailment.expression import Const, StackBaseOffset, VirtualVariable
|
|
8
|
-
from angr.ailment.statement import Call, Assignment
|
|
9
|
+
from angr.ailment.statement import Call, Assignment, Statement, Store
|
|
9
10
|
|
|
11
|
+
from angr.sim_type import SimTypePointer, SimTypeWideChar
|
|
10
12
|
from angr.utils.endness import ail_const_to_be
|
|
11
13
|
from .base import PeepholeOptimizationStmtBase
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
ASCII_PRINTABLES =
|
|
15
|
-
ASCII_DIGITS =
|
|
16
|
+
ASCII_PRINTABLES = {ord(x) for x in string.printable}
|
|
17
|
+
ASCII_DIGITS = {ord(x) for x in string.digits}
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class InlinedWstrcpy(PeepholeOptimizationStmtBase):
|
|
@@ -23,70 +25,83 @@ class InlinedWstrcpy(PeepholeOptimizationStmtBase):
|
|
|
23
25
|
__slots__ = ()
|
|
24
26
|
|
|
25
27
|
NAME = "Simplifying inlined wstrcpy"
|
|
26
|
-
stmt_classes = (Assignment,)
|
|
28
|
+
stmt_classes = (Assignment, Store)
|
|
27
29
|
|
|
28
|
-
def optimize(self, stmt: Assignment, stmt_idx: int | None = None, block=None, **kwargs):
|
|
30
|
+
def optimize(self, stmt: Assignment | Store, stmt_idx: int | None = None, block=None, **kwargs):
|
|
29
31
|
if (
|
|
30
|
-
isinstance(stmt
|
|
32
|
+
isinstance(stmt, Assignment)
|
|
33
|
+
and isinstance(stmt.dst, VirtualVariable)
|
|
31
34
|
and stmt.dst.was_stack
|
|
32
35
|
and isinstance(stmt.src, Const)
|
|
33
36
|
and isinstance(stmt.src.value, int)
|
|
34
37
|
):
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
38
|
+
dst = StackBaseOffset(None, self.project.arch.bits, stmt.dst.stack_offset)
|
|
39
|
+
value_size = stmt.src.size
|
|
40
|
+
value = stmt.src.value
|
|
41
|
+
elif isinstance(stmt, Store) and isinstance(stmt.data, Const) and isinstance(stmt.data.value, int):
|
|
42
|
+
dst = stmt.addr
|
|
43
|
+
value_size = stmt.data.size
|
|
44
|
+
value = stmt.data.value
|
|
45
|
+
else:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
r, s = self.is_integer_likely_a_wide_string(value, value_size, self.project.arch.memory_endness)
|
|
49
|
+
if r:
|
|
50
|
+
# replace it with a call to strncpy
|
|
51
|
+
str_id = self.kb.custom_strings.allocate(s)
|
|
52
|
+
wstr_type = SimTypePointer(SimTypeWideChar()).with_arch(self.project.arch)
|
|
53
|
+
return Call(
|
|
54
|
+
stmt.idx,
|
|
55
|
+
"wstrncpy",
|
|
56
|
+
args=[
|
|
57
|
+
dst,
|
|
58
|
+
Const(None, None, str_id, self.project.arch.bits, custom_string=True, type=wstr_type),
|
|
59
|
+
Const(None, None, len(s) // 2, self.project.arch.bits),
|
|
60
|
+
],
|
|
61
|
+
**stmt.tags,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# scan forward in the current block to find all consecutive constant stores
|
|
65
|
+
if block is not None and stmt_idx is not None:
|
|
66
|
+
all_constant_stores: dict[int, tuple[int, Const | None]] = self.collect_constant_stores(block, stmt_idx)
|
|
67
|
+
if all_constant_stores:
|
|
68
|
+
offsets = sorted(all_constant_stores.keys())
|
|
69
|
+
next_offset = min(offsets)
|
|
70
|
+
stride = []
|
|
71
|
+
for offset in offsets:
|
|
72
|
+
if next_offset is not None and offset != next_offset:
|
|
73
|
+
next_offset = None
|
|
74
|
+
stride = []
|
|
75
|
+
stmt_idx_, v = all_constant_stores[offset]
|
|
76
|
+
if v is not None:
|
|
77
|
+
stride.append((offset, stmt_idx_, v))
|
|
78
|
+
next_offset = offset + v.size
|
|
79
|
+
else:
|
|
80
|
+
next_offset = None
|
|
81
|
+
stride = []
|
|
82
|
+
|
|
83
|
+
integer, size = self.stride_to_int(stride)
|
|
84
|
+
r, s = self.is_integer_likely_a_wide_string(integer, size, Endness.BE, min_length=3)
|
|
85
|
+
if r:
|
|
86
|
+
# we remove all involved statements whose statement IDs are greater than the current one
|
|
87
|
+
for _, stmt_idx_, _ in reversed(stride):
|
|
88
|
+
if stmt_idx_ <= stmt_idx:
|
|
89
|
+
continue
|
|
90
|
+
block.statements[stmt_idx_] = None
|
|
91
|
+
block.statements = [ss for ss in block.statements if ss is not None]
|
|
92
|
+
|
|
93
|
+
str_id = self.kb.custom_strings.allocate(s)
|
|
94
|
+
wstr_type = SimTypePointer(SimTypeWideChar()).with_arch(self.project.arch)
|
|
95
|
+
return Call(
|
|
96
|
+
stmt.idx,
|
|
97
|
+
"wstrncpy",
|
|
98
|
+
args=[
|
|
99
|
+
dst,
|
|
100
|
+
Const(None, None, str_id, self.project.arch.bits, custom_string=True, type=wstr_type),
|
|
101
|
+
Const(None, None, len(s) // 2, self.project.arch.bits),
|
|
102
|
+
],
|
|
103
|
+
**stmt.tags,
|
|
104
|
+
)
|
|
90
105
|
|
|
91
106
|
return None
|
|
92
107
|
|
|
@@ -103,68 +118,131 @@ class InlinedWstrcpy(PeepholeOptimizationStmtBase):
|
|
|
103
118
|
|
|
104
119
|
def collect_constant_stores(self, block, starting_stmt_idx: int) -> dict[int, tuple[int, Const | None]]:
|
|
105
120
|
r = {}
|
|
121
|
+
expected_store_varid: int | None = None
|
|
122
|
+
starting_stmt = block.statements[starting_stmt_idx]
|
|
123
|
+
if (
|
|
124
|
+
isinstance(starting_stmt, Assignment)
|
|
125
|
+
and isinstance(starting_stmt.dst, VirtualVariable)
|
|
126
|
+
and starting_stmt.dst.was_stack
|
|
127
|
+
and isinstance(starting_stmt.dst.stack_offset, int)
|
|
128
|
+
):
|
|
129
|
+
expected_type = "stack"
|
|
130
|
+
elif isinstance(starting_stmt, Store):
|
|
131
|
+
if isinstance(starting_stmt.addr, VirtualVariable):
|
|
132
|
+
expected_store_varid = starting_stmt.addr.varid
|
|
133
|
+
elif (
|
|
134
|
+
isinstance(starting_stmt.addr, BinaryOp)
|
|
135
|
+
and starting_stmt.addr.op == "Add"
|
|
136
|
+
and isinstance(starting_stmt.addr.operands[0], VirtualVariable)
|
|
137
|
+
and isinstance(starting_stmt.addr.operands[1], Const)
|
|
138
|
+
):
|
|
139
|
+
expected_store_varid = starting_stmt.addr.operands[0].varid
|
|
140
|
+
else:
|
|
141
|
+
expected_store_varid = None
|
|
142
|
+
expected_type = "store"
|
|
143
|
+
else:
|
|
144
|
+
return r
|
|
145
|
+
|
|
106
146
|
for idx, stmt in enumerate(block.statements):
|
|
107
147
|
if idx < starting_stmt_idx:
|
|
108
148
|
continue
|
|
109
149
|
if (
|
|
110
|
-
|
|
150
|
+
expected_type == "stack"
|
|
151
|
+
and isinstance(stmt, Assignment)
|
|
111
152
|
and isinstance(stmt.dst, VirtualVariable)
|
|
112
153
|
and stmt.dst.was_stack
|
|
113
154
|
and isinstance(stmt.dst.stack_offset, int)
|
|
114
155
|
):
|
|
115
|
-
|
|
116
|
-
|
|
156
|
+
offset = stmt.dst.stack_offset
|
|
157
|
+
value = (
|
|
158
|
+
ail_const_to_be(stmt.src, self.project.arch.memory_endness) if isinstance(stmt.src, Const) else None
|
|
159
|
+
)
|
|
160
|
+
elif expected_type == "store" and isinstance(stmt, Store):
|
|
161
|
+
if isinstance(stmt.addr, VirtualVariable) and stmt.addr.varid == expected_store_varid:
|
|
162
|
+
offset = 0
|
|
163
|
+
elif (
|
|
164
|
+
isinstance(stmt.addr, BinaryOp)
|
|
165
|
+
and stmt.addr.op == "Add"
|
|
166
|
+
and isinstance(stmt.addr.operands[0], VirtualVariable)
|
|
167
|
+
and isinstance(stmt.addr.operands[1], Const)
|
|
168
|
+
and stmt.addr.operands[0].varid == expected_store_varid
|
|
169
|
+
):
|
|
170
|
+
offset = stmt.addr.operands[1].value
|
|
117
171
|
else:
|
|
118
|
-
|
|
172
|
+
offset = None
|
|
173
|
+
value = (
|
|
174
|
+
ail_const_to_be(stmt.data, self.project.arch.memory_endness)
|
|
175
|
+
if isinstance(stmt.data, Const)
|
|
176
|
+
else None
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
if offset is not None:
|
|
182
|
+
r[offset] = idx, value
|
|
119
183
|
|
|
120
184
|
return r
|
|
121
185
|
|
|
122
186
|
@staticmethod
|
|
123
|
-
def even_offsets_are_zero(lst: list[
|
|
124
|
-
|
|
187
|
+
def even_offsets_are_zero(lst: list[int]) -> bool:
|
|
188
|
+
if len(lst) >= 2 and lst[-1] == 0 and lst[-2] == 0:
|
|
189
|
+
lst = lst[:-2]
|
|
190
|
+
return all((ch == 0 if i % 2 == 0 else ch != 0) for i, ch in enumerate(lst))
|
|
125
191
|
|
|
126
192
|
@staticmethod
|
|
127
|
-
def odd_offsets_are_zero(lst: list[
|
|
128
|
-
|
|
193
|
+
def odd_offsets_are_zero(lst: list[int]) -> bool:
|
|
194
|
+
if len(lst) >= 2 and lst[-1] == 0 and lst[-2] == 0:
|
|
195
|
+
lst = lst[:-2]
|
|
196
|
+
return all((ch == 0 if i % 2 == 1 else ch != 0) for i, ch in enumerate(lst))
|
|
129
197
|
|
|
130
198
|
@staticmethod
|
|
131
199
|
def is_integer_likely_a_wide_string(
|
|
132
200
|
v: int, size: int, endness: Endness, min_length: int = 4
|
|
133
|
-
) -> tuple[bool,
|
|
201
|
+
) -> tuple[bool, bytes | None]:
|
|
134
202
|
# we need at least four bytes of printable characters
|
|
135
203
|
|
|
136
|
-
chars = []
|
|
204
|
+
chars: list[int] = []
|
|
137
205
|
if endness == Endness.LE:
|
|
138
206
|
while v != 0:
|
|
139
207
|
byt = v & 0xFF
|
|
140
|
-
if byt != 0 and
|
|
208
|
+
if byt != 0 and byt not in ASCII_PRINTABLES:
|
|
141
209
|
return False, None
|
|
142
|
-
chars.append(
|
|
210
|
+
chars.append(byt)
|
|
143
211
|
v >>= 8
|
|
212
|
+
if len(chars) % 2 == 1:
|
|
213
|
+
chars.append(0)
|
|
144
214
|
|
|
145
215
|
elif endness == Endness.BE:
|
|
146
216
|
for _ in range(size):
|
|
147
217
|
byt = v & 0xFF
|
|
148
218
|
v >>= 8
|
|
149
|
-
if byt != 0 and
|
|
219
|
+
if byt != 0 and byt not in ASCII_PRINTABLES:
|
|
150
220
|
return False, None
|
|
151
|
-
chars.append(
|
|
221
|
+
chars.append(byt)
|
|
152
222
|
chars.reverse()
|
|
153
223
|
else:
|
|
154
224
|
# unsupported endness
|
|
155
225
|
return False, None
|
|
156
226
|
|
|
157
|
-
if InlinedWstrcpy.even_offsets_are_zero(chars):
|
|
158
|
-
chars = [ch for i, ch in enumerate(chars) if i % 2 == 1]
|
|
159
|
-
elif InlinedWstrcpy.odd_offsets_are_zero(chars):
|
|
160
|
-
chars = [ch for i, ch in enumerate(chars) if i % 2 == 0]
|
|
161
|
-
else:
|
|
227
|
+
if not (InlinedWstrcpy.even_offsets_are_zero(chars) or InlinedWstrcpy.odd_offsets_are_zero(chars)):
|
|
162
228
|
return False, None
|
|
163
229
|
|
|
164
|
-
if chars and chars[-1] ==
|
|
230
|
+
if chars and len(chars) >= 2 and chars[-1] == 0 and chars[-2] == 0:
|
|
165
231
|
chars = chars[:-1]
|
|
166
|
-
if len(chars) >= min_length and all(ch in ASCII_PRINTABLES for ch in chars):
|
|
167
|
-
if len(chars) <= 4 and all(ch in ASCII_DIGITS for ch in chars):
|
|
232
|
+
if len(chars) >= min_length * 2 and all((ch == 0 or ch in ASCII_PRINTABLES) for ch in chars):
|
|
233
|
+
if len(chars) <= 4 * 2 and all((ch == 0 or ch in ASCII_DIGITS) for ch in chars):
|
|
168
234
|
return False, None
|
|
169
|
-
return True,
|
|
235
|
+
return True, bytes(chars)
|
|
170
236
|
return False, None
|
|
237
|
+
|
|
238
|
+
@staticmethod
|
|
239
|
+
def is_inlined_wstrncpy(stmt: Statement) -> bool:
|
|
240
|
+
return (
|
|
241
|
+
isinstance(stmt, Call)
|
|
242
|
+
and isinstance(stmt.target, str)
|
|
243
|
+
and stmt.target == "wstrncpy"
|
|
244
|
+
and stmt.args is not None
|
|
245
|
+
and len(stmt.args) == 3
|
|
246
|
+
and isinstance(stmt.args[1], Const)
|
|
247
|
+
and hasattr(stmt.args[1], "custom_string")
|
|
248
|
+
)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# pylint:disable=arguments-differ
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from angr.ailment.expression import Expression, BinaryOp, Const, Register, StackBaseOffset, UnaryOp, VirtualVariable
|
|
5
|
+
from angr.ailment.statement import Call, Store
|
|
6
|
+
|
|
7
|
+
from angr.sim_type import SimTypePointer, SimTypeWideChar
|
|
8
|
+
from .base import PeepholeOptimizationMultiStmtBase
|
|
9
|
+
from .inlined_wstrcpy import InlinedWstrcpy
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class InlinedWstrcpyConsolidation(PeepholeOptimizationMultiStmtBase):
|
|
13
|
+
"""
|
|
14
|
+
Consolidate multiple inlined wstrcpy/wstrncpy calls.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__slots__ = ()
|
|
18
|
+
|
|
19
|
+
NAME = "Consolidate multiple inlined wstrncpy calls"
|
|
20
|
+
stmt_classes = ((Call, Call), (Call, Store))
|
|
21
|
+
|
|
22
|
+
def optimize( # type:ignore
|
|
23
|
+
self, stmts: list[Call], stmt_idx: int | None = None, block=None, **kwargs
|
|
24
|
+
): # pylint:disable=unused-argument
|
|
25
|
+
last_stmt, stmt = stmts
|
|
26
|
+
if InlinedWstrcpy.is_inlined_wstrncpy(last_stmt):
|
|
27
|
+
assert last_stmt.args is not None
|
|
28
|
+
assert self.kb is not None
|
|
29
|
+
s_last: bytes = self.kb.custom_strings[last_stmt.args[1].value]
|
|
30
|
+
addr_last = last_stmt.args[0]
|
|
31
|
+
new_str = None # will be set if consolidation should happen
|
|
32
|
+
|
|
33
|
+
if isinstance(stmt, Call) and InlinedWstrcpy.is_inlined_wstrncpy(stmt):
|
|
34
|
+
assert stmt.args is not None
|
|
35
|
+
# consolidating two calls
|
|
36
|
+
s_curr: bytes = self.kb.custom_strings[stmt.args[1].value]
|
|
37
|
+
addr_curr = stmt.args[0]
|
|
38
|
+
# determine if the two addresses are consecutive
|
|
39
|
+
delta = self._get_delta(addr_last, addr_curr)
|
|
40
|
+
if delta is not None and delta == len(s_last):
|
|
41
|
+
# consolidate both calls!
|
|
42
|
+
new_str = s_last + s_curr
|
|
43
|
+
elif isinstance(stmt, Store) and isinstance(stmt.data, Const) and isinstance(stmt.data.value, int):
|
|
44
|
+
# consolidating a call and a store, in case the store statement is storing the suffix of a string (but
|
|
45
|
+
# the suffix is too short to qualify an inlined strcpy optimization)
|
|
46
|
+
addr_curr = stmt.addr
|
|
47
|
+
delta = self._get_delta(addr_last, addr_curr)
|
|
48
|
+
if delta is not None and delta == len(s_last):
|
|
49
|
+
if stmt.size == 2 and stmt.data.value == 0:
|
|
50
|
+
# it's probably the terminating null byte
|
|
51
|
+
r, s = True, b"\x00\x00"
|
|
52
|
+
else:
|
|
53
|
+
r, s = InlinedWstrcpy.is_integer_likely_a_wide_string(
|
|
54
|
+
stmt.data.value, stmt.size, stmt.endness, min_length=1 # type:ignore
|
|
55
|
+
)
|
|
56
|
+
if r and s is not None:
|
|
57
|
+
new_str = s_last + s
|
|
58
|
+
|
|
59
|
+
if new_str is not None:
|
|
60
|
+
assert self.project is not None
|
|
61
|
+
wstr_type = SimTypePointer(SimTypeWideChar()).with_arch(self.project.arch)
|
|
62
|
+
if new_str.endswith(b"\x00\x00"):
|
|
63
|
+
call_name = "wstrcpy"
|
|
64
|
+
new_str_idx = self.kb.custom_strings.allocate(new_str[:-2])
|
|
65
|
+
args = [
|
|
66
|
+
last_stmt.args[0],
|
|
67
|
+
Const(None, None, new_str_idx, last_stmt.args[0].bits, custom_string=True, type=wstr_type),
|
|
68
|
+
]
|
|
69
|
+
prototype = None
|
|
70
|
+
else:
|
|
71
|
+
call_name = "wstrncpy"
|
|
72
|
+
new_str_idx = self.kb.custom_strings.allocate(new_str)
|
|
73
|
+
args = [
|
|
74
|
+
last_stmt.args[0],
|
|
75
|
+
Const(None, None, new_str_idx, last_stmt.args[0].bits, custom_string=True, type=wstr_type),
|
|
76
|
+
Const(None, None, len(new_str) // 2, self.project.arch.bits),
|
|
77
|
+
]
|
|
78
|
+
prototype = None
|
|
79
|
+
|
|
80
|
+
return [Call(stmt.idx, call_name, args=args, prototype=prototype, **stmt.tags)]
|
|
81
|
+
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _parse_addr(addr: Expression) -> tuple[Expression, int]:
|
|
86
|
+
if isinstance(addr, Register):
|
|
87
|
+
return addr, 0
|
|
88
|
+
if isinstance(addr, StackBaseOffset):
|
|
89
|
+
return StackBaseOffset(None, addr.bits, 0), addr.offset
|
|
90
|
+
if (
|
|
91
|
+
isinstance(addr, UnaryOp)
|
|
92
|
+
and addr.op == "Reference"
|
|
93
|
+
and isinstance(addr.operand, VirtualVariable)
|
|
94
|
+
and addr.operand.was_stack
|
|
95
|
+
):
|
|
96
|
+
return StackBaseOffset(None, addr.bits, 0), addr.operand.stack_offset
|
|
97
|
+
if isinstance(addr, BinaryOp):
|
|
98
|
+
if addr.op == "Add" and isinstance(addr.operands[1], Const) and isinstance(addr.operands[1].value, int):
|
|
99
|
+
base_0, offset_0 = InlinedWstrcpyConsolidation._parse_addr(addr.operands[0])
|
|
100
|
+
return base_0, offset_0 + addr.operands[1].value
|
|
101
|
+
if addr.op == "Sub" and isinstance(addr.operands[1], Const) and isinstance(addr.operands[1].value, int):
|
|
102
|
+
base_0, offset_0 = InlinedWstrcpyConsolidation._parse_addr(addr.operands[0])
|
|
103
|
+
return base_0, offset_0 - addr.operands[1].value
|
|
104
|
+
|
|
105
|
+
return addr, 0
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def _get_delta(addr_0: Expression, addr_1: Expression) -> int | None:
|
|
109
|
+
base_0, offset_0 = InlinedWstrcpyConsolidation._parse_addr(addr_0)
|
|
110
|
+
base_1, offset_1 = InlinedWstrcpyConsolidation._parse_addr(addr_1)
|
|
111
|
+
if base_0.likes(base_1):
|
|
112
|
+
return offset_1 - offset_0
|
|
113
|
+
return None
|
|
@@ -2230,52 +2230,68 @@ class CConstant(CExpression):
|
|
|
2230
2230
|
return f'{prefix}"{base_str}"'
|
|
2231
2231
|
|
|
2232
2232
|
def c_repr_chunks(self, indent=0, asexpr=False):
|
|
2233
|
+
|
|
2234
|
+
def _default_output(v) -> str | None:
|
|
2235
|
+
if isinstance(v, MemoryData) and v.sort == MemoryDataSort.String:
|
|
2236
|
+
return CConstant.str_to_c_str(v.content.decode("utf-8"))
|
|
2237
|
+
if isinstance(v, Function):
|
|
2238
|
+
return get_cpp_function_name(v.demangled_name)
|
|
2239
|
+
if isinstance(v, str):
|
|
2240
|
+
return CConstant.str_to_c_str(v)
|
|
2241
|
+
if isinstance(v, bytes):
|
|
2242
|
+
return CConstant.str_to_c_str(v.replace(b"\x00", b"").decode("utf-8"))
|
|
2243
|
+
return None
|
|
2244
|
+
|
|
2233
2245
|
if self.collapsed:
|
|
2234
2246
|
yield "...", self
|
|
2235
2247
|
return
|
|
2236
2248
|
|
|
2237
|
-
# default priority: string references -> variables -> other reference values
|
|
2238
2249
|
if self.reference_values is not None:
|
|
2239
|
-
|
|
2240
|
-
if isinstance(
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
yield
|
|
2250
|
+
if self._type is not None and self._type in self.reference_values:
|
|
2251
|
+
if isinstance(self._type, SimTypeInt):
|
|
2252
|
+
if isinstance(self.reference_values[self._type], int):
|
|
2253
|
+
yield self.fmt_int(self.reference_values[self._type]), self
|
|
2254
|
+
return
|
|
2255
|
+
yield hex(self.reference_values[self._type]), self
|
|
2245
2256
|
return
|
|
2246
|
-
elif isinstance(
|
|
2257
|
+
elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeChar):
|
|
2258
|
+
refval = self.reference_values[self._type]
|
|
2259
|
+
if isinstance(refval, MemoryData):
|
|
2260
|
+
v = refval.content.decode("utf-8")
|
|
2261
|
+
elif isinstance(refval, bytes):
|
|
2262
|
+
v = refval.decode("latin1")
|
|
2263
|
+
else:
|
|
2264
|
+
# it must be a string
|
|
2265
|
+
v = refval
|
|
2266
|
+
assert isinstance(v, str)
|
|
2247
2267
|
yield CConstant.str_to_c_str(v), self
|
|
2248
2268
|
return
|
|
2249
|
-
elif isinstance(
|
|
2250
|
-
|
|
2269
|
+
elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeWideChar):
|
|
2270
|
+
refval = self.reference_values[self._type]
|
|
2271
|
+
v = (
|
|
2272
|
+
refval.content.decode("utf_16_le")
|
|
2273
|
+
if isinstance(refval, MemoryData)
|
|
2274
|
+
else refval.decode("utf_16_le")
|
|
2275
|
+
) # it's a string
|
|
2276
|
+
yield CConstant.str_to_c_str(v, prefix="L"), self
|
|
2251
2277
|
return
|
|
2252
|
-
|
|
2253
|
-
if self.reference_values is not None and self._type is not None and self._type in self.reference_values:
|
|
2254
|
-
if isinstance(self._type, SimTypeInt):
|
|
2255
|
-
if isinstance(self.reference_values[self._type], int):
|
|
2256
|
-
yield self.fmt_int(self.reference_values[self._type]), self
|
|
2257
|
-
return
|
|
2258
|
-
yield hex(self.reference_values[self._type]), self
|
|
2259
|
-
elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeChar):
|
|
2260
|
-
refval = self.reference_values[self._type]
|
|
2261
|
-
if isinstance(refval, MemoryData):
|
|
2262
|
-
v = refval.content.decode("utf-8")
|
|
2263
2278
|
else:
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2279
|
+
if isinstance(self.reference_values[self._type], int):
|
|
2280
|
+
yield self.fmt_int(self.reference_values[self._type]), self
|
|
2281
|
+
return
|
|
2282
|
+
o = _default_output(self.reference_values[self.type])
|
|
2283
|
+
if o is not None:
|
|
2284
|
+
yield o, self
|
|
2285
|
+
return
|
|
2286
|
+
|
|
2287
|
+
# default priority: string references -> variables -> other reference values
|
|
2288
|
+
for _ty, v in self.reference_values.items(): # pylint:disable=unused-variable
|
|
2289
|
+
o = _default_output(v)
|
|
2290
|
+
if o is not None:
|
|
2291
|
+
yield o, self
|
|
2275
2292
|
return
|
|
2276
|
-
yield self.reference_values[self.type], self
|
|
2277
2293
|
|
|
2278
|
-
|
|
2294
|
+
if isinstance(self.value, int) and self.value == 0 and isinstance(self.type, SimTypePointer):
|
|
2279
2295
|
# print NULL instead
|
|
2280
2296
|
yield "NULL", self
|
|
2281
2297
|
|
|
@@ -3622,10 +3638,10 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3622
3638
|
if type_ is None and hasattr(expr, "type"):
|
|
3623
3639
|
type_ = expr.type
|
|
3624
3640
|
|
|
3625
|
-
if
|
|
3641
|
+
if reference_values is None and hasattr(expr, "reference_values"):
|
|
3626
3642
|
reference_values = expr.reference_values.copy()
|
|
3627
|
-
|
|
3628
|
-
|
|
3643
|
+
if type_ is None and reference_values is not None and len(reference_values) == 1: # type: ignore
|
|
3644
|
+
type_ = next(iter(reference_values)) # type: ignore
|
|
3629
3645
|
|
|
3630
3646
|
if reference_values is None:
|
|
3631
3647
|
reference_values = {}
|
|
@@ -3714,10 +3730,10 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3714
3730
|
offset = getattr(expr, "reference_variable_offset", 0)
|
|
3715
3731
|
var_access = self._access_constant_offset_reference(self._get_variable_reference(cvar), offset, None)
|
|
3716
3732
|
|
|
3717
|
-
if var_access is not None
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3733
|
+
if var_access is not None:
|
|
3734
|
+
if expr.value >= self.min_data_addr:
|
|
3735
|
+
return var_access
|
|
3736
|
+
reference_values["offset"] = var_access
|
|
3721
3737
|
return CConstant(expr.value, type_, reference_values=reference_values, tags=expr.tags, codegen=self)
|
|
3722
3738
|
|
|
3723
3739
|
def _handle_Expr_UnaryOp(self, expr, **kwargs):
|
|
@@ -30,6 +30,9 @@ class RegVVarPredicate:
|
|
|
30
30
|
self.arch = arch
|
|
31
31
|
|
|
32
32
|
def _get_call_clobbered_regs(self, stmt: Call) -> set[int]:
|
|
33
|
+
if isinstance(stmt.target, str):
|
|
34
|
+
# pseudo calls do not clobber any registers
|
|
35
|
+
return set()
|
|
33
36
|
cc = stmt.calling_convention
|
|
34
37
|
if cc is None:
|
|
35
38
|
# get the default calling convention
|
|
@@ -1,25 +1,45 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
from angr.serializable import Serializable
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class IndirectJumpType:
|
|
7
|
+
"""
|
|
8
|
+
The type of an indirect jump or call.
|
|
9
|
+
"""
|
|
10
|
+
|
|
6
11
|
Jumptable_AddressLoadedFromMemory = 0
|
|
7
12
|
Jumptable_AddressComputed = 1
|
|
8
13
|
Vtable = 3
|
|
9
14
|
Unknown = 255
|
|
10
15
|
|
|
11
16
|
|
|
17
|
+
class JumptableInfo:
|
|
18
|
+
"""
|
|
19
|
+
Describes a jump table or a vtable.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ("addr", "entries", "entry_size", "size")
|
|
23
|
+
|
|
24
|
+
def __init__(self, addr: int | None, size: int, entry_size: int, entries: list[int]):
|
|
25
|
+
self.addr = addr
|
|
26
|
+
self.size = size
|
|
27
|
+
self.entry_size = entry_size
|
|
28
|
+
self.entries = entries
|
|
29
|
+
|
|
30
|
+
|
|
12
31
|
class IndirectJump(Serializable):
|
|
32
|
+
"""
|
|
33
|
+
Describes an indirect jump or call site.
|
|
34
|
+
"""
|
|
35
|
+
|
|
13
36
|
__slots__ = (
|
|
14
37
|
"addr",
|
|
15
38
|
"func_addr",
|
|
16
39
|
"ins_addr",
|
|
17
40
|
"jumpkind",
|
|
18
41
|
"jumptable",
|
|
19
|
-
"
|
|
20
|
-
"jumptable_entries",
|
|
21
|
-
"jumptable_entry_size",
|
|
22
|
-
"jumptable_size",
|
|
42
|
+
"jumptables",
|
|
23
43
|
"resolved_targets",
|
|
24
44
|
"stmt_idx",
|
|
25
45
|
"type",
|
|
@@ -47,12 +67,56 @@ class IndirectJump(Serializable):
|
|
|
47
67
|
self.stmt_idx = stmt_idx
|
|
48
68
|
self.resolved_targets = set() if resolved_targets is None else set(resolved_targets)
|
|
49
69
|
self.jumptable = jumptable
|
|
50
|
-
self.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
70
|
+
self.jumptables: list[JumptableInfo] = []
|
|
71
|
+
if (
|
|
72
|
+
jumptable_addr is not None
|
|
73
|
+
and jumptable_size is not None
|
|
74
|
+
and jumptable_entry_size is not None
|
|
75
|
+
and jumptable_entries is not None
|
|
76
|
+
):
|
|
77
|
+
self.add_jumptable(jumptable_addr, jumptable_size, jumptable_entry_size, jumptable_entries)
|
|
54
78
|
self.type = type_
|
|
55
79
|
|
|
80
|
+
def add_jumptable(
|
|
81
|
+
self,
|
|
82
|
+
addr: int | None,
|
|
83
|
+
size: int,
|
|
84
|
+
entry_size: int,
|
|
85
|
+
entries: list[int],
|
|
86
|
+
is_primary: bool = False,
|
|
87
|
+
) -> None:
|
|
88
|
+
ji = JumptableInfo(addr, size, entry_size, entries)
|
|
89
|
+
if is_primary:
|
|
90
|
+
self.jumptables.insert(0, ji)
|
|
91
|
+
else:
|
|
92
|
+
self.jumptables.append(ji)
|
|
93
|
+
|
|
94
|
+
# for compatibility convenience
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def jumptable_addr(self) -> int | None:
|
|
98
|
+
if self.jumptables:
|
|
99
|
+
return self.jumptables[0].addr
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def jumptable_size(self) -> int | None:
|
|
104
|
+
if self.jumptables:
|
|
105
|
+
return self.jumptables[0].size
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def jumptable_entry_size(self) -> int | None:
|
|
110
|
+
if self.jumptables:
|
|
111
|
+
return self.jumptables[0].entry_size
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def jumptable_entries(self) -> list[int] | None:
|
|
116
|
+
if self.jumptables:
|
|
117
|
+
return self.jumptables[0].entries
|
|
118
|
+
return None
|
|
119
|
+
|
|
56
120
|
def __repr__(self):
|
|
57
121
|
status = ""
|
|
58
122
|
if self.jumptable or self.jumptable_entries:
|
|
@@ -61,5 +125,7 @@ class IndirectJump(Serializable):
|
|
|
61
125
|
status += f"@{self.jumptable_addr:#08x}"
|
|
62
126
|
if self.jumptable_entries is not None:
|
|
63
127
|
status += f" with {len(self.jumptable_entries)} entries"
|
|
128
|
+
if len(self.jumptables) > 1:
|
|
129
|
+
status += f" (+{len(self.jumptables)-1} jumptables)"
|
|
64
130
|
|
|
65
131
|
return "<IndirectJump {:#08x} - ins {:#08x}{}>".format(self.addr, self.ins_addr, " " + status if status else "")
|
angr/rustylib.abi3.so
CHANGED
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: angr
|
|
3
|
-
Version: 9.2.
|
|
3
|
+
Version: 9.2.173
|
|
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
|
License: BSD-2-Clause
|
|
6
6
|
Project-URL: Homepage, https://angr.io/
|
|
@@ -16,12 +16,12 @@ Description-Content-Type: text/markdown
|
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: cxxheaderparser
|
|
18
18
|
Requires-Dist: GitPython
|
|
19
|
-
Requires-Dist: archinfo==9.2.
|
|
19
|
+
Requires-Dist: archinfo==9.2.173
|
|
20
20
|
Requires-Dist: cachetools
|
|
21
21
|
Requires-Dist: capstone==5.0.3
|
|
22
22
|
Requires-Dist: cffi>=1.14.0
|
|
23
|
-
Requires-Dist: claripy==9.2.
|
|
24
|
-
Requires-Dist: cle==9.2.
|
|
23
|
+
Requires-Dist: claripy==9.2.173
|
|
24
|
+
Requires-Dist: cle==9.2.173
|
|
25
25
|
Requires-Dist: mulpyplexer
|
|
26
26
|
Requires-Dist: networkx!=2.8.1,>=2.0
|
|
27
27
|
Requires-Dist: protobuf>=5.28.2
|
|
@@ -30,7 +30,7 @@ Requires-Dist: pycparser>=2.18
|
|
|
30
30
|
Requires-Dist: pydemumble
|
|
31
31
|
Requires-Dist: pyformlang
|
|
32
32
|
Requires-Dist: pypcode<4.0,>=3.2.1
|
|
33
|
-
Requires-Dist: pyvex==9.2.
|
|
33
|
+
Requires-Dist: pyvex==9.2.173
|
|
34
34
|
Requires-Dist: rich>=13.1.0
|
|
35
35
|
Requires-Dist: sortedcontainers
|
|
36
36
|
Requires-Dist: sympy
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
angr/__init__.py,sha256=
|
|
1
|
+
angr/__init__.py,sha256=2Ys7dgqv6Ad4nZVxaLf0JjowZ0LJFev07_3vDZ21Y3M,9246
|
|
2
2
|
angr/__main__.py,sha256=AK9V6uPZ58UuTKmmiH_Kgn5pG9AvjnmJCPOku69A-WU,4993
|
|
3
3
|
angr/annocfg.py,sha256=0NIvcuCskwz45hbBzigUTAuCrYutjDMwEXtMJf0y0S0,10742
|
|
4
4
|
angr/blade.py,sha256=OGGW-oggqI9_LvgZhiQuh9Ktkvf3vhRBmH0XviNyZ6o,15801
|
|
@@ -15,7 +15,7 @@ angr/keyed_region.py,sha256=Cx6dadqFgEvRmEHTbCJpg9mXkBtKGc_BKckHc6bk1IU,17992
|
|
|
15
15
|
angr/knowledge_base.py,sha256=hRoSLuLaOXmddTSF9FN5TVs7liftpBGq_IICz5AaYBk,4533
|
|
16
16
|
angr/project.py,sha256=AJmBgv3U8iv-hGEfnpmESVVjK16NiBAemmahLuqz7yk,38096
|
|
17
17
|
angr/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
|
|
18
|
-
angr/rustylib.abi3.so,sha256=
|
|
18
|
+
angr/rustylib.abi3.so,sha256=Us4swHS7rEEqLmZh7WJPrAoDpb7f4ppBLJivsmEzBYo,5823792
|
|
19
19
|
angr/serializable.py,sha256=l908phj_KcqopEEL_oCufbP_H6cm3Wc9v-5xdux1-6g,1533
|
|
20
20
|
angr/sim_manager.py,sha256=w7yTfWR-P9yoN5x85eeiNpj9dTrnjpJ3o5aoFpDAPnc,39396
|
|
21
21
|
angr/sim_options.py,sha256=tfl57MFECmA7uvMMtQrRRbpG8g_A9jKOzwY6nApTW6Y,17782
|
|
@@ -80,7 +80,7 @@ angr/analyses/vtable.py,sha256=1Ed7jzr99rk9VgOGzcxBw_6GFqby5mIdSTGPqQPhcZM,3872
|
|
|
80
80
|
angr/analyses/xrefs.py,sha256=vs6cpVmwXHOmxrI9lJUwCRMYbPSqvIQXS5_fINMaOGI,10290
|
|
81
81
|
angr/analyses/calling_convention/__init__.py,sha256=bK5VS6AxT5l86LAhTL7l1HUT9IuvXG9x9ikbIohIFoE,194
|
|
82
82
|
angr/analyses/calling_convention/calling_convention.py,sha256=vdGqrv7SQDnO6Rg9rgDuQSUPxHYGRgEeneTEQhGM-2M,46762
|
|
83
|
-
angr/analyses/calling_convention/fact_collector.py,sha256=
|
|
83
|
+
angr/analyses/calling_convention/fact_collector.py,sha256=9qx3jvBBrhKvRoZrCir61KZBqFtduiFzhbHAtWFvMic,28762
|
|
84
84
|
angr/analyses/calling_convention/utils.py,sha256=twkO073RvkkFXnOTc-KYQT1GKUtz0OPjxh0N6AWIriQ,2110
|
|
85
85
|
angr/analyses/cfg/__init__.py,sha256=-w8Vd6FD6rtjlQaQ7MxwmliFgS2zt-kZepAY4gHas04,446
|
|
86
86
|
angr/analyses/cfg/cfb.py,sha256=HI25OJKs2OUlWkOSG4kLsZQFnBJcfDwSQKp6_ZRsoQY,15353
|
|
@@ -88,7 +88,7 @@ angr/analyses/cfg/cfg.py,sha256=dc9M91CaLeEKduYfMwpsT_01x6XyYuoNvgvcDKtbN-I,3177
|
|
|
88
88
|
angr/analyses/cfg/cfg_arch_options.py,sha256=_XRewFZ51SeNaxChadb6_ER7-8LW8KXeTIpoP8_iRj0,3506
|
|
89
89
|
angr/analyses/cfg/cfg_base.py,sha256=eleUmM_znfsl6KV7T2tUmSEy2iLmPsrT3dNB2BYudd4,124964
|
|
90
90
|
angr/analyses/cfg/cfg_emulated.py,sha256=4lKrmGVfCGt8l3Nz9zH6EcUcAVLwyOM7p81DlxUVNGA,148351
|
|
91
|
-
angr/analyses/cfg/cfg_fast.py,sha256=
|
|
91
|
+
angr/analyses/cfg/cfg_fast.py,sha256=shJdaaQ_4gAB7yMe6oFNrC-uWIdhbD-z4jqx5_VdSGs,233023
|
|
92
92
|
angr/analyses/cfg/cfg_fast_soot.py,sha256=8YgMtY_8w4nAMcHR6n-q_eFvKwsvNz0anUH7EzIL1B4,25924
|
|
93
93
|
angr/analyses/cfg/cfg_job_base.py,sha256=Zshze972MakTsd-licQz77lac17igQaaTsAteHeHhYQ,5974
|
|
94
94
|
angr/analyses/cfg/indirect_jump_resolvers/__init__.py,sha256=qWiTSIAQgXWmaYa9YYaiKsSTwUVClymaXv9sCX-bY-k,835
|
|
@@ -98,7 +98,7 @@ angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py,sha256=KzX-BYgEM1npZYi
|
|
|
98
98
|
angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py,sha256=eo9Bn-lVAzsx-Y7ncr647enHmWyAZIehc9_Q6Uq7xc8,15517
|
|
99
99
|
angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py,sha256=iADDFxnMdIOaN72a0FcODG79dcMzlesYT6LGmQKJxAc,3728
|
|
100
100
|
angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py,sha256=Gec_CgniGF9kXcbYfsocYbxhkTncI4MzfzDLxq_4cuk,1741
|
|
101
|
-
angr/analyses/cfg/indirect_jump_resolvers/jumptable.py,sha256=
|
|
101
|
+
angr/analyses/cfg/indirect_jump_resolvers/jumptable.py,sha256=XJKPcZiKAYJQ4YusVx0xPXQfuoi_qdrHM1Wjf_zh2C4,109111
|
|
102
102
|
angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py,sha256=jmCiDkloyyqb6iRfjXBlu2N9uwYhiqeiXWhnUXW27dU,2950
|
|
103
103
|
angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py,sha256=SSwWVKCqMNxdqTeMkLqXk5UFmzgxJDm8H-xLNBr1Hnc,10173
|
|
104
104
|
angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py,sha256=DT1tomUTCXmhD8N_V4KMeyS-YecDlR7f4kOANiKyGeI,5213
|
|
@@ -120,9 +120,9 @@ angr/analyses/decompiler/ail_simplifier.py,sha256=s9hFXhNwU8fBKDOkw4vtSWhSWy9xBd
|
|
|
120
120
|
angr/analyses/decompiler/ailgraph_walker.py,sha256=m71HCthOr9J8PZoMxJzCPskay8yfCZ2j8esWT4Ka3KI,1630
|
|
121
121
|
angr/analyses/decompiler/block_io_finder.py,sha256=9J56W0_SQPczZ2-VoxqSv61T57foHmzy7wPtUtQKffU,10943
|
|
122
122
|
angr/analyses/decompiler/block_similarity.py,sha256=S1lTlXFyOmJlQa7I3y7xgLsENLS4XGET7tdD55k_6Vg,6859
|
|
123
|
-
angr/analyses/decompiler/block_simplifier.py,sha256=
|
|
123
|
+
angr/analyses/decompiler/block_simplifier.py,sha256=vjlugXCB3xFYBDBn3LPxOtU1dDc76PpYtVEoju3i9-4,15513
|
|
124
124
|
angr/analyses/decompiler/callsite_maker.py,sha256=O7vjwNTmCLijzjKgSCaoX3IX4_sC-u-OqoKhE7lahlc,23427
|
|
125
|
-
angr/analyses/decompiler/clinic.py,sha256=
|
|
125
|
+
angr/analyses/decompiler/clinic.py,sha256=pULhfkuDYNBT9o5nYWX9fl1sP0RiWBVCUhHDsmUeIPc,151320
|
|
126
126
|
angr/analyses/decompiler/condition_processor.py,sha256=ALx1EO82EWOfj1mjWhS_8GNMLdEO98jqnIqB-CtfELg,56692
|
|
127
127
|
angr/analyses/decompiler/decompilation_cache.py,sha256=06oiG299mVpGOTL54Xy1CUxz5s8QLgYJn5XIvKFLYkU,1566
|
|
128
128
|
angr/analyses/decompiler/decompilation_options.py,sha256=bs6CNpU3UxepgBB_9eUH4jriNpGoryyPP0sR1hDWpTk,8477
|
|
@@ -202,7 +202,7 @@ angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_re
|
|
|
202
202
|
angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py,sha256=dJq1F3jbGBFWi0zIUmDu8bwUAKPt-JyAh5iegY9rYuU,527
|
|
203
203
|
angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py,sha256=H9FGTyxHm-KbqgxuTe2qjMotboRbUyOTeiPVcD_8DSk,4411
|
|
204
204
|
angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py,sha256=_WiRuxiMaxRAYtU5LiHGQ383PiI0sCt-KgG2QFG0KX4,5176
|
|
205
|
-
angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=
|
|
205
|
+
angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=EbnjFKVoLce23AbmF-06EdW-TzAeoZjn_NHDkqNWATQ,5034
|
|
206
206
|
angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py,sha256=HY6EQkThiyMaahz3bodJUqLBKWY2n4aKGbKyspMXN50,1641
|
|
207
207
|
angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py,sha256=-V60wMaBKz1Ld1NcaQ8Dl0T4Xo9Qq6nfAQpXJ-MNsDI,1379
|
|
208
208
|
angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py,sha256=5Gsq3DSQEWt3tZSkrxnbAEePkKC_dmpoQHZ2PVNlSfs,1158
|
|
@@ -217,7 +217,7 @@ angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py,sh
|
|
|
217
217
|
angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py,sha256=09PA82Sg2FlBp2XZd4-WSES-8BQesXPXvIlpuuGByvM,1306
|
|
218
218
|
angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py,sha256=vLXt0ekjRep4SgaNq1wyxVkBTzOMTa03d3rgkjUOcUg,995
|
|
219
219
|
angr/analyses/decompiler/peephole_optimizations/bswap.py,sha256=fXV_a58W2X30KCanYeSHdZ2yPcfDlyZq_OkYNMkglrg,6420
|
|
220
|
-
angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py,sha256=
|
|
220
|
+
angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py,sha256=2A7NZIzZpDCq3i8e72l7c7KHfEwfJvzi5NffoXU_NNE,4559
|
|
221
221
|
angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py,sha256=sJV-8aP9KUx5Kt7pZmb3M28K3z2bGD3NWJFZOdYaBYc,2662
|
|
222
222
|
angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py,sha256=fXq-qFe7JUdD5LdtUhoA9AF3LnY-3Jrmo4t3ZRJIIiQ,1414
|
|
223
223
|
angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py,sha256=--C1JQluHt8ltdfUPBHvRD3SjW_ZcBU3oWdFwpCtpuw,1072
|
|
@@ -229,7 +229,8 @@ angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py,sha256
|
|
|
229
229
|
angr/analyses/decompiler/peephole_optimizations/inlined_memcpy.py,sha256=5OAgdFMTRlTggLQSUbVcUdgUmkJN7_p4wYkqt1A4AYQ,2944
|
|
230
230
|
angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py,sha256=q2IVsIFhfo0TGY3PfeOmCZqdpzUI2B3Tjv_p3_jpwl4,8668
|
|
231
231
|
angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py,sha256=d-O_rIm0OrwK88P0zYBZcOY0ewTdCp4bnkJZDdWUUVw,4883
|
|
232
|
-
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py,sha256=
|
|
232
|
+
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py,sha256=rR3eC_pjCVBuc8GuWzJJkn6h8c964ODf-5uiwlncwVE,9896
|
|
233
|
+
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy_consolidation.py,sha256=TsQEpHhyVr7MdiSFkijR6GFMHsuKlmmy9qvSCo32c2U,5409
|
|
233
234
|
angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py,sha256=hRx0tuK_s47AEgPfaWYbzh5lPfBhx_anGDTVoIxHYkg,1990
|
|
234
235
|
angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py,sha256=M09Whprj6tOJdFI5n9a7b-82YZOgnm3QvIbISJ9Lvaw,3724
|
|
235
236
|
angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py,sha256=zljXiUnoH6AwgAoXVRwz9dXEedW7RiUTkHvBMZIA-o8,1140
|
|
@@ -285,7 +286,7 @@ angr/analyses/decompiler/ssailification/traversal_engine.py,sha256=MdmNKWN2LVQ9f
|
|
|
285
286
|
angr/analyses/decompiler/ssailification/traversal_state.py,sha256=RDs2mTc6GYnbMom2gBfNfNMcazKMSkhemEmse8uELTY,1558
|
|
286
287
|
angr/analyses/decompiler/structured_codegen/__init__.py,sha256=mxG4yruPAab8735wVgXZ1zu8qFPz-njKe0m5UcywE3o,633
|
|
287
288
|
angr/analyses/decompiler/structured_codegen/base.py,sha256=mb5d5iQO1N2wMl7QySvfHemXM-e0yQBhjtlmnLsVSgE,5134
|
|
288
|
-
angr/analyses/decompiler/structured_codegen/c.py,sha256=
|
|
289
|
+
angr/analyses/decompiler/structured_codegen/c.py,sha256=sFizu2EWABRhv_yaBXd85rPhoRIEZNZ6zdLp5Q4XHa8,150180
|
|
289
290
|
angr/analyses/decompiler/structured_codegen/dummy.py,sha256=JZLeovXE-8C-unp2hbejxCG30l-yCx4sWFh7JMF_iRM,570
|
|
290
291
|
angr/analyses/decompiler/structured_codegen/dwarf_import.py,sha256=J6V40RuIyKXN7r6ESftIYfoREgmgFavnUL5m3lyTzlM,7072
|
|
291
292
|
angr/analyses/decompiler/structuring/__init__.py,sha256=kEFP-zv9CZrhJtLTKwT9-9cGVTls71wLYaLDUuYorBU,711
|
|
@@ -379,7 +380,7 @@ angr/analyses/reaching_definitions/function_handler_library/string.py,sha256=qh7
|
|
|
379
380
|
angr/analyses/reaching_definitions/function_handler_library/unistd.py,sha256=oO2HROZZWsjPlCLMxEo7T4M5JkYRlkc9BLLYLwY1SfQ,2370
|
|
380
381
|
angr/analyses/s_reaching_definitions/__init__.py,sha256=TyfVplxkJj8FAAAw9wegzJlcrbGwlFpIB23PdCcwrLA,254
|
|
381
382
|
angr/analyses/s_reaching_definitions/s_rda_model.py,sha256=FJSge_31FFzyzBJA1xm7dQz40TfuNna6v_RWAZMZvi0,5801
|
|
382
|
-
angr/analyses/s_reaching_definitions/s_rda_view.py,sha256=
|
|
383
|
+
angr/analyses/s_reaching_definitions/s_rda_view.py,sha256=7o-llkMUJP_ZhnQ4tkCDrzYok4cAOA7PLt2tX9DY8Mo,13929
|
|
383
384
|
angr/analyses/s_reaching_definitions/s_reaching_definitions.py,sha256=gNdg8xpu5by_McWU8j0g0502yQsO2evkTlben9yimV0,7826
|
|
384
385
|
angr/analyses/typehoon/__init__.py,sha256=KjKBUZadAd3grXUy48_qO0L4Me-riSqPGteVDcTL59M,92
|
|
385
386
|
angr/analyses/typehoon/dfa.py,sha256=41lzhE-QmkC342SjfaaPI41lr4Au5XROTu_7oenvg7g,3823
|
|
@@ -562,7 +563,7 @@ angr/knowledge_plugins/cfg/__init__.py,sha256=oU07YZ4TIsoje8qr6nw_nM2NXizEGKuulD
|
|
|
562
563
|
angr/knowledge_plugins/cfg/cfg_manager.py,sha256=QGXCsdoLiH_vW7LP1EWGLlRVlMSqAM06l6qWq7uxQJU,2651
|
|
563
564
|
angr/knowledge_plugins/cfg/cfg_model.py,sha256=Z5HOM7xh285gF5DGmQGRSWWD9KJyjXVWLvl0i521OkA,41722
|
|
564
565
|
angr/knowledge_plugins/cfg/cfg_node.py,sha256=mAvQ8XAEURM7y0suc_S9lfxCmfXSTJHmWBsLonpNpLA,17183
|
|
565
|
-
angr/knowledge_plugins/cfg/indirect_jump.py,sha256=
|
|
566
|
+
angr/knowledge_plugins/cfg/indirect_jump.py,sha256=XQjyH8ZhSlRFWLc--QY9Voq0RB7nI2wzeP5COANwoOc,3741
|
|
566
567
|
angr/knowledge_plugins/cfg/memory_data.py,sha256=QLxFZfrtwz8u6UJn1L-Sxa-C8S0Gy9IOlfNfHCLPIow,5056
|
|
567
568
|
angr/knowledge_plugins/functions/__init__.py,sha256=asiLNiT6sHbjP6eU-kDpawIoVxv4J35cwz5yQHtQ2E0,167
|
|
568
569
|
angr/knowledge_plugins/functions/function.py,sha256=8DsaHa_mcMZ79zRw804f5q6Vj1XRCwL7XUZVA3F2X88,71180
|
|
@@ -1406,9 +1407,9 @@ angr/utils/vex.py,sha256=epcrCexi_NjKnPGM2gfpiRsUea_Scd-71UMuF32ZAQo,306
|
|
|
1406
1407
|
angr/utils/ssa/__init__.py,sha256=xbuVllFoPane9lHACdRQP5OO99Mca-4sqpFrtoAvnxo,17464
|
|
1407
1408
|
angr/utils/ssa/tmp_uses_collector.py,sha256=digAUQpYoFR1VYfwoXlF3T1pYdDi6Pdq_ck54SjMabQ,813
|
|
1408
1409
|
angr/utils/ssa/vvar_uses_collector.py,sha256=HewqUQluNE9EsaiLeFo7LaBvws_DDBDYNt9RBExy464,1367
|
|
1409
|
-
angr-9.2.
|
|
1410
|
-
angr-9.2.
|
|
1411
|
-
angr-9.2.
|
|
1412
|
-
angr-9.2.
|
|
1413
|
-
angr-9.2.
|
|
1414
|
-
angr-9.2.
|
|
1410
|
+
angr-9.2.173.dist-info/METADATA,sha256=iZFZTkufSw1zmEbcMmoF3paxU1UXWSFzOPAJ4lU_t4c,4343
|
|
1411
|
+
angr-9.2.173.dist-info/WHEEL,sha256=LqR_W0RRJW31YMkRS3Dv-iW-Y--YJhfEgOaHweTHgb8,112
|
|
1412
|
+
angr-9.2.173.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
|
|
1413
|
+
angr-9.2.173.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
|
|
1414
|
+
angr-9.2.173.dist-info/RECORD,,
|
|
1415
|
+
angr-9.2.173.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|