angr 9.2.121__py3-none-macosx_11_0_arm64.whl → 9.2.123__py3-none-macosx_11_0_arm64.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.py +6 -1
- angr/analyses/decompiler/ail_simplifier.py +22 -323
- angr/analyses/decompiler/callsite_maker.py +11 -1
- angr/analyses/decompiler/clinic.py +3 -2
- angr/analyses/decompiler/dephication/rewriting_engine.py +1 -1
- angr/analyses/decompiler/expression_narrower.py +201 -5
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +11 -7
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +10 -1
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +73 -42
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +4 -0
- angr/analyses/decompiler/sequence_walker.py +20 -4
- angr/analyses/s_propagator.py +10 -6
- angr/calling_conventions.py +2 -2
- angr/engines/light/engine.py +12 -2
- angr/engines/soot/expressions/instanceOf.py +4 -1
- angr/engines/successors.py +1 -1
- angr/engines/vex/heavy/concretizers.py +47 -47
- angr/engines/vex/heavy/dirty.py +4 -4
- angr/lib/angr_native.dylib +0 -0
- angr/procedures/java_lang/getsimplename.py +4 -1
- angr/procedures/linux_kernel/iovec.py +5 -2
- angr/sim_type.py +56 -19
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/METADATA +7 -6
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/RECORD +29 -29
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/LICENSE +0 -0
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/WHEEL +0 -0
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/entry_points.txt +0 -0
- {angr-9.2.121.dist-info → angr-9.2.123.dist-info}/top_level.txt +0 -0
angr/__init__.py
CHANGED
|
@@ -356,9 +356,12 @@ class CallingConventionAnalysis(Analysis):
|
|
|
356
356
|
caller_block_addr: int,
|
|
357
357
|
call_insn_addr: int,
|
|
358
358
|
include_preds: bool = False,
|
|
359
|
-
) -> CallSiteFact:
|
|
359
|
+
) -> CallSiteFact | None:
|
|
360
360
|
func = self.kb.functions[caller_addr]
|
|
361
361
|
subgraph = self._generate_callsite_subgraph(func, caller_block_addr, include_preds=include_preds)
|
|
362
|
+
if subgraph is None:
|
|
363
|
+
# failed to generate a subgraph when the caller block cannot be found in the function graph
|
|
364
|
+
return None
|
|
362
365
|
|
|
363
366
|
observation_points: list = [("insn", call_insn_addr, OP_BEFORE), ("node", caller_block_addr, OP_AFTER)]
|
|
364
367
|
|
|
@@ -440,6 +443,8 @@ class CallingConventionAnalysis(Analysis):
|
|
|
440
443
|
call_insn_addr,
|
|
441
444
|
include_preds=include_callsite_preds,
|
|
442
445
|
)
|
|
446
|
+
if fact is None:
|
|
447
|
+
continue
|
|
443
448
|
facts.append(fact)
|
|
444
449
|
|
|
445
450
|
ctr += 1
|
|
@@ -22,7 +22,6 @@ from ailment.expression import (
|
|
|
22
22
|
Const,
|
|
23
23
|
BinaryOp,
|
|
24
24
|
VirtualVariable,
|
|
25
|
-
Phi,
|
|
26
25
|
)
|
|
27
26
|
|
|
28
27
|
from angr.analyses.s_reaching_definitions import SRDAModel
|
|
@@ -36,7 +35,7 @@ from angr.knowledge_plugins.key_definitions.constants import OP_BEFORE
|
|
|
36
35
|
from angr.errors import AngrRuntimeError
|
|
37
36
|
from angr.analyses import Analysis, AnalysesHub
|
|
38
37
|
from .ailgraph_walker import AILGraphWalker
|
|
39
|
-
from .expression_narrower import
|
|
38
|
+
from .expression_narrower import ExprNarrowingInfo, NarrowingInfoExtractor, ExpressionNarrower
|
|
40
39
|
from .block_simplifier import BlockSimplifier
|
|
41
40
|
from .ccall_rewriters import CCALL_REWRITERS
|
|
42
41
|
from .counters.expression_counters import SingleExpressionCounter
|
|
@@ -76,26 +75,6 @@ class AILBlockTempCollector(AILBlockWalker):
|
|
|
76
75
|
self.temps.add(expr)
|
|
77
76
|
|
|
78
77
|
|
|
79
|
-
class ExprNarrowingInfo:
|
|
80
|
-
"""
|
|
81
|
-
Stores the analysis result of _narrowing_needed().
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
__slots__ = ("narrowable", "to_size", "use_exprs", "phi_vars")
|
|
85
|
-
|
|
86
|
-
def __init__(
|
|
87
|
-
self,
|
|
88
|
-
narrowable: bool,
|
|
89
|
-
to_size: int | None = None,
|
|
90
|
-
use_exprs: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] | None = None,
|
|
91
|
-
phi_vars: set[atoms.VirtualVariable] | None = None,
|
|
92
|
-
):
|
|
93
|
-
self.narrowable = narrowable
|
|
94
|
-
self.to_size = to_size
|
|
95
|
-
self.use_exprs = use_exprs
|
|
96
|
-
self.phi_vars = phi_vars
|
|
97
|
-
|
|
98
|
-
|
|
99
78
|
class AILSimplifier(Analysis):
|
|
100
79
|
"""
|
|
101
80
|
Perform function-level simplifications.
|
|
@@ -343,309 +322,26 @@ class AILSimplifier(Analysis):
|
|
|
343
322
|
if not repeat:
|
|
344
323
|
break
|
|
345
324
|
|
|
346
|
-
replaced_vvar_ids = set()
|
|
347
|
-
|
|
348
325
|
# let's narrow them (finally)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if use_type == "binop-convert" and self._exprs_contain_vvar(use_expr_tpl, replaced_vvar_ids):
|
|
356
|
-
should_skip = True
|
|
357
|
-
break
|
|
358
|
-
if should_skip:
|
|
359
|
-
continue
|
|
360
|
-
|
|
361
|
-
# replace the definition
|
|
362
|
-
if not isinstance(def_.codeloc, ExternalCodeLocation):
|
|
363
|
-
old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx))
|
|
364
|
-
if old_block is None:
|
|
365
|
-
# this definition might be inside a callee function, which is why the block does not exist
|
|
366
|
-
# ignore it
|
|
367
|
-
continue
|
|
368
|
-
|
|
369
|
-
the_block = self.blocks.get(old_block, old_block)
|
|
370
|
-
stmt = the_block.statements[def_.codeloc.stmt_idx]
|
|
371
|
-
r, new_block = False, None
|
|
372
|
-
replaced_vvar: VirtualVariable | None = None
|
|
373
|
-
if is_phi_assignment(stmt):
|
|
374
|
-
new_assignment_dst = VirtualVariable(
|
|
375
|
-
stmt.dst.idx,
|
|
376
|
-
stmt.dst.varid,
|
|
377
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
378
|
-
category=def_.atom.category,
|
|
379
|
-
oident=def_.atom.oident,
|
|
380
|
-
**stmt.dst.tags,
|
|
381
|
-
)
|
|
382
|
-
new_src_and_vvars = []
|
|
383
|
-
for src, vvar in stmt.src.src_and_vvars:
|
|
384
|
-
if vvar is not None and vvar.varid == stmt.dst.varid:
|
|
385
|
-
new_vvar = VirtualVariable(
|
|
386
|
-
vvar.idx,
|
|
387
|
-
vvar.varid,
|
|
388
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
389
|
-
category=vvar.category,
|
|
390
|
-
oident=vvar.oident,
|
|
391
|
-
**vvar.tags,
|
|
392
|
-
)
|
|
393
|
-
else:
|
|
394
|
-
new_vvar = vvar
|
|
395
|
-
new_src_and_vvars.append((src, new_vvar))
|
|
396
|
-
new_assignment_src = Phi(
|
|
397
|
-
stmt.src.idx,
|
|
398
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
399
|
-
new_src_and_vvars,
|
|
400
|
-
**stmt.src.tags,
|
|
401
|
-
)
|
|
402
|
-
replaced_vvar = stmt.dst
|
|
403
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
404
|
-
the_block,
|
|
405
|
-
{
|
|
406
|
-
def_.codeloc: {
|
|
407
|
-
stmt.dst: new_assignment_dst,
|
|
408
|
-
stmt.src: new_assignment_src,
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
replace_assignment_dsts=True,
|
|
412
|
-
replace_loads=True,
|
|
413
|
-
)
|
|
414
|
-
elif isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable) and stmt.dst.was_reg:
|
|
415
|
-
new_assignment_dst = VirtualVariable(
|
|
416
|
-
stmt.dst.idx,
|
|
417
|
-
stmt.dst.varid,
|
|
418
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
419
|
-
category=def_.atom.category,
|
|
420
|
-
oident=def_.atom.oident,
|
|
421
|
-
**stmt.dst.tags,
|
|
422
|
-
)
|
|
423
|
-
new_assignment_src = Convert(
|
|
424
|
-
stmt.src.idx, # FIXME: This is a hack
|
|
425
|
-
stmt.src.bits,
|
|
426
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
427
|
-
False,
|
|
428
|
-
stmt.src,
|
|
429
|
-
**stmt.src.tags,
|
|
430
|
-
)
|
|
431
|
-
replaced_vvar = stmt.dst
|
|
432
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
433
|
-
the_block,
|
|
434
|
-
{
|
|
435
|
-
def_.codeloc: {
|
|
436
|
-
stmt.dst: new_assignment_dst,
|
|
437
|
-
stmt.src: new_assignment_src,
|
|
438
|
-
}
|
|
439
|
-
},
|
|
440
|
-
replace_assignment_dsts=True,
|
|
441
|
-
replace_loads=True,
|
|
442
|
-
)
|
|
443
|
-
elif isinstance(stmt, Call):
|
|
444
|
-
if stmt.ret_expr is not None:
|
|
445
|
-
tags = dict(stmt.ret_expr.tags)
|
|
446
|
-
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
447
|
-
def_.atom.reg_offset, size=narrow_info.to_size
|
|
448
|
-
)
|
|
449
|
-
replaced_vvar = stmt.ret_expr
|
|
450
|
-
new_retexpr = VirtualVariable(
|
|
451
|
-
stmt.ret_expr.idx,
|
|
452
|
-
stmt.ret_expr.varid,
|
|
453
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
454
|
-
category=def_.atom.category,
|
|
455
|
-
oident=def_.atom.oident,
|
|
456
|
-
**stmt.ret_expr.tags,
|
|
457
|
-
)
|
|
458
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
459
|
-
the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
|
|
460
|
-
)
|
|
461
|
-
if not r:
|
|
462
|
-
# couldn't replace the definition...
|
|
463
|
-
continue
|
|
326
|
+
narrower = ExpressionNarrower(self.project, rd, narrowables, addr_and_idx_to_block, self.blocks)
|
|
327
|
+
for old_block in addr_and_idx_to_block.values():
|
|
328
|
+
new_block = self.blocks.get(old_block, old_block)
|
|
329
|
+
new_block = narrower.walk(new_block)
|
|
330
|
+
if narrower.narrowed_any:
|
|
331
|
+
narrowed = True
|
|
464
332
|
self.blocks[old_block] = new_block
|
|
465
|
-
if replaced_vvar is not None:
|
|
466
|
-
replaced_vvar_ids.add(replaced_vvar.varid)
|
|
467
|
-
|
|
468
|
-
use_exprs = list(narrow_info.use_exprs)
|
|
469
|
-
if narrow_info.phi_vars:
|
|
470
|
-
for phi_var in narrow_info.phi_vars:
|
|
471
|
-
loc = rd.all_vvar_definitions[phi_var]
|
|
472
|
-
old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx))
|
|
473
|
-
the_block = self.blocks.get(old_block, old_block)
|
|
474
|
-
stmt = the_block.statements[loc.stmt_idx]
|
|
475
|
-
assert is_phi_assignment(stmt)
|
|
476
|
-
|
|
477
|
-
for _, vvar in stmt.src.src_and_vvars:
|
|
478
|
-
if vvar is not None and vvar.varid == def_.atom.varid:
|
|
479
|
-
use_exprs.append((vvar, loc, ("phi-src-expr", (vvar,))))
|
|
480
|
-
|
|
481
|
-
# replace all uses if necessary
|
|
482
|
-
for use_atom, use_loc, (use_type, use_expr_tpl) in use_exprs:
|
|
483
|
-
if (
|
|
484
|
-
isinstance(use_expr_tpl[0], VirtualVariable)
|
|
485
|
-
and use_expr_tpl[0].was_reg
|
|
486
|
-
and narrow_info.to_size == use_expr_tpl[0].size
|
|
487
|
-
):
|
|
488
|
-
# don't replace registers to the same registers
|
|
489
|
-
continue
|
|
490
|
-
if use_atom.varid != def_.atom.varid:
|
|
491
|
-
# don't replace this use - it will be replaced later
|
|
492
|
-
continue
|
|
493
|
-
|
|
494
|
-
old_block = addr_and_idx_to_block.get((use_loc.block_addr, use_loc.block_idx))
|
|
495
|
-
the_block = self.blocks.get(old_block, old_block)
|
|
496
333
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
new_use_expr = new_use_expr_0
|
|
509
|
-
|
|
510
|
-
# the second used expr (if it exists)
|
|
511
|
-
if len(use_expr_tpl) == 2:
|
|
512
|
-
use_expr_1 = use_expr_tpl[1]
|
|
513
|
-
assert isinstance(use_expr_1, BinaryOp)
|
|
514
|
-
con = use_expr_1.operands[1]
|
|
515
|
-
assert isinstance(con, Const)
|
|
516
|
-
new_use_expr_1 = BinaryOp(
|
|
517
|
-
use_expr_1.idx,
|
|
518
|
-
use_expr_1.op,
|
|
519
|
-
[
|
|
520
|
-
new_use_expr_0,
|
|
521
|
-
Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
|
|
522
|
-
],
|
|
523
|
-
use_expr_1.signed,
|
|
524
|
-
floating_point=use_expr_1.floating_point,
|
|
525
|
-
rounding_mode=use_expr_1.rounding_mode,
|
|
526
|
-
**use_expr_1.tags,
|
|
527
|
-
)
|
|
528
|
-
|
|
529
|
-
if use_expr_1.size > new_use_expr_1.size:
|
|
530
|
-
new_use_expr_1 = Convert(
|
|
531
|
-
None,
|
|
532
|
-
new_use_expr_1.bits,
|
|
533
|
-
use_expr_1.bits,
|
|
534
|
-
False,
|
|
535
|
-
new_use_expr_1,
|
|
536
|
-
**new_use_expr_1.tags,
|
|
537
|
-
)
|
|
538
|
-
|
|
539
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
540
|
-
the_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
541
|
-
)
|
|
542
|
-
elif len(use_expr_tpl) == 1:
|
|
543
|
-
if use_expr_0.size > new_use_expr_0.size:
|
|
544
|
-
new_use_expr_0 = Convert(
|
|
545
|
-
None,
|
|
546
|
-
new_use_expr_0.bits,
|
|
547
|
-
use_expr_0.bits,
|
|
548
|
-
False,
|
|
549
|
-
new_use_expr_0,
|
|
550
|
-
**new_use_expr_0.tags,
|
|
551
|
-
)
|
|
552
|
-
|
|
553
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
554
|
-
the_block, {use_loc: {use_expr_0: new_use_expr_0}}
|
|
555
|
-
)
|
|
556
|
-
else:
|
|
557
|
-
_l.warning("Nothing to replace at %s.", use_loc)
|
|
558
|
-
r = False
|
|
559
|
-
new_block = None
|
|
560
|
-
|
|
561
|
-
elif use_type == "phi-src-expr":
|
|
562
|
-
# the size of the replaced variable will be different from its original size, and it's expected
|
|
563
|
-
use_expr = use_expr_tpl[0]
|
|
564
|
-
new_use_expr = VirtualVariable(
|
|
565
|
-
use_expr.idx,
|
|
566
|
-
def_.atom.varid,
|
|
567
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
568
|
-
category=def_.atom.category,
|
|
569
|
-
oident=def_.atom.oident,
|
|
570
|
-
**use_expr.tags,
|
|
571
|
-
)
|
|
572
|
-
r, new_block = BlockSimplifier._replace_and_build(the_block, {use_loc: {use_expr: new_use_expr}})
|
|
573
|
-
|
|
574
|
-
elif use_type == "binop-convert":
|
|
575
|
-
use_expr_0 = use_expr_tpl[0]
|
|
576
|
-
new_use_expr_0 = VirtualVariable(
|
|
577
|
-
use_expr_0.idx,
|
|
578
|
-
def_.atom.varid,
|
|
579
|
-
narrow_info.to_size * self.project.arch.byte_width,
|
|
580
|
-
category=def_.atom.category,
|
|
581
|
-
oident=def_.atom.oident,
|
|
582
|
-
**use_expr_0.tags,
|
|
583
|
-
)
|
|
584
|
-
new_use_expr = new_use_expr_0
|
|
585
|
-
|
|
586
|
-
use_expr_1: BinaryOp = use_expr_tpl[1]
|
|
587
|
-
# build the new use_expr_1
|
|
588
|
-
new_use_expr_1_operands = {}
|
|
589
|
-
if use_expr_1.operands[0] is use_expr_0:
|
|
590
|
-
new_use_expr_1_operands[0] = new_use_expr_0
|
|
591
|
-
other_operand = use_expr_1.operands[1]
|
|
592
|
-
else:
|
|
593
|
-
new_use_expr_1_operands[1] = new_use_expr_0
|
|
594
|
-
other_operand = use_expr_1.operands[0]
|
|
595
|
-
use_expr_2: Convert = use_expr_tpl[2]
|
|
596
|
-
if other_operand.bits == use_expr_2.from_bits:
|
|
597
|
-
new_other_operand = Convert(
|
|
598
|
-
None, use_expr_2.from_bits, use_expr_2.to_bits, False, other_operand
|
|
599
|
-
)
|
|
600
|
-
else:
|
|
601
|
-
# Some operations, like Sar and Shl, have operands with different sizes
|
|
602
|
-
new_other_operand = other_operand
|
|
603
|
-
|
|
604
|
-
if 0 in new_use_expr_1_operands:
|
|
605
|
-
new_use_expr_1_operands[1] = new_other_operand
|
|
606
|
-
else:
|
|
607
|
-
new_use_expr_1_operands[0] = new_other_operand
|
|
608
|
-
|
|
609
|
-
# build new use_expr_1
|
|
610
|
-
new_use_expr_1 = BinaryOp(
|
|
611
|
-
use_expr_1.idx,
|
|
612
|
-
use_expr_1.op,
|
|
613
|
-
[new_use_expr_1_operands[0], new_use_expr_1_operands[1]],
|
|
614
|
-
use_expr_1.signed,
|
|
615
|
-
bits=narrow_info.to_size * 8,
|
|
616
|
-
floating_point=use_expr_1.floating_point,
|
|
617
|
-
rounding_mode=use_expr_1.rounding_mode,
|
|
618
|
-
**use_expr_1.tags,
|
|
619
|
-
)
|
|
620
|
-
|
|
621
|
-
# first remove the old conversion
|
|
622
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
623
|
-
the_block, {use_loc: {use_expr_2: use_expr_2.operand}}
|
|
624
|
-
)
|
|
625
|
-
# then replace use_expr_1
|
|
626
|
-
if r:
|
|
627
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
628
|
-
new_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
629
|
-
)
|
|
630
|
-
else:
|
|
631
|
-
raise TypeError(f'Unsupported use_type value "{use_type}"')
|
|
632
|
-
|
|
633
|
-
if not r:
|
|
634
|
-
_l.warning("Failed to replace use-expr at %s.", use_loc)
|
|
635
|
-
else:
|
|
636
|
-
# update self._arg_vvars if necessary
|
|
637
|
-
if new_use_expr is not None and new_use_expr.was_parameter and self._arg_vvars:
|
|
638
|
-
for func_arg_idx in list(self._arg_vvars):
|
|
639
|
-
vvar, simvar = self._arg_vvars[func_arg_idx]
|
|
640
|
-
if vvar.varid == new_use_expr.varid:
|
|
641
|
-
simvar_new = simvar.copy()
|
|
642
|
-
simvar_new._hash = None
|
|
643
|
-
simvar_new.size = new_use_expr.size
|
|
644
|
-
self._arg_vvars[func_arg_idx] = new_use_expr, simvar_new
|
|
645
|
-
|
|
646
|
-
self.blocks[old_block] = new_block
|
|
647
|
-
|
|
648
|
-
narrowed = True
|
|
334
|
+
# update self._arg_vvars if necessary
|
|
335
|
+
for new_vvars in narrower.replacement_core_vvars.values():
|
|
336
|
+
for new_vvar in new_vvars:
|
|
337
|
+
if new_vvar.was_parameter and self._arg_vvars:
|
|
338
|
+
for func_arg_idx in list(self._arg_vvars):
|
|
339
|
+
vvar, simvar = self._arg_vvars[func_arg_idx]
|
|
340
|
+
if vvar.varid == new_vvar.varid:
|
|
341
|
+
simvar_new = simvar.copy()
|
|
342
|
+
simvar_new._hash = None
|
|
343
|
+
simvar_new.size = new_vvar.size
|
|
344
|
+
self._arg_vvars[func_arg_idx] = new_vvar, simvar_new
|
|
649
345
|
|
|
650
346
|
return narrowed
|
|
651
347
|
|
|
@@ -669,6 +365,9 @@ class AILSimplifier(Analysis):
|
|
|
669
365
|
if len(narrowing_sizes) == 1 and None not in narrowing_sizes:
|
|
670
366
|
# we can narrow this phi vvar!
|
|
671
367
|
narrowable_phivarids.add(def_vvarid)
|
|
368
|
+
else:
|
|
369
|
+
# blacklist it for now
|
|
370
|
+
blacklist_varids.add(def_vvarid)
|
|
672
371
|
|
|
673
372
|
# now determine what to narrow!
|
|
674
373
|
narrowables = []
|
|
@@ -834,7 +533,7 @@ class AILSimplifier(Analysis):
|
|
|
834
533
|
Determine the effective size of an expression when it's used.
|
|
835
534
|
"""
|
|
836
535
|
|
|
837
|
-
walker =
|
|
536
|
+
walker = NarrowingInfoExtractor(expr)
|
|
838
537
|
walker.walk_statement(statement)
|
|
839
538
|
if not walker.operations:
|
|
840
539
|
if expr is None:
|
|
@@ -8,7 +8,7 @@ from ailment import Stmt, Expr, Const
|
|
|
8
8
|
|
|
9
9
|
from angr.procedures.stubs.format_parser import FormatParser, FormatSpecifier
|
|
10
10
|
from angr.sim_type import SimTypeBottom, SimTypePointer, SimTypeChar, SimTypeInt, dereference_simtype
|
|
11
|
-
from angr.calling_conventions import SimRegArg, SimStackArg, SimCC, SimStructArg
|
|
11
|
+
from angr.calling_conventions import SimRegArg, SimStackArg, SimCC, SimStructArg, SimComboArg
|
|
12
12
|
from angr.knowledge_plugins.key_definitions.constants import OP_BEFORE
|
|
13
13
|
from angr.analyses import Analysis, register_analysis
|
|
14
14
|
from angr.analyses.s_reaching_definitions import SRDAView
|
|
@@ -129,7 +129,17 @@ class CallSiteMaker(Analysis):
|
|
|
129
129
|
arg_locs = cc.arg_locs(callsite_ty)
|
|
130
130
|
|
|
131
131
|
if arg_locs is not None:
|
|
132
|
+
expanded_arg_locs = []
|
|
132
133
|
for arg_loc in arg_locs:
|
|
134
|
+
if isinstance(arg_loc, SimComboArg):
|
|
135
|
+
# a ComboArg spans across multiple locations (mostly stack but *in theory* can also be spanning
|
|
136
|
+
# across registers). most importantly, a ComboArg represents one variable, not multiple, but we
|
|
137
|
+
# have no way to know that until later down the pipeline.
|
|
138
|
+
expanded_arg_locs += arg_loc.locations
|
|
139
|
+
else:
|
|
140
|
+
expanded_arg_locs.append(arg_loc)
|
|
141
|
+
|
|
142
|
+
for arg_loc in expanded_arg_locs:
|
|
133
143
|
if isinstance(arg_loc, SimRegArg):
|
|
134
144
|
size = arg_loc.size
|
|
135
145
|
offset = arg_loc.check_offset(cc.arch)
|
|
@@ -749,8 +749,9 @@ class Clinic(Analysis):
|
|
|
749
749
|
continue
|
|
750
750
|
|
|
751
751
|
call_sites = []
|
|
752
|
-
for pred in self.function.transition_graph.
|
|
753
|
-
|
|
752
|
+
for pred, _, data in self.function.transition_graph.in_edges(node, data=True):
|
|
753
|
+
if data.get("type", None) != "return":
|
|
754
|
+
call_sites.append(pred)
|
|
754
755
|
# case 1: calling conventions and prototypes are available at every single call site
|
|
755
756
|
if call_sites and all(self.kb.callsite_prototypes.has_prototype(callsite.addr) for callsite in call_sites):
|
|
756
757
|
continue
|
|
@@ -126,7 +126,7 @@ class SimEngineDephiRewriting(
|
|
|
126
126
|
return None
|
|
127
127
|
|
|
128
128
|
def _handle_Call(self, stmt: Call) -> Call | None:
|
|
129
|
-
new_target = self._expr(stmt.target) if stmt.target is not None else None
|
|
129
|
+
new_target = self._expr(stmt.target) if stmt.target is not None and not isinstance(stmt.target, str) else None
|
|
130
130
|
new_ret_expr = self._expr(stmt.ret_expr) if stmt.ret_expr is not None else None
|
|
131
131
|
new_fp_ret_expr = self._expr(stmt.fp_ret_expr) if stmt.fp_ret_expr is not None else None
|
|
132
132
|
|