angr 9.2.172__cp310-abi3-macosx_10_12_x86_64.whl → 9.2.173__cp310-abi3-macosx_10_12_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/unicornlib.dylib +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 +21 -20
- {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
|
angr/unicornlib.dylib
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,23 +1,23 @@
|
|
|
1
|
-
angr-9.2.
|
|
2
|
-
angr-9.2.
|
|
3
|
-
angr-9.2.
|
|
4
|
-
angr-9.2.
|
|
5
|
-
angr-9.2.
|
|
6
|
-
angr-9.2.
|
|
1
|
+
angr-9.2.173.dist-info/RECORD,,
|
|
2
|
+
angr-9.2.173.dist-info/WHEEL,sha256=wTy_3c4XcOAcqIE15cpeRqeJHiJiSBH-pmU5VVW1EO8,137
|
|
3
|
+
angr-9.2.173.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
|
|
4
|
+
angr-9.2.173.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
|
|
5
|
+
angr-9.2.173.dist-info/METADATA,sha256=iZFZTkufSw1zmEbcMmoF3paxU1UXWSFzOPAJ4lU_t4c,4343
|
|
6
|
+
angr-9.2.173.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
|
|
7
7
|
angr/vaults.py,sha256=D_gkDegCyPlZMKGC5E8zINYAaZfSXNWbmhX0rXCYpvM,9718
|
|
8
|
-
angr/unicornlib.dylib,sha256=
|
|
8
|
+
angr/unicornlib.dylib,sha256=ap3ME0HcxUPSsyrifxavZ6J_v9nKZSz1chr2amCB8Jw,264656
|
|
9
9
|
angr/state_hierarchy.py,sha256=qDQCUGXmQm3vOxE3CSoiqTH4OAFFOWZZt9BLhNpeOhA,8484
|
|
10
10
|
angr/callable.py,sha256=j9Orwd4H4fPqOYylcEt5GuLGPV7ZOqyA_OYO2bp5PAA,6437
|
|
11
11
|
angr/sim_type.py,sha256=Z0gWJaTVwjC6I_O7nzwa0DtEXZSFA9ekikm-U2gxCR4,135357
|
|
12
12
|
angr/knowledge_base.py,sha256=hRoSLuLaOXmddTSF9FN5TVs7liftpBGq_IICz5AaYBk,4533
|
|
13
13
|
angr/emulator.py,sha256=572e9l-N4VUzUzLKylqpv3JmBvVC5VExi1tLy6MZSoU,4633
|
|
14
|
-
angr/rustylib.abi3.so,sha256=
|
|
14
|
+
angr/rustylib.abi3.so,sha256=GxYgg0Ujk_bP1mpelCeLpUeAKSF1ZUCuAiO7pJ-hk7M,5259788
|
|
15
15
|
angr/codenode.py,sha256=hCrQRp4Ebb2X6JicNmY1PXo3_Pm8GDxVivVW0Pwe84k,3918
|
|
16
16
|
angr/graph_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
angr/sim_manager.py,sha256=w7yTfWR-P9yoN5x85eeiNpj9dTrnjpJ3o5aoFpDAPnc,39396
|
|
18
18
|
angr/serializable.py,sha256=l908phj_KcqopEEL_oCufbP_H6cm3Wc9v-5xdux1-6g,1533
|
|
19
19
|
angr/code_location.py,sha256=kXNJDEMge9VRHadrK4E6HQ8wDdCaHSXNqyAZuHDEGuM,5397
|
|
20
|
-
angr/__init__.py,sha256=
|
|
20
|
+
angr/__init__.py,sha256=2Ys7dgqv6Ad4nZVxaLf0JjowZ0LJFev07_3vDZ21Y3M,9246
|
|
21
21
|
angr/blade.py,sha256=OGGW-oggqI9_LvgZhiQuh9Ktkvf3vhRBmH0XviNyZ6o,15801
|
|
22
22
|
angr/factory.py,sha256=PPNWvTiWaIgzxzyoTr8ObSF-TXp1hCdbY2e-0xBePNc,17815
|
|
23
23
|
angr/sim_state_options.py,sha256=dsMY3UefvL7yZKXloubMhzUET3N2Crw-Fpw2Vd1ouZQ,12468
|
|
@@ -914,7 +914,7 @@ angr/knowledge_plugins/key_definitions/definition.py,sha256=AAePJW3BYV0Ju3ZFdqVJ
|
|
|
914
914
|
angr/knowledge_plugins/key_definitions/environment.py,sha256=UbXUgv2vjz_dbG_gF2iNK6ZztKt2vgxov9SXdVEWFXk,3886
|
|
915
915
|
angr/knowledge_plugins/key_definitions/atoms.py,sha256=dKbhvROB0cKSIZC1Z29MvIUmEHx5Ke6rK1lMgmKNdV8,11149
|
|
916
916
|
angr/knowledge_plugins/key_definitions/tag.py,sha256=QWtBe5yuMei6t2NRPwolVyUa1XyY2khMeU6pQwb66iQ,1710
|
|
917
|
-
angr/knowledge_plugins/cfg/indirect_jump.py,sha256=
|
|
917
|
+
angr/knowledge_plugins/cfg/indirect_jump.py,sha256=XQjyH8ZhSlRFWLc--QY9Voq0RB7nI2wzeP5COANwoOc,3741
|
|
918
918
|
angr/knowledge_plugins/cfg/__init__.py,sha256=oU07YZ4TIsoje8qr6nw_nM2NXizEGKuulD1RDxk4PWI,418
|
|
919
919
|
angr/knowledge_plugins/cfg/memory_data.py,sha256=QLxFZfrtwz8u6UJn1L-Sxa-C8S0Gy9IOlfNfHCLPIow,5056
|
|
920
920
|
angr/knowledge_plugins/cfg/cfg_model.py,sha256=Z5HOM7xh285gF5DGmQGRSWWD9KJyjXVWLvl0i521OkA,41722
|
|
@@ -1120,7 +1120,7 @@ angr/analyses/variable_recovery/engine_vex.py,sha256=5Q2S1jAr7tALa0m0okqBHBe3cUe
|
|
|
1120
1120
|
angr/analyses/variable_recovery/variable_recovery_base.py,sha256=Ewd0TzNdZ_gRYXtXjVrJfODNABMMPjnuvMy9-Nnyui0,16813
|
|
1121
1121
|
angr/analyses/variable_recovery/annotations.py,sha256=2va7cXnRHYqVqXeVt00QanxfAo3zanL4BkAcC0-Bk20,1438
|
|
1122
1122
|
angr/analyses/variable_recovery/engine_base.py,sha256=MJ6h-dq_0r-3I3ZOhR8E4So2VqxlyudNeSrAHyQCNRg,53171
|
|
1123
|
-
angr/analyses/calling_convention/fact_collector.py,sha256=
|
|
1123
|
+
angr/analyses/calling_convention/fact_collector.py,sha256=9qx3jvBBrhKvRoZrCir61KZBqFtduiFzhbHAtWFvMic,28762
|
|
1124
1124
|
angr/analyses/calling_convention/__init__.py,sha256=bK5VS6AxT5l86LAhTL7l1HUT9IuvXG9x9ikbIohIFoE,194
|
|
1125
1125
|
angr/analyses/calling_convention/calling_convention.py,sha256=vdGqrv7SQDnO6Rg9rgDuQSUPxHYGRgEeneTEQhGM-2M,46762
|
|
1126
1126
|
angr/analyses/calling_convention/utils.py,sha256=twkO073RvkkFXnOTc-KYQT1GKUtz0OPjxh0N6AWIriQ,2110
|
|
@@ -1159,13 +1159,13 @@ angr/analyses/reaching_definitions/function_handler_library/stdlib.py,sha256=YRN
|
|
|
1159
1159
|
angr/analyses/cfg/cfg.py,sha256=dc9M91CaLeEKduYfMwpsT_01x6XyYuoNvgvcDKtbN-I,3177
|
|
1160
1160
|
angr/analyses/cfg/cfb.py,sha256=HI25OJKs2OUlWkOSG4kLsZQFnBJcfDwSQKp6_ZRsoQY,15353
|
|
1161
1161
|
angr/analyses/cfg/cfg_job_base.py,sha256=Zshze972MakTsd-licQz77lac17igQaaTsAteHeHhYQ,5974
|
|
1162
|
-
angr/analyses/cfg/cfg_fast.py,sha256=
|
|
1162
|
+
angr/analyses/cfg/cfg_fast.py,sha256=shJdaaQ_4gAB7yMe6oFNrC-uWIdhbD-z4jqx5_VdSGs,233023
|
|
1163
1163
|
angr/analyses/cfg/__init__.py,sha256=-w8Vd6FD6rtjlQaQ7MxwmliFgS2zt-kZepAY4gHas04,446
|
|
1164
1164
|
angr/analyses/cfg/cfg_fast_soot.py,sha256=8YgMtY_8w4nAMcHR6n-q_eFvKwsvNz0anUH7EzIL1B4,25924
|
|
1165
1165
|
angr/analyses/cfg/cfg_arch_options.py,sha256=_XRewFZ51SeNaxChadb6_ER7-8LW8KXeTIpoP8_iRj0,3506
|
|
1166
1166
|
angr/analyses/cfg/cfg_emulated.py,sha256=4lKrmGVfCGt8l3Nz9zH6EcUcAVLwyOM7p81DlxUVNGA,148351
|
|
1167
1167
|
angr/analyses/cfg/cfg_base.py,sha256=eleUmM_znfsl6KV7T2tUmSEy2iLmPsrT3dNB2BYudd4,124964
|
|
1168
|
-
angr/analyses/cfg/indirect_jump_resolvers/jumptable.py,sha256=
|
|
1168
|
+
angr/analyses/cfg/indirect_jump_resolvers/jumptable.py,sha256=XJKPcZiKAYJQ4YusVx0xPXQfuoi_qdrHM1Wjf_zh2C4,109111
|
|
1169
1169
|
angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py,sha256=SSwWVKCqMNxdqTeMkLqXk5UFmzgxJDm8H-xLNBr1Hnc,10173
|
|
1170
1170
|
angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py,sha256=jmCiDkloyyqb6iRfjXBlu2N9uwYhiqeiXWhnUXW27dU,2950
|
|
1171
1171
|
angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py,sha256=eo9Bn-lVAzsx-Y7ncr647enHmWyAZIehc9_Q6Uq7xc8,15517
|
|
@@ -1228,9 +1228,9 @@ angr/analyses/decompiler/region_identifier.py,sha256=kQJ_KCd3Qx9LWStTM_iUNBG10bD
|
|
|
1228
1228
|
angr/analyses/decompiler/empty_node_remover.py,sha256=4CdxTM1AVmRoEdRIwJg1YEy10AgkEoRmJ8SU7xGbKnM,7424
|
|
1229
1229
|
angr/analyses/decompiler/seq_to_blocks.py,sha256=4-tqstendHHO2J0WD3JHQkm8c4c2KG3AO3mYWrn4xvg,569
|
|
1230
1230
|
angr/analyses/decompiler/__init__.py,sha256=eyxt2UKvPkbuS_l_1GPb0CJ6hrj2wTavh-mVf23wwiQ,1162
|
|
1231
|
-
angr/analyses/decompiler/clinic.py,sha256=
|
|
1231
|
+
angr/analyses/decompiler/clinic.py,sha256=pULhfkuDYNBT9o5nYWX9fl1sP0RiWBVCUhHDsmUeIPc,151320
|
|
1232
1232
|
angr/analyses/decompiler/decompilation_cache.py,sha256=06oiG299mVpGOTL54Xy1CUxz5s8QLgYJn5XIvKFLYkU,1566
|
|
1233
|
-
angr/analyses/decompiler/block_simplifier.py,sha256=
|
|
1233
|
+
angr/analyses/decompiler/block_simplifier.py,sha256=vjlugXCB3xFYBDBn3LPxOtU1dDc76PpYtVEoju3i9-4,15513
|
|
1234
1234
|
angr/analyses/decompiler/node_replacer.py,sha256=jJd3XkIwFE07bIbLriJ6_mQEvfhm90C8lqlrL5Mz1Xg,1450
|
|
1235
1235
|
angr/analyses/decompiler/decompilation_options.py,sha256=bs6CNpU3UxepgBB_9eUH4jriNpGoryyPP0sR1hDWpTk,8477
|
|
1236
1236
|
angr/analyses/decompiler/region_walker.py,sha256=u0hR0bEX1hSwkv-vejIM1gS-hcX2F2DLsDqpKhQ5_pQ,752
|
|
@@ -1245,7 +1245,7 @@ angr/analyses/decompiler/label_collector.py,sha256=fsCkldy8ZKH4FjkREByg-NDmfCd7P
|
|
|
1245
1245
|
angr/analyses/decompiler/jumptable_entry_condition_rewriter.py,sha256=f_JyNiSZfoudElfl2kIzONoYCiosR4xYFOe8Q5SkvLg,2176
|
|
1246
1246
|
angr/analyses/decompiler/structured_codegen/__init__.py,sha256=mxG4yruPAab8735wVgXZ1zu8qFPz-njKe0m5UcywE3o,633
|
|
1247
1247
|
angr/analyses/decompiler/structured_codegen/dwarf_import.py,sha256=J6V40RuIyKXN7r6ESftIYfoREgmgFavnUL5m3lyTzlM,7072
|
|
1248
|
-
angr/analyses/decompiler/structured_codegen/c.py,sha256=
|
|
1248
|
+
angr/analyses/decompiler/structured_codegen/c.py,sha256=sFizu2EWABRhv_yaBXd85rPhoRIEZNZ6zdLp5Q4XHa8,150180
|
|
1249
1249
|
angr/analyses/decompiler/structured_codegen/dummy.py,sha256=JZLeovXE-8C-unp2hbejxCG30l-yCx4sWFh7JMF_iRM,570
|
|
1250
1250
|
angr/analyses/decompiler/structured_codegen/base.py,sha256=mb5d5iQO1N2wMl7QySvfHemXM-e0yQBhjtlmnLsVSgE,5134
|
|
1251
1251
|
angr/analyses/decompiler/ssailification/rewriting.py,sha256=aIYuFGlroEXqxaf6lZCfodLD2B53Sb8UJgl2nNb4lg8,15076
|
|
@@ -1284,7 +1284,7 @@ angr/analyses/decompiler/region_simplifiers/cascading_ifs.py,sha256=kPWajH8__ap-
|
|
|
1284
1284
|
angr/analyses/decompiler/region_simplifiers/expr_folding.py,sha256=naCgnDUjdiDsh6dvoNO-VARfbTfaEYpu3EX9HkJ1cqE,31790
|
|
1285
1285
|
angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py,sha256=2Tb4zGnFA5hZH8oI6t1hoRstGDmOBsOoQxf6fU5Ct7A,1105
|
|
1286
1286
|
angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py,sha256=8gPWhFTcezgO7pZ_v0pxR7pweds4_GrrY82ur6Nrlf8,4796
|
|
1287
|
-
angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py,sha256=
|
|
1287
|
+
angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py,sha256=2A7NZIzZpDCq3i8e72l7c7KHfEwfJvzi5NffoXU_NNE,4559
|
|
1288
1288
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py,sha256=V5Vm1zUGjsauyOYXbUgDfZEgmChLbY8wnvmcRbfdMk0,1278
|
|
1289
1289
|
angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py,sha256=vLXt0ekjRep4SgaNq1wyxVkBTzOMTa03d3rgkjUOcUg,995
|
|
1290
1290
|
angr/analyses/decompiler/peephole_optimizations/bswap.py,sha256=fXV_a58W2X30KCanYeSHdZ2yPcfDlyZq_OkYNMkglrg,6420
|
|
@@ -1301,7 +1301,7 @@ angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py,sha256=5Gsq
|
|
|
1301
1301
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py,sha256=0R_ja5u2fO_BMSpfSk68sDMfhwpvBpyCBKahQh-SB4w,3997
|
|
1302
1302
|
angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py,sha256=YMfsqffIzsB7YslHVohBOeOWeNJydsrBowJ_6oD1QyY,1909
|
|
1303
1303
|
angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py,sha256=KRjv1VUMmzkmax_s1ZM3nz24iqz1wqInMgJn3NR9kd4,1788
|
|
1304
|
-
angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=
|
|
1304
|
+
angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=EbnjFKVoLce23AbmF-06EdW-TzAeoZjn_NHDkqNWATQ,5034
|
|
1305
1305
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py,sha256=1pbXLE65KwREUoB9GqCXBgz-BeUrzXxoIRFUYZAnBVA,1133
|
|
1306
1306
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py,sha256=NpjPio84lBFY76hPyvOWChRo1jgFEj9XKmSh_A3A-bg,1430
|
|
1307
1307
|
angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py,sha256=nhV4URuLjH_G-te15cJJ3O2-9VJvpOnkRJjdHSBRoko,1481
|
|
@@ -1327,9 +1327,10 @@ angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuctio
|
|
|
1327
1327
|
angr/analyses/decompiler/peephole_optimizations/rol_ror.py,sha256=hrtAJaWTZgphP6Wex50uz9vHIBeXy1ie5M5CBSruY7Y,5144
|
|
1328
1328
|
angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py,sha256=4fZUQGdEY2qVANb6xQWZJRf5N7X78R_gyECxzhC_5vU,2384
|
|
1329
1329
|
angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py,sha256=--C1JQluHt8ltdfUPBHvRD3SjW_ZcBU3oWdFwpCtpuw,1072
|
|
1330
|
-
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py,sha256=
|
|
1330
|
+
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py,sha256=rR3eC_pjCVBuc8GuWzJJkn6h8c964ODf-5uiwlncwVE,9896
|
|
1331
1331
|
angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py,sha256=fXq-qFe7JUdD5LdtUhoA9AF3LnY-3Jrmo4t3ZRJIIiQ,1414
|
|
1332
1332
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py,sha256=FUf1bg9nADlwT1upwTKcVhhPcvZ98C-8PlmkWoHqwZ4,4787
|
|
1333
|
+
angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy_consolidation.py,sha256=TsQEpHhyVr7MdiSFkijR6GFMHsuKlmmy9qvSCo32c2U,5409
|
|
1333
1334
|
angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py,sha256=pMdKsNJtAIPqyWsR8cUEyujdF7e7kbqqvVgelVmKtqY,1610
|
|
1334
1335
|
angr/analyses/decompiler/peephole_optimizations/optimized_div_simplifier.py,sha256=M4GxEWKs6V9aEYejGluZ8w8QpvPKpaESeFFzid88HjE,14208
|
|
1335
1336
|
angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py,sha256=HY6EQkThiyMaahz3bodJUqLBKWY2n4aKGbKyspMXN50,1641
|
|
@@ -1398,7 +1399,7 @@ angr/analyses/decompiler/presets/basic.py,sha256=sHT2oalBmINVSZfpEbx4LmK0G1zqbZm
|
|
|
1398
1399
|
angr/analyses/s_reaching_definitions/__init__.py,sha256=TyfVplxkJj8FAAAw9wegzJlcrbGwlFpIB23PdCcwrLA,254
|
|
1399
1400
|
angr/analyses/s_reaching_definitions/s_reaching_definitions.py,sha256=gNdg8xpu5by_McWU8j0g0502yQsO2evkTlben9yimV0,7826
|
|
1400
1401
|
angr/analyses/s_reaching_definitions/s_rda_model.py,sha256=FJSge_31FFzyzBJA1xm7dQz40TfuNna6v_RWAZMZvi0,5801
|
|
1401
|
-
angr/analyses/s_reaching_definitions/s_rda_view.py,sha256=
|
|
1402
|
+
angr/analyses/s_reaching_definitions/s_rda_view.py,sha256=7o-llkMUJP_ZhnQ4tkCDrzYok4cAOA7PLt2tX9DY8Mo,13929
|
|
1402
1403
|
angr/analyses/fcp/__init__.py,sha256=E9dxFckDM9DijfU4RRg9SGL6xDKCz7yBBP-XSkS-S9U,115
|
|
1403
1404
|
angr/analyses/fcp/fcp.py,sha256=djkJsvSja_De7ptNwllmTHjvVl62BFcH_haBhwhzFtw,16373
|
|
1404
1405
|
angr/analyses/flirt/flirt.py,sha256=UNXtUBs11WafKeMAW2BwqKJLFhOyObqmRhfCqYdsJpc,10762
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|