angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.133__py3-none-manylinux2014_aarch64.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 +128 -128
- angr/analyses/__init__.py +38 -38
- angr/analyses/analysis.py +6 -2
- angr/analyses/backward_slice.py +3 -4
- angr/analyses/binary_optimizer.py +5 -12
- angr/analyses/bindiff.py +3 -6
- angr/analyses/calling_convention.py +3 -4
- angr/analyses/cfg/__init__.py +3 -3
- angr/analyses/cfg/cfg_base.py +1 -1
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +19 -17
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +148 -101
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/data_dep/__init__.py +4 -4
- angr/analyses/datagraph_meta.py +1 -1
- angr/analyses/ddg.py +16 -17
- angr/analyses/decompiler/__init__.py +12 -12
- angr/analyses/decompiler/ail_simplifier.py +24 -12
- angr/analyses/decompiler/block_similarity.py +2 -4
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/callsite_maker.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
- angr/analyses/decompiler/clinic.py +122 -41
- angr/analyses/decompiler/condition_processor.py +57 -39
- angr/analyses/decompiler/counters/__init__.py +3 -3
- angr/analyses/decompiler/decompilation_cache.py +7 -7
- angr/analyses/decompiler/dephication/__init__.py +1 -1
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/expression_narrower.py +1 -1
- angr/analyses/decompiler/graph_region.py +8 -8
- angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
- angr/analyses/decompiler/optimization_passes/engine_base.py +262 -84
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +175 -39
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +12 -3
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +42 -19
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
- angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
- angr/analyses/decompiler/presets/__init__.py +1 -1
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +139 -56
- angr/analyses/decompiler/ssailification/ssailification.py +2 -1
- angr/analyses/decompiler/ssailification/traversal.py +4 -6
- angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
- angr/analyses/decompiler/structured_codegen/__init__.py +5 -5
- angr/analyses/decompiler/structured_codegen/base.py +3 -3
- angr/analyses/decompiler/structured_codegen/c.py +39 -40
- angr/analyses/decompiler/structuring/__init__.py +3 -3
- angr/analyses/decompiler/structuring/phoenix.py +45 -29
- angr/analyses/decompiler/structuring/structurer_base.py +2 -2
- angr/analyses/decompiler/structuring/structurer_nodes.py +23 -14
- angr/analyses/deobfuscator/__init__.py +3 -3
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
- angr/analyses/disassembly.py +4 -4
- angr/analyses/forward_analysis/__init__.py +1 -1
- angr/analyses/forward_analysis/visitors/graph.py +6 -6
- angr/analyses/init_finder.py +47 -22
- angr/analyses/loop_analysis.py +1 -1
- angr/analyses/loopfinder.py +1 -1
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/outdated_definition_walker.py +12 -6
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +4 -4
- angr/analyses/reaching_definitions/__init__.py +9 -9
- angr/analyses/reaching_definitions/call_trace.py +2 -2
- angr/analyses/reaching_definitions/dep_graph.py +1 -1
- angr/analyses/reaching_definitions/engine_ail.py +304 -329
- angr/analyses/reaching_definitions/engine_vex.py +243 -229
- angr/analyses/reaching_definitions/function_handler.py +3 -3
- angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -1
- angr/analyses/reaching_definitions/rd_state.py +47 -42
- angr/analyses/reassembler.py +26 -31
- angr/analyses/s_liveness.py +8 -0
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/stack_pointer_tracker.py +4 -4
- angr/analyses/typehoon/simple_solver.py +14 -14
- angr/analyses/typehoon/translator.py +10 -2
- angr/analyses/typehoon/typeconsts.py +11 -3
- angr/analyses/typehoon/typevars.py +26 -26
- angr/analyses/unpacker/__init__.py +1 -1
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +138 -121
- angr/analyses/variable_recovery/engine_vex.py +175 -185
- angr/analyses/variable_recovery/irsb_scanner.py +49 -38
- angr/analyses/variable_recovery/variable_recovery.py +28 -5
- angr/analyses/variable_recovery/variable_recovery_base.py +33 -34
- angr/analyses/variable_recovery/variable_recovery_fast.py +4 -8
- angr/analyses/veritesting.py +2 -2
- angr/analyses/vfg.py +5 -5
- angr/analyses/xrefs.py +46 -19
- angr/angrdb/serializers/__init__.py +1 -1
- angr/annocfg.py +20 -15
- angr/blade.py +2 -2
- angr/block.py +20 -25
- angr/calling_conventions.py +12 -14
- angr/code_location.py +6 -10
- angr/codenode.py +3 -3
- angr/engines/__init__.py +12 -14
- angr/engines/engine.py +24 -61
- angr/engines/light/__init__.py +13 -5
- angr/engines/light/data.py +1 -1
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/__init__.py +1 -1
- angr/engines/pcode/behavior.py +1 -1
- angr/engines/pcode/cc.py +2 -0
- angr/engines/pcode/lifter.py +13 -15
- angr/engines/soot/expressions/__init__.py +12 -12
- angr/engines/soot/statements/__init__.py +6 -6
- angr/engines/soot/values/__init__.py +6 -6
- angr/engines/soot/values/arrayref.py +2 -2
- angr/engines/soot/values/constants.py +1 -1
- angr/engines/soot/values/instancefieldref.py +1 -1
- angr/engines/soot/values/paramref.py +1 -1
- angr/engines/soot/values/staticfieldref.py +1 -1
- angr/engines/successors.py +15 -14
- angr/engines/vex/__init__.py +5 -5
- angr/engines/vex/claripy/ccall.py +2 -2
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +19 -19
- angr/engines/vex/heavy/__init__.py +2 -2
- angr/engines/vex/heavy/actions.py +1 -3
- angr/engines/vex/heavy/heavy.py +4 -6
- angr/engines/vex/lifter.py +2 -4
- angr/engines/vex/light/light.py +0 -2
- angr/engines/vex/light/slicing.py +5 -5
- angr/exploration_techniques/__init__.py +19 -142
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +1 -1
- angr/exploration_techniques/dfs.py +3 -1
- angr/exploration_techniques/director.py +2 -3
- angr/exploration_techniques/driller_core.py +1 -1
- angr/exploration_techniques/explorer.py +4 -2
- angr/exploration_techniques/lengthlimiter.py +2 -1
- angr/exploration_techniques/local_loop_seer.py +2 -1
- angr/exploration_techniques/loop_seer.py +5 -5
- angr/exploration_techniques/manual_mergepoint.py +2 -1
- angr/exploration_techniques/memory_watcher.py +3 -1
- angr/exploration_techniques/oppologist.py +4 -5
- angr/exploration_techniques/slicecutor.py +4 -2
- angr/exploration_techniques/spiller.py +1 -1
- angr/exploration_techniques/stochastic.py +2 -1
- angr/exploration_techniques/stub_stasher.py +2 -1
- angr/exploration_techniques/suggestions.py +3 -1
- angr/exploration_techniques/symbion.py +3 -1
- angr/exploration_techniques/tech_builder.py +2 -1
- angr/exploration_techniques/threading.py +2 -11
- angr/exploration_techniques/timeout.py +4 -2
- angr/exploration_techniques/tracer.py +4 -3
- angr/exploration_techniques/unique.py +3 -2
- angr/exploration_techniques/veritesting.py +1 -1
- angr/factory.py +36 -6
- angr/keyed_region.py +4 -4
- angr/knowledge_base.py +1 -1
- angr/knowledge_plugins/__init__.py +11 -11
- angr/knowledge_plugins/cfg/__init__.py +5 -5
- angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
- angr/knowledge_plugins/cfg/cfg_model.py +8 -8
- angr/knowledge_plugins/cfg/cfg_node.py +19 -19
- angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
- angr/knowledge_plugins/cfg/memory_data.py +5 -7
- angr/knowledge_plugins/functions/function.py +48 -52
- angr/knowledge_plugins/functions/function_parser.py +4 -4
- angr/knowledge_plugins/key_definitions/__init__.py +3 -3
- angr/knowledge_plugins/key_definitions/atoms.py +8 -8
- angr/knowledge_plugins/key_definitions/definition.py +1 -1
- angr/knowledge_plugins/key_definitions/live_definitions.py +30 -27
- angr/knowledge_plugins/labels.py +1 -1
- angr/knowledge_plugins/propagations/__init__.py +1 -1
- angr/knowledge_plugins/propagations/prop_value.py +2 -2
- angr/knowledge_plugins/propagations/propagation_model.py +7 -8
- angr/knowledge_plugins/propagations/states.py +44 -39
- angr/knowledge_plugins/variables/variable_access.py +2 -2
- angr/knowledge_plugins/variables/variable_manager.py +24 -10
- angr/knowledge_plugins/xrefs/xref.py +5 -8
- angr/misc/__init__.py +4 -4
- angr/misc/hookset.py +4 -5
- angr/misc/loggers.py +2 -2
- angr/misc/telemetry.py +1 -1
- angr/procedures/__init__.py +1 -1
- angr/procedures/cgc/fdwait.py +2 -2
- angr/procedures/definitions/__init__.py +2 -2
- angr/procedures/definitions/linux_kernel.py +0 -1
- angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
- angr/procedures/definitions/parse_win32json.py +0 -1
- angr/procedures/ntdll/exceptions.py +1 -1
- angr/procedures/stubs/format_parser.py +3 -3
- angr/procedures/win32/dynamic_loading.py +1 -1
- angr/protos/__init__.py +3 -3
- angr/sim_manager.py +3 -5
- angr/sim_state.py +40 -42
- angr/sim_state_options.py +3 -3
- angr/sim_type.py +15 -14
- angr/sim_variable.py +42 -45
- angr/simos/__init__.py +4 -4
- angr/simos/cgc.py +1 -1
- angr/simos/simos.py +1 -1
- angr/simos/userland.py +1 -1
- angr/slicer.py +4 -7
- angr/state_plugins/__init__.py +34 -34
- angr/state_plugins/callstack.py +5 -12
- angr/state_plugins/heap/__init__.py +2 -2
- angr/state_plugins/heap/heap_brk.py +2 -4
- angr/state_plugins/heap/heap_ptmalloc.py +1 -1
- angr/state_plugins/jni_references.py +3 -2
- angr/state_plugins/scratch.py +1 -1
- angr/state_plugins/sim_action.py +1 -4
- angr/state_plugins/sim_event.py +1 -1
- angr/state_plugins/solver.py +7 -9
- angr/state_plugins/uc_manager.py +1 -1
- angr/state_plugins/view.py +2 -2
- angr/storage/__init__.py +1 -1
- angr/storage/file.py +10 -10
- angr/storage/memory_mixins/__init__.py +46 -46
- angr/storage/memory_mixins/default_filler_mixin.py +1 -3
- angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
- angr/storage/memory_mixins/name_resolution_mixin.py +2 -2
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
- angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
- angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
- angr/storage/memory_object.py +4 -4
- angr/utils/__init__.py +3 -3
- angr/utils/bits.py +12 -0
- angr/utils/dynamic_dictlist.py +1 -1
- angr/utils/graph.py +1 -1
- angr/utils/orderedset.py +4 -1
- angr/utils/segment_list.py +2 -2
- angr/utils/ssa/__init__.py +33 -8
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/RECORD +262 -263
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/entry_points.txt +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# pylint:disable=too-many-boolean-expressions
|
|
1
2
|
from __future__ import annotations
|
|
2
3
|
from typing import Any, NamedTuple, TYPE_CHECKING
|
|
3
4
|
import copy
|
|
@@ -12,6 +13,7 @@ import capstone
|
|
|
12
13
|
|
|
13
14
|
import ailment
|
|
14
15
|
|
|
16
|
+
from angr.analyses.decompiler.ssailification.ssailification import Ssailification
|
|
15
17
|
from angr.errors import AngrDecompilationError
|
|
16
18
|
from angr.knowledge_base import KnowledgeBase
|
|
17
19
|
from angr.knowledge_plugins.functions import Function
|
|
@@ -268,6 +270,7 @@ class Clinic(Analysis):
|
|
|
268
270
|
def _decompilation_fixups(self, ail_graph):
|
|
269
271
|
is_pcode_arch = ":" in self.project.arch.name
|
|
270
272
|
|
|
273
|
+
self._remove_redundant_jump_blocks(ail_graph)
|
|
271
274
|
# _fix_abnormal_switch_case_heads may re-lift from VEX blocks, so it should be placed as high up as possible
|
|
272
275
|
self._fix_abnormal_switch_case_heads(ail_graph)
|
|
273
276
|
if self._rewrite_ites_to_diamonds:
|
|
@@ -597,7 +600,7 @@ class Clinic(Analysis):
|
|
|
597
600
|
arg_list.append(arg_vvars[idx][1])
|
|
598
601
|
|
|
599
602
|
# Get virtual variable mapping that can de-phi the SSA representation
|
|
600
|
-
vvar2vvar = self._collect_dephi_vvar_mapping_and_rewrite_blocks(ail_graph)
|
|
603
|
+
vvar2vvar, copied_vvar_ids = self._collect_dephi_vvar_mapping_and_rewrite_blocks(ail_graph, arg_vvars)
|
|
601
604
|
|
|
602
605
|
# Recover variables on AIL blocks
|
|
603
606
|
self._update_progress(80.0, text="Recovering variables")
|
|
@@ -605,7 +608,11 @@ class Clinic(Analysis):
|
|
|
605
608
|
|
|
606
609
|
# Run simplification passes
|
|
607
610
|
self._update_progress(85.0, text="Running simplifications 4")
|
|
608
|
-
ail_graph = self._run_simplification_passes(
|
|
611
|
+
ail_graph = self._run_simplification_passes(
|
|
612
|
+
ail_graph,
|
|
613
|
+
stage=OptimizationPassStage.AFTER_VARIABLE_RECOVERY,
|
|
614
|
+
avoid_vvar_ids=copied_vvar_ids,
|
|
615
|
+
)
|
|
609
616
|
|
|
610
617
|
# Make function prototype
|
|
611
618
|
self._update_progress(90.0, text="Making function prototype")
|
|
@@ -1359,10 +1366,9 @@ class Clinic(Analysis):
|
|
|
1359
1366
|
|
|
1360
1367
|
@timethis
|
|
1361
1368
|
def _transform_to_ssa_level0(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
|
|
1362
|
-
ssailification = self.project.analyses.
|
|
1369
|
+
ssailification = self.project.analyses[Ssailification].prep(fail_fast=self._fail_fast)(
|
|
1363
1370
|
self.function,
|
|
1364
1371
|
ail_graph,
|
|
1365
|
-
fail_fast=self._fail_fast,
|
|
1366
1372
|
entry=next(iter(bb for bb in ail_graph if (bb.addr, bb.idx) == self.entry_node_addr)),
|
|
1367
1373
|
ail_manager=self._ail_manager,
|
|
1368
1374
|
ssa_stackvars=False,
|
|
@@ -1387,16 +1393,19 @@ class Clinic(Analysis):
|
|
|
1387
1393
|
return ssailification.out_graph
|
|
1388
1394
|
|
|
1389
1395
|
@timethis
|
|
1390
|
-
def _collect_dephi_vvar_mapping_and_rewrite_blocks(
|
|
1396
|
+
def _collect_dephi_vvar_mapping_and_rewrite_blocks(
|
|
1397
|
+
self, ail_graph: networkx.DiGraph, arg_vvars: dict[int, tuple[ailment.Expr.VirtualVariable, SimVariable]]
|
|
1398
|
+
) -> tuple[dict[int, int], set[int]]:
|
|
1391
1399
|
dephication = self.project.analyses.GraphDephicationVVarMapping(
|
|
1392
1400
|
self.function,
|
|
1393
1401
|
ail_graph,
|
|
1394
1402
|
fail_fast=self._fail_fast,
|
|
1395
1403
|
entry=next(iter(bb for bb in ail_graph if (bb.addr, bb.idx) == self.entry_node_addr)),
|
|
1396
1404
|
vvar_id_start=self.vvar_id_start,
|
|
1405
|
+
arg_vvars=[arg_vvar for arg_vvar, _ in arg_vvars.values()],
|
|
1397
1406
|
)
|
|
1398
1407
|
self.vvar_id_start = dephication.vvar_id_start + 1
|
|
1399
|
-
return dephication.vvar_to_vvar_mapping
|
|
1408
|
+
return dephication.vvar_to_vvar_mapping, dephication.copied_vvar_ids
|
|
1400
1409
|
|
|
1401
1410
|
@timethis
|
|
1402
1411
|
def _make_argument_list(self) -> list[SimVariable]:
|
|
@@ -1410,7 +1419,7 @@ class Clinic(Analysis):
|
|
|
1410
1419
|
argvar = SimRegisterVariable(
|
|
1411
1420
|
self.project.arch.registers[arg.reg_name][0],
|
|
1412
1421
|
arg.size,
|
|
1413
|
-
ident="arg_
|
|
1422
|
+
ident=f"arg_{idx}",
|
|
1414
1423
|
name=arg_names[idx],
|
|
1415
1424
|
region=self.function.addr,
|
|
1416
1425
|
)
|
|
@@ -1419,13 +1428,13 @@ class Clinic(Analysis):
|
|
|
1419
1428
|
arg.stack_offset,
|
|
1420
1429
|
arg.size,
|
|
1421
1430
|
base="bp",
|
|
1422
|
-
ident="arg_
|
|
1431
|
+
ident=f"arg_{idx}",
|
|
1423
1432
|
name=arg_names[idx],
|
|
1424
1433
|
region=self.function.addr,
|
|
1425
1434
|
)
|
|
1426
1435
|
else:
|
|
1427
1436
|
argvar = SimVariable(
|
|
1428
|
-
ident="arg_
|
|
1437
|
+
ident=f"arg_{idx}",
|
|
1429
1438
|
name=arg_names[idx],
|
|
1430
1439
|
region=self.function.addr,
|
|
1431
1440
|
size=arg.size,
|
|
@@ -1932,10 +1941,12 @@ class Clinic(Analysis):
|
|
|
1932
1941
|
break
|
|
1933
1942
|
|
|
1934
1943
|
def _create_triangle_for_ite_expression(self, ail_graph, block_addr: int, ite_ins_addr: int):
|
|
1935
|
-
|
|
1936
|
-
ite_insn_size =
|
|
1944
|
+
ite_insn_only_block = self.project.factory.block(ite_ins_addr, num_inst=1)
|
|
1945
|
+
ite_insn_size = ite_insn_only_block.size
|
|
1937
1946
|
if ite_insn_size <= 2: # we need an address for true_block and another address for false_block
|
|
1938
1947
|
return None
|
|
1948
|
+
if ite_insn_only_block.vex.exit_statements:
|
|
1949
|
+
return None
|
|
1939
1950
|
|
|
1940
1951
|
# relift the head and the ITE instruction
|
|
1941
1952
|
new_head = self.project.factory.block(
|
|
@@ -2037,6 +2048,10 @@ class Clinic(Analysis):
|
|
|
2037
2048
|
):
|
|
2038
2049
|
return None
|
|
2039
2050
|
|
|
2051
|
+
# corner-case: the last statement of original_block might have been patched by _remove_redundant_jump_blocks.
|
|
2052
|
+
# we detect such case and fix it in new_head_ail
|
|
2053
|
+
self._remove_redundant_jump_blocks_repatch_relifted_block(original_block, end_block_ail)
|
|
2054
|
+
|
|
2040
2055
|
ail_graph.remove_node(original_block)
|
|
2041
2056
|
|
|
2042
2057
|
if end_block_ail not in ail_graph:
|
|
@@ -2142,15 +2157,15 @@ class Clinic(Analysis):
|
|
|
2142
2157
|
),
|
|
2143
2158
|
None,
|
|
2144
2159
|
)
|
|
2160
|
+
intended_head_block = self.project.factory.block(
|
|
2161
|
+
intended_head.addr, size=intended_head.original_size
|
|
2162
|
+
)
|
|
2145
2163
|
if comparison_stmt is not None:
|
|
2146
|
-
intended_head_block = self.project.factory.block(
|
|
2147
|
-
intended_head.addr, size=intended_head.original_size
|
|
2148
|
-
)
|
|
2149
2164
|
cmp_rpos = len(
|
|
2150
2165
|
intended_head_block.instruction_addrs
|
|
2151
2166
|
) - intended_head_block.instruction_addrs.index(comparison_stmt.ins_addr)
|
|
2152
2167
|
else:
|
|
2153
|
-
cmp_rpos = 2
|
|
2168
|
+
cmp_rpos = min(len(intended_head_block.instruction_addrs), 2)
|
|
2154
2169
|
self._fix_abnormal_switch_case_heads_case2(
|
|
2155
2170
|
ail_graph,
|
|
2156
2171
|
candidate,
|
|
@@ -2216,7 +2231,6 @@ class Clinic(Analysis):
|
|
|
2216
2231
|
if isinstance(stmt, ailment.Stmt.Assignment)
|
|
2217
2232
|
and isinstance(stmt.src, ailment.Expr.BinaryOp)
|
|
2218
2233
|
and stmt.src.op in ailment.Expr.BinaryOp.COMPARISON_NEGATION
|
|
2219
|
-
and isinstance(stmt.src.operands[1], ailment.Expr.Const)
|
|
2220
2234
|
and stmt.ins_addr == last_stmt_0.ins_addr
|
|
2221
2235
|
),
|
|
2222
2236
|
None,
|
|
@@ -2228,7 +2242,6 @@ class Clinic(Analysis):
|
|
|
2228
2242
|
if isinstance(stmt, ailment.Stmt.Assignment)
|
|
2229
2243
|
and isinstance(stmt.src, ailment.Expr.BinaryOp)
|
|
2230
2244
|
and stmt.src.op in ailment.Expr.BinaryOp.COMPARISON_NEGATION
|
|
2231
|
-
and isinstance(stmt.src.operands[1], ailment.Expr.Const)
|
|
2232
2245
|
and stmt.ins_addr == last_stmt_1.ins_addr
|
|
2233
2246
|
),
|
|
2234
2247
|
None,
|
|
@@ -2270,51 +2283,86 @@ class Clinic(Analysis):
|
|
|
2270
2283
|
# split the intended head into two
|
|
2271
2284
|
intended_head_block = self.project.factory.block(intended_head.addr, size=intended_head.original_size)
|
|
2272
2285
|
split_ins_addr = intended_head_block.instruction_addrs[-intended_head_split_insns]
|
|
2273
|
-
|
|
2286
|
+
# note that the two blocks can be fully overlapping, so block_0 will be empty...
|
|
2287
|
+
intended_head_block_0 = (
|
|
2288
|
+
self.project.factory.block(intended_head.addr, size=split_ins_addr - intended_head.addr)
|
|
2289
|
+
if split_ins_addr != intended_head.addr
|
|
2290
|
+
else None
|
|
2291
|
+
)
|
|
2274
2292
|
intended_head_block_1 = self.project.factory.block(
|
|
2275
2293
|
split_ins_addr, size=intended_head.addr + intended_head.original_size - split_ins_addr
|
|
2276
2294
|
)
|
|
2277
|
-
intended_head_0 = self._convert_vex(intended_head_block_0)
|
|
2295
|
+
intended_head_0 = self._convert_vex(intended_head_block_0) if intended_head_block_0 is not None else None
|
|
2278
2296
|
intended_head_1 = self._convert_vex(intended_head_block_1)
|
|
2279
2297
|
|
|
2298
|
+
# corner-case: the last statement of intended_head might have been patched by _remove_redundant_jump_blocks. we
|
|
2299
|
+
# detect such case and fix it in intended_head_1
|
|
2300
|
+
self._remove_redundant_jump_blocks_repatch_relifted_block(intended_head, intended_head_1)
|
|
2301
|
+
|
|
2280
2302
|
# adjust the graph accordingly
|
|
2281
2303
|
preds = list(ail_graph.predecessors(intended_head))
|
|
2282
2304
|
succs = list(ail_graph.successors(intended_head))
|
|
2283
2305
|
ail_graph.remove_node(intended_head)
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2306
|
+
|
|
2307
|
+
if intended_head_0 is None:
|
|
2308
|
+
# perfect overlap; the first block is empty
|
|
2309
|
+
for pred in preds:
|
|
2310
|
+
if pred is intended_head:
|
|
2311
|
+
ail_graph.add_edge(intended_head_1, intended_head_1)
|
|
2312
|
+
else:
|
|
2313
|
+
ail_graph.add_edge(pred, intended_head_1)
|
|
2314
|
+
for succ in succs:
|
|
2315
|
+
if succ is intended_head:
|
|
2316
|
+
ail_graph.add_edge(intended_head_1, intended_head_1)
|
|
2317
|
+
else:
|
|
2318
|
+
ail_graph.add_edge(intended_head_1, succ)
|
|
2319
|
+
else:
|
|
2320
|
+
ail_graph.add_edge(intended_head_0, intended_head_1)
|
|
2321
|
+
for pred in preds:
|
|
2322
|
+
if pred is intended_head:
|
|
2323
|
+
ail_graph.add_edge(intended_head_1, intended_head_0)
|
|
2324
|
+
else:
|
|
2325
|
+
ail_graph.add_edge(pred, intended_head_0)
|
|
2326
|
+
for succ in succs:
|
|
2327
|
+
if succ is intended_head:
|
|
2328
|
+
ail_graph.add_edge(intended_head_1, intended_head_0)
|
|
2329
|
+
else:
|
|
2330
|
+
ail_graph.add_edge(intended_head_1, succ)
|
|
2295
2331
|
|
|
2296
2332
|
# split other heads
|
|
2297
2333
|
for o in other_heads:
|
|
2298
2334
|
if other_head_split_insns > 0:
|
|
2299
2335
|
o_block = self.project.factory.block(o.addr, size=o.original_size)
|
|
2300
2336
|
o_split_addr = o_block.instruction_addrs[-other_head_split_insns]
|
|
2301
|
-
new_o_block =
|
|
2302
|
-
|
|
2337
|
+
new_o_block = (
|
|
2338
|
+
self.project.factory.block(o.addr, size=o_split_addr - o.addr) if o_split_addr != o.addr else None
|
|
2339
|
+
)
|
|
2340
|
+
new_head = self._convert_vex(new_o_block) if new_o_block is not None else None
|
|
2303
2341
|
else:
|
|
2304
2342
|
new_head = o
|
|
2305
2343
|
|
|
2306
|
-
if
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
):
|
|
2311
|
-
# update the jump target
|
|
2312
|
-
new_head.statements[-1] = ailment.Stmt.Jump(
|
|
2313
|
-
new_head.statements[-1].idx,
|
|
2344
|
+
if new_head is None:
|
|
2345
|
+
# the head is removed - let's replace it with a jump to the target
|
|
2346
|
+
jump_stmt = ailment.Stmt.Jump(
|
|
2347
|
+
None,
|
|
2314
2348
|
ailment.Expr.Const(None, None, intended_head_1.addr, self.project.arch.bits),
|
|
2315
2349
|
target_idx=intended_head_1.idx,
|
|
2316
|
-
|
|
2350
|
+
ins_addr=o.addr,
|
|
2317
2351
|
)
|
|
2352
|
+
new_head = ailment.Block(o.addr, 1, statements=[jump_stmt], idx=o.idx)
|
|
2353
|
+
else:
|
|
2354
|
+
if (
|
|
2355
|
+
new_head.statements
|
|
2356
|
+
and isinstance(new_head.statements[-1], ailment.Stmt.Jump)
|
|
2357
|
+
and isinstance(new_head.statements[-1].target, ailment.Expr.Const)
|
|
2358
|
+
):
|
|
2359
|
+
# update the jump target
|
|
2360
|
+
new_head.statements[-1] = ailment.Stmt.Jump(
|
|
2361
|
+
new_head.statements[-1].idx,
|
|
2362
|
+
ailment.Expr.Const(None, None, intended_head_1.addr, self.project.arch.bits),
|
|
2363
|
+
target_idx=intended_head_1.idx,
|
|
2364
|
+
**new_head.statements[-1].tags,
|
|
2365
|
+
)
|
|
2318
2366
|
|
|
2319
2367
|
# adjust the graph accordingly
|
|
2320
2368
|
preds = list(ail_graph.predecessors(o))
|
|
@@ -2384,6 +2432,39 @@ class Clinic(Analysis):
|
|
|
2384
2432
|
ail_graph.add_edge(pred, succs[0])
|
|
2385
2433
|
ail_graph.remove_node(node)
|
|
2386
2434
|
|
|
2435
|
+
@staticmethod
|
|
2436
|
+
def _remove_redundant_jump_blocks_repatch_relifted_block(
|
|
2437
|
+
patched_block: ailment.Block, new_block: ailment.Block
|
|
2438
|
+
) -> None:
|
|
2439
|
+
"""
|
|
2440
|
+
The last statement of patched_block might have been patched by _remove_redundant_jump_blocks. In this case, we
|
|
2441
|
+
fix the last instruction for new_block, which is a newly lifted (from VEX) block that ends at the same address
|
|
2442
|
+
as patched_block.
|
|
2443
|
+
|
|
2444
|
+
:param patched_block: Previously patched block.
|
|
2445
|
+
:param new_block: Newly lifted block.
|
|
2446
|
+
"""
|
|
2447
|
+
|
|
2448
|
+
if (
|
|
2449
|
+
isinstance(patched_block.statements[-1], ailment.Stmt.Jump)
|
|
2450
|
+
and isinstance(patched_block.statements[-1].target, ailment.Expr.Const)
|
|
2451
|
+
and isinstance(new_block.statements[-1], ailment.Stmt.Jump)
|
|
2452
|
+
and isinstance(new_block.statements[-1].target, ailment.Expr.Const)
|
|
2453
|
+
and not patched_block.statements[-1].likes(new_block.statements[-1])
|
|
2454
|
+
):
|
|
2455
|
+
new_block.statements[-1].target = patched_block.statements[-1].target
|
|
2456
|
+
if (
|
|
2457
|
+
isinstance(patched_block.statements[-1], ailment.Stmt.ConditionalJump)
|
|
2458
|
+
and isinstance(patched_block.statements[-1].true_target, ailment.Expr.Const)
|
|
2459
|
+
and isinstance(patched_block.statements[-1].false_target, ailment.Expr.Const)
|
|
2460
|
+
and isinstance(new_block.statements[-1], ailment.Stmt.ConditionalJump)
|
|
2461
|
+
and isinstance(new_block.statements[-1].true_target, ailment.Expr.Const)
|
|
2462
|
+
and isinstance(new_block.statements[-1].false_target, ailment.Expr.Const)
|
|
2463
|
+
and not patched_block.statements[-1].likes(new_block.statements[-1])
|
|
2464
|
+
):
|
|
2465
|
+
new_block.statements[-1].true_target = patched_block.statements[-1].true_target
|
|
2466
|
+
new_block.statements[-1].false_target = patched_block.statements[-1].false_target
|
|
2467
|
+
|
|
2387
2468
|
@staticmethod
|
|
2388
2469
|
def _insert_block_labels(ail_graph):
|
|
2389
2470
|
for node in ail_graph.nodes:
|
|
@@ -113,41 +113,53 @@ _ail2claripy_op_mapping = {
|
|
|
113
113
|
"LogicalOr": lambda expr, conv, _, ia: claripy.Or(
|
|
114
114
|
conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
|
|
115
115
|
),
|
|
116
|
-
"CmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
117
|
-
|
|
118
|
-
"
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
"CmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
117
|
+
== conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
118
|
+
"CmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
119
|
+
!= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
120
|
+
"CmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
121
|
+
<= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
122
|
+
"CmpLE (signed)": lambda expr, conv, _, ia: claripy.SLE(
|
|
123
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
121
124
|
),
|
|
122
|
-
"CmpLT": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
"CmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
126
|
+
< conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
127
|
+
"CmpLT (signed)": lambda expr, conv, _, ia: claripy.SLT(
|
|
128
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
125
129
|
),
|
|
126
|
-
"CmpGE": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
"CmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
131
|
+
>= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
132
|
+
"CmpGE (signed)": lambda expr, conv, _, ia: claripy.SGE(
|
|
133
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
129
134
|
),
|
|
130
|
-
"CmpGT": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
"CmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
136
|
+
> conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
137
|
+
"CmpGT (signed)": lambda expr, conv, _, ia: claripy.SGT(
|
|
138
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
133
139
|
),
|
|
134
|
-
"CasCmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
135
|
-
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
"CasCmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
141
|
+
== conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
142
|
+
"CasCmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
143
|
+
!= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
144
|
+
"CasCmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
145
|
+
<= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
146
|
+
"CasCmpLE (signed)": lambda expr, conv, _, ia: claripy.SLE(
|
|
147
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
139
148
|
),
|
|
140
|
-
"CasCmpLT": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
141
|
-
|
|
142
|
-
|
|
149
|
+
"CasCmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
150
|
+
< conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
151
|
+
"CasCmpLT (signed)": lambda expr, conv, _, ia: claripy.SLT(
|
|
152
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
143
153
|
),
|
|
144
|
-
"CasCmpGE": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
"CasCmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
155
|
+
>= conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
156
|
+
"CasCmpGE (signed)": lambda expr, conv, _, ia: claripy.SGE(
|
|
157
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
147
158
|
),
|
|
148
|
-
"CasCmpGT": lambda expr, conv, _, ia: conv(expr.operands[0],
|
|
149
|
-
|
|
150
|
-
|
|
159
|
+
"CasCmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
160
|
+
> conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
161
|
+
"CasCmpGT (signed)": lambda expr, conv, _, ia: claripy.SGT(
|
|
162
|
+
conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
|
|
151
163
|
),
|
|
152
164
|
"Add": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
|
|
153
165
|
+ conv(expr.operands[1], nobool=True, ins_addr=ia),
|
|
@@ -177,10 +189,9 @@ _ail2claripy_op_mapping = {
|
|
|
177
189
|
),
|
|
178
190
|
"Concat": lambda expr, conv, _, ia: claripy.Concat(*[conv(operand, ins_addr=ia) for operand in expr.operands]),
|
|
179
191
|
# There are no corresponding claripy operations for the following operations
|
|
180
|
-
"DivMod": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
181
192
|
"CmpF": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
182
193
|
"Mull": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
183
|
-
"
|
|
194
|
+
"Mull (signed)": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
184
195
|
"Reinterpret": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
185
196
|
"Rol": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
186
197
|
"Ror": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
@@ -190,7 +201,10 @@ _ail2claripy_op_mapping = {
|
|
|
190
201
|
"SBorrow": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
191
202
|
"ExpCmpNE": lambda expr, _, m, *args: _dummy_bools(expr, m),
|
|
192
203
|
"CmpORD": lambda expr, _, m, *args: _dummy_bvs(expr, m), # in case CmpORDRewriter fails
|
|
204
|
+
"CmpEQV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
193
205
|
"GetMSBs": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
206
|
+
"ShlNV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
207
|
+
"ShrNV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
194
208
|
"InterleaveLOV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
195
209
|
"InterleaveHIV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
|
|
196
210
|
# catch-all
|
|
@@ -800,9 +814,13 @@ class ConditionProcessor:
|
|
|
800
814
|
f"Condition variable {cond} has an unsupported operator {cond.op}. Consider implementing."
|
|
801
815
|
)
|
|
802
816
|
|
|
803
|
-
def claripy_ast_from_ail_condition(
|
|
817
|
+
def claripy_ast_from_ail_condition(
|
|
818
|
+
self, condition, nobool: bool = False, *, ins_addr: int = 0
|
|
819
|
+
) -> claripy.ast.Bool | claripy.ast.Bits:
|
|
804
820
|
# Unpack a condition all the way to the leaves
|
|
805
|
-
if isinstance(
|
|
821
|
+
if isinstance(
|
|
822
|
+
condition, (claripy.ast.Bits, claripy.ast.Bool)
|
|
823
|
+
): # pylint:disable=isinstance-second-argument-not-valid-type
|
|
806
824
|
return condition
|
|
807
825
|
|
|
808
826
|
if isinstance(
|
|
@@ -830,11 +848,11 @@ class ConditionProcessor:
|
|
|
830
848
|
# convert is special. if it generates a 1-bit variable, it should be treated as a BoolS
|
|
831
849
|
if condition.to_bits == 1:
|
|
832
850
|
var_ = self.claripy_ast_from_ail_condition(condition.operands[0], ins_addr=ins_addr)
|
|
833
|
-
name = "ailcond_Conv(
|
|
851
|
+
name = f"ailcond_Conv({condition.from_bits}->{condition.to_bits}, {hash(var_)})"
|
|
834
852
|
var = claripy.BoolS(name, explicit_name=True)
|
|
835
853
|
else:
|
|
836
854
|
var_ = self.claripy_ast_from_ail_condition(condition.operands[0], ins_addr=ins_addr)
|
|
837
|
-
name = "ailexpr_Conv(
|
|
855
|
+
name = f"ailexpr_Conv({condition.from_bits}->{condition.to_bits}, {hash(var_)})"
|
|
838
856
|
var = claripy.BVS(name, condition.to_bits, explicit_name=True)
|
|
839
857
|
self._condition_mapping[var.args[0]] = condition
|
|
840
858
|
return var
|
|
@@ -849,17 +867,17 @@ class ConditionProcessor:
|
|
|
849
867
|
if isinstance(condition, ailment.Expr.Tmp):
|
|
850
868
|
l.warning("Left-over ailment.Tmp variable %s.", condition)
|
|
851
869
|
if condition.bits == 1:
|
|
852
|
-
var = claripy.BoolS("ailtmp_
|
|
870
|
+
var = claripy.BoolS(f"ailtmp_{condition.tmp_idx}", explicit_name=True)
|
|
853
871
|
else:
|
|
854
|
-
var = claripy.BVS("ailtmp_
|
|
872
|
+
var = claripy.BVS(f"ailtmp_{condition.tmp_idx}", condition.bits, explicit_name=True)
|
|
855
873
|
self._condition_mapping[var.args[0]] = condition
|
|
856
874
|
return var
|
|
857
875
|
if isinstance(condition, ailment.Expr.MultiStatementExpression):
|
|
858
876
|
# just cache it
|
|
859
877
|
if condition.bits == 1:
|
|
860
|
-
var = claripy.BoolS("mstmtexpr_
|
|
878
|
+
var = claripy.BoolS(f"mstmtexpr_{hash(condition)}", explicit_name=True)
|
|
861
879
|
else:
|
|
862
|
-
var = claripy.BVS("mstmtexpr_
|
|
880
|
+
var = claripy.BVS(f"mstmtexpr_{hash(condition)}", condition.bits, explicit_name=True)
|
|
863
881
|
self._condition_mapping[var.args[0]] = condition
|
|
864
882
|
return var
|
|
865
883
|
|
|
@@ -883,7 +901,7 @@ class ConditionProcessor:
|
|
|
883
901
|
self._condition_mapping[r.args[0]] = condition
|
|
884
902
|
|
|
885
903
|
if r is NotImplemented:
|
|
886
|
-
if condition.bits == 1:
|
|
904
|
+
if condition.bits == 1 and not nobool:
|
|
887
905
|
r = claripy.BoolS(f"ailexpr_{condition!r}", explicit_name=True)
|
|
888
906
|
else:
|
|
889
907
|
r = claripy.BVS(f"ailexpr_{condition!r}", condition.bits, explicit_name=True)
|
|
@@ -7,10 +7,10 @@ from .expression_counters import SingleExpressionCounter, RegisterExpressionCoun
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
__all__ = (
|
|
10
|
-
"BooleanCounter",
|
|
11
10
|
"AILBlockCallCounter",
|
|
11
|
+
"BooleanCounter",
|
|
12
12
|
"ControlFlowStructureCounter",
|
|
13
|
-
"SingleExpressionCounter",
|
|
14
|
-
"RegisterExpressionCounter",
|
|
15
13
|
"OperatorCounter",
|
|
14
|
+
"RegisterExpressionCounter",
|
|
15
|
+
"SingleExpressionCounter",
|
|
16
16
|
)
|
|
@@ -14,16 +14,16 @@ class DecompilationCache:
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
__slots__ = (
|
|
17
|
-
"parameters",
|
|
18
17
|
"addr",
|
|
19
|
-
"type_constraints",
|
|
20
|
-
"func_typevar",
|
|
21
|
-
"var_to_typevar",
|
|
22
|
-
"codegen",
|
|
23
|
-
"clinic",
|
|
24
|
-
"ite_exprs",
|
|
25
18
|
"binop_operators",
|
|
19
|
+
"clinic",
|
|
20
|
+
"codegen",
|
|
26
21
|
"errors",
|
|
22
|
+
"func_typevar",
|
|
23
|
+
"ite_exprs",
|
|
24
|
+
"parameters",
|
|
25
|
+
"type_constraints",
|
|
26
|
+
"var_to_typevar",
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
def __init__(self, addr):
|
|
@@ -3,4 +3,4 @@ from .graph_vvar_mapping import GraphDephicationVVarMapping
|
|
|
3
3
|
from .graph_dephication import GraphDephication
|
|
4
4
|
from .seqnode_dephication import SeqNodeDephication
|
|
5
5
|
|
|
6
|
-
__all__ = ["
|
|
6
|
+
__all__ = ["GraphDephication", "GraphDephicationVVarMapping", "SeqNodeDephication"]
|
|
@@ -37,7 +37,7 @@ class GraphRewritingAnalysis(ForwardAnalysis[None, NodeType, object, object]):
|
|
|
37
37
|
)
|
|
38
38
|
self._graph = ail_graph
|
|
39
39
|
self._vvar_to_vvar = vvar_to_vvar
|
|
40
|
-
self._engine_ail = SimEngineDephiRewriting(self.project
|
|
40
|
+
self._engine_ail = SimEngineDephiRewriting(self.project, self._vvar_to_vvar)
|
|
41
41
|
|
|
42
42
|
self._visited_blocks: set[Any] = set()
|
|
43
43
|
self.out_blocks = {}
|
|
@@ -10,7 +10,7 @@ from angr.analyses import Analysis
|
|
|
10
10
|
from angr.analyses.s_reaching_definitions import SRDAModel
|
|
11
11
|
from angr.knowledge_plugins.functions import Function
|
|
12
12
|
from angr.analyses import register_analysis
|
|
13
|
-
from angr.utils.ssa import is_phi_assignment
|
|
13
|
+
from angr.utils.ssa import is_phi_assignment, DEPHI_VVAR_REG_OFFSET
|
|
14
14
|
|
|
15
15
|
l = logging.getLogger(name=__name__)
|
|
16
16
|
|
|
@@ -30,6 +30,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
30
30
|
ail_graph,
|
|
31
31
|
entry=None,
|
|
32
32
|
vvar_id_start: int = 0,
|
|
33
|
+
arg_vvars: list[VirtualVariable] | None = None,
|
|
33
34
|
):
|
|
34
35
|
"""
|
|
35
36
|
:param func: The subject of the analysis: a function, or a single basic block
|
|
@@ -49,8 +50,10 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
49
50
|
self._vvar_defloc = {}
|
|
50
51
|
self.vvar_id_start = vvar_id_start
|
|
51
52
|
self._stmts_to_prepend = defaultdict(list)
|
|
53
|
+
self._arg_vvars = arg_vvars or []
|
|
52
54
|
|
|
53
55
|
self.vvar_to_vvar_mapping = None
|
|
56
|
+
self.copied_vvar_ids: set[int] = set()
|
|
54
57
|
self._rd: SRDAModel = self.project.analyses.SReachingDefinitions(
|
|
55
58
|
subject=self._function, func_graph=self._graph
|
|
56
59
|
).model
|
|
@@ -74,7 +77,9 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
74
77
|
phi_congruence_class[varid] = {varid}
|
|
75
78
|
|
|
76
79
|
# compute liveness
|
|
77
|
-
liveness = self.project.analyses.SLiveness(
|
|
80
|
+
liveness = self.project.analyses.SLiveness(
|
|
81
|
+
self._function, func_graph=self._graph, entry=self._entry, arg_vvars=self._arg_vvars
|
|
82
|
+
)
|
|
78
83
|
|
|
79
84
|
live_ins = liveness.model.live_ins
|
|
80
85
|
live_outs = liveness.model.live_outs
|
|
@@ -136,6 +141,8 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
136
141
|
|
|
137
142
|
if insertion_type == 0:
|
|
138
143
|
for src, old_vvar_id, new_vvar_id in new_vvar_ids:
|
|
144
|
+
self.copied_vvar_ids.add(new_vvar_id)
|
|
145
|
+
|
|
139
146
|
phi_congruence_class[new_vvar_id] = {new_vvar_id}
|
|
140
147
|
live_outs[src].add(new_vvar_id)
|
|
141
148
|
|
|
@@ -153,6 +160,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
153
160
|
|
|
154
161
|
else: # insertion_type == 1
|
|
155
162
|
phi_block_loc, old_phi_varid, new_phi_varid = next(iter(new_vvar_ids))
|
|
163
|
+
self.copied_vvar_ids.add(new_phi_varid)
|
|
156
164
|
|
|
157
165
|
phi_congruence_class[new_phi_varid] = {new_phi_varid}
|
|
158
166
|
|
|
@@ -217,7 +225,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
|
|
|
217
225
|
# it's a parameter, so we copy the variable into a dummy register vvar
|
|
218
226
|
# a parameter vvar should never be assigned to
|
|
219
227
|
new_category = VirtualVariableCategory.REGISTER
|
|
220
|
-
new_oident =
|
|
228
|
+
new_oident = DEPHI_VVAR_REG_OFFSET
|
|
221
229
|
else:
|
|
222
230
|
new_category = vvar.category
|
|
223
231
|
new_oident = vvar.oident
|