smallworld-re 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.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.
- smallworld/analyses/__init__.py +8 -0
- smallworld/analyses/analysis.py +8 -67
- smallworld/analyses/code_coverage.py +1 -2
- smallworld/analyses/colorizer.py +301 -534
- smallworld/analyses/colorizer_def_use.py +217 -0
- smallworld/analyses/colorizer_summary.py +173 -83
- smallworld/analyses/field_detection/field_analysis.py +7 -8
- smallworld/analyses/field_detection/hints.py +1 -1
- smallworld/analyses/field_detection/malloc.py +2 -2
- smallworld/analyses/trace_execution.py +160 -0
- smallworld/analyses/trace_execution_types.py +42 -0
- smallworld/analyses/unstable/angr/divergence.py +1 -2
- smallworld/analyses/unstable/angr/model.py +5 -6
- smallworld/analyses/unstable/angr_nwbt.py +3 -4
- smallworld/analyses/unstable/code_coverage.py +2 -3
- smallworld/analyses/unstable/code_reachable.py +2 -3
- smallworld/analyses/unstable/control_flow_tracer.py +2 -3
- smallworld/analyses/unstable/pointer_finder.py +2 -3
- smallworld/analyses/unstable/utils/tui.py +71 -0
- smallworld/emulators/__init__.py +3 -1
- smallworld/emulators/angr/angr.py +30 -9
- smallworld/emulators/angr/machdefs/__init__.py +2 -0
- smallworld/emulators/angr/machdefs/aarch64.py +1 -1
- smallworld/emulators/angr/machdefs/amd64.py +0 -4
- smallworld/emulators/angr/machdefs/arm.py +0 -2
- smallworld/emulators/angr/machdefs/i386.py +0 -2
- smallworld/emulators/angr/machdefs/loongarch.py +340 -0
- smallworld/emulators/angr/machdefs/machdef.py +1 -8
- smallworld/emulators/angr/machdefs/mips.py +0 -2
- smallworld/emulators/angr/machdefs/mips64.py +0 -2
- smallworld/emulators/angr/machdefs/ppc.py +1 -2
- smallworld/emulators/angr/machdefs/riscv.py +8 -10
- smallworld/emulators/angr/machdefs/xtensa.py +7 -4
- smallworld/emulators/emulator.py +22 -0
- smallworld/emulators/ghidra/__init__.py +37 -0
- smallworld/emulators/ghidra/ghidra.py +513 -0
- smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
- smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
- smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
- smallworld/emulators/ghidra/machdefs/arm.py +370 -0
- smallworld/emulators/ghidra/machdefs/i386.py +109 -0
- smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
- smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
- smallworld/emulators/ghidra/machdefs/mips.py +163 -0
- smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
- smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
- smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
- smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
- smallworld/emulators/ghidra/typing.py +28 -0
- smallworld/emulators/hookable.py +18 -4
- smallworld/emulators/panda/machdefs/__init__.py +2 -2
- smallworld/emulators/panda/machdefs/aarch64.py +186 -11
- smallworld/emulators/panda/machdefs/amd64.py +103 -11
- smallworld/emulators/panda/machdefs/arm.py +216 -20
- smallworld/emulators/panda/machdefs/i386.py +30 -7
- smallworld/emulators/panda/machdefs/machdef.py +9 -16
- smallworld/emulators/panda/machdefs/mips.py +49 -5
- smallworld/emulators/panda/machdefs/mips64.py +57 -5
- smallworld/emulators/panda/machdefs/ppc.py +38 -13
- smallworld/emulators/panda/panda.py +146 -44
- smallworld/emulators/unicorn/__init__.py +2 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
- smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
- smallworld/emulators/unicorn/machdefs/arm.py +200 -212
- smallworld/emulators/unicorn/machdefs/i386.py +84 -90
- smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
- smallworld/emulators/unicorn/machdefs/mips.py +127 -135
- smallworld/emulators/unicorn/unicorn.py +52 -13
- smallworld/helpers.py +4 -19
- smallworld/hinting/hinting.py +22 -192
- smallworld/hinting/hints.py +50 -18
- smallworld/instructions/bsid.py +8 -8
- smallworld/logging.py +4 -2
- smallworld/platforms/__init__.py +12 -0
- smallworld/platforms/defs/__init__.py +36 -0
- smallworld/platforms/defs/aarch64.py +450 -0
- smallworld/platforms/defs/amd64.py +463 -0
- smallworld/platforms/defs/arm.py +519 -0
- smallworld/platforms/defs/i386.py +258 -0
- smallworld/platforms/defs/loongarch.py +270 -0
- smallworld/platforms/defs/mips.py +321 -0
- smallworld/platforms/defs/mips64.py +313 -0
- smallworld/platforms/defs/platformdef.py +97 -0
- smallworld/platforms/defs/powerpc.py +259 -0
- smallworld/platforms/defs/riscv.py +257 -0
- smallworld/platforms/defs/xtensa.py +96 -0
- smallworld/{platforms.py → platforms/platforms.py} +3 -0
- smallworld/state/cpus/__init__.py +2 -0
- smallworld/state/cpus/aarch64.py +0 -9
- smallworld/state/cpus/amd64.py +6 -28
- smallworld/state/cpus/arm.py +0 -11
- smallworld/state/cpus/cpu.py +0 -11
- smallworld/state/cpus/i386.py +0 -7
- smallworld/state/cpus/loongarch.py +299 -0
- smallworld/state/cpus/mips.py +4 -47
- smallworld/state/cpus/mips64.py +18 -58
- smallworld/state/cpus/powerpc.py +2 -9
- smallworld/state/cpus/riscv.py +1 -11
- smallworld/state/cpus/xtensa.py +0 -5
- smallworld/state/memory/code.py +44 -2
- smallworld/state/memory/elf/__init__.py +5 -1
- smallworld/state/memory/elf/coredump/__init__.py +3 -0
- smallworld/state/memory/elf/coredump/coredump.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
- smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
- smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
- smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
- smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
- smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
- smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
- smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
- smallworld/state/memory/elf/elf.py +225 -61
- smallworld/state/memory/elf/register_state.py +36 -0
- smallworld/state/memory/elf/rela/__init__.py +2 -0
- smallworld/state/memory/elf/rela/aarch64.py +3 -1
- smallworld/state/memory/elf/rela/amd64.py +4 -2
- smallworld/state/memory/elf/rela/arm.py +4 -2
- smallworld/state/memory/elf/rela/i386.py +4 -2
- smallworld/state/memory/elf/rela/loongarch.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +39 -18
- smallworld/state/memory/elf/rela/ppc.py +31 -14
- smallworld/state/memory/elf/structs.py +3 -0
- smallworld/state/memory/heap.py +2 -2
- smallworld/state/memory/memory.py +18 -0
- smallworld/state/memory/pe/__init__.py +3 -0
- smallworld/state/memory/pe/pe.py +361 -0
- smallworld/state/memory/pe/structs.py +60 -0
- smallworld/state/memory/stack/__init__.py +2 -0
- smallworld/state/memory/stack/loongarch.py +26 -0
- smallworld/state/models/__init__.py +29 -2
- smallworld/state/models/aarch64/__init__.py +1 -0
- smallworld/state/models/aarch64/systemv/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/aarch64/systemv/systemv.py +80 -0
- smallworld/state/models/amd64/__init__.py +1 -0
- smallworld/state/models/amd64/systemv/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
- smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/amd64/systemv/c99/string.py +139 -0
- smallworld/state/models/amd64/systemv/c99/time.py +61 -0
- smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
- smallworld/state/models/amd64/systemv/systemv.py +78 -0
- smallworld/state/models/armel/__init__.py +1 -0
- smallworld/state/models/armel/systemv/__init__.py +6 -0
- smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armel/systemv/c99/signal.py +16 -0
- smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armel/systemv/c99/string.py +139 -0
- smallworld/state/models/armel/systemv/c99/time.py +61 -0
- smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armel/systemv/posix/signal.py +157 -0
- smallworld/state/models/armel/systemv/systemv.py +82 -0
- smallworld/state/models/armhf/__init__.py +1 -0
- smallworld/state/models/armhf/systemv/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
- smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armhf/systemv/c99/string.py +139 -0
- smallworld/state/models/armhf/systemv/c99/time.py +61 -0
- smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
- smallworld/state/models/armhf/systemv/systemv.py +77 -0
- smallworld/state/models/c99/__init__.py +12 -0
- smallworld/state/models/c99/fmt_print.py +915 -0
- smallworld/state/models/c99/fmt_scan.py +864 -0
- smallworld/state/models/c99/math.py +362 -0
- smallworld/state/models/c99/signal.py +71 -0
- smallworld/state/models/c99/stdio.py +1305 -0
- smallworld/state/models/c99/stdlib.py +595 -0
- smallworld/state/models/c99/string.py +674 -0
- smallworld/state/models/c99/time.py +340 -0
- smallworld/state/models/c99/utils.py +89 -0
- smallworld/state/models/cstd.py +759 -0
- smallworld/state/models/errno.py +581 -0
- smallworld/state/models/filedesc.py +515 -0
- smallworld/state/models/i386/__init__.py +1 -0
- smallworld/state/models/i386/systemv/__init__.py +6 -0
- smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
- smallworld/state/models/i386/systemv/c99/signal.py +16 -0
- smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
- smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/i386/systemv/c99/string.py +139 -0
- smallworld/state/models/i386/systemv/c99/time.py +61 -0
- smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
- smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
- smallworld/state/models/i386/systemv/posix/signal.py +157 -0
- smallworld/state/models/i386/systemv/systemv.py +71 -0
- smallworld/state/models/loongarch64/__init__.py +1 -0
- smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
- smallworld/state/models/mips/__init__.py +1 -0
- smallworld/state/models/mips/systemv/__init__.py +6 -0
- smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips/systemv/c99/string.py +139 -0
- smallworld/state/models/mips/systemv/c99/time.py +61 -0
- smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips/systemv/systemv.py +78 -0
- smallworld/state/models/mips64/__init__.py +1 -0
- smallworld/state/models/mips64/systemv/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64/systemv/systemv.py +98 -0
- smallworld/state/models/mips64el/__init__.py +1 -0
- smallworld/state/models/mips64el/systemv/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64el/systemv/systemv.py +96 -0
- smallworld/state/models/mipsel/__init__.py +1 -0
- smallworld/state/models/mipsel/systemv/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
- smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
- smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
- smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
- smallworld/state/models/mipsel/systemv/systemv.py +78 -0
- smallworld/state/models/model.py +27 -2
- smallworld/state/models/posix/__init__.py +6 -0
- smallworld/state/models/posix/libgen.py +123 -0
- smallworld/state/models/posix/signal.py +690 -0
- smallworld/state/models/powerpc/__init__.py +1 -0
- smallworld/state/models/powerpc/systemv/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
- smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
- smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
- smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
- smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
- smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
- smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
- smallworld/state/models/powerpc/systemv/systemv.py +93 -0
- smallworld/state/models/riscv64/__init__.py +1 -0
- smallworld/state/models/riscv64/systemv/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
- smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
- smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
- smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
- smallworld/state/models/riscv64/systemv/systemv.py +85 -0
- smallworld/state/state.py +65 -24
- smallworld/state/unstable/elf.py +16 -31
- smallworld/utils.py +6 -1
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +76 -43
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
- smallworld/state/models/x86/__init__.py +0 -2
- smallworld/state/models/x86/microsoftcdecl.py +0 -35
- smallworld/state/models/x86/systemv.py +0 -240
- smallworld_re-1.0.2.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
import logging
|
2
|
+
import re
|
3
|
+
|
4
|
+
import networkx as nx
|
5
|
+
|
6
|
+
from .. import hinting
|
7
|
+
from . import analysis
|
8
|
+
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
|
11
|
+
|
12
|
+
class DefUseGraph(nx.MultiDiGraph):
|
13
|
+
def add_def_use(self, def_node, use_node, def_info, use_info, color):
|
14
|
+
# logger.info(f"def use def_node={def_node} use_node={use_node}")
|
15
|
+
# logger.info(f" def_info={def_info}")
|
16
|
+
# logger.info(f" use_info={use_info}")
|
17
|
+
self.add_edges_from(
|
18
|
+
[
|
19
|
+
(
|
20
|
+
def_node,
|
21
|
+
use_node,
|
22
|
+
{"def_info": def_info, "use_info": use_info, "color": color},
|
23
|
+
)
|
24
|
+
]
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
class ColorizerDefUse(analysis.Analysis):
|
29
|
+
name = "colorizer_def_use_graph"
|
30
|
+
description = "assemble a def use graph from colorizer summary hints"
|
31
|
+
version = "0.0.1"
|
32
|
+
|
33
|
+
def __init__(self, *args, **kwargs):
|
34
|
+
super().__init__(*args, **kwargs)
|
35
|
+
self.new_hints = []
|
36
|
+
self.not_new_hints = []
|
37
|
+
self.hinter.register(
|
38
|
+
hinting.DynamicRegisterValueSummaryHint, self.collect_hints
|
39
|
+
)
|
40
|
+
self.hinter.register(hinting.DynamicMemoryValueSummaryHint, self.collect_hints)
|
41
|
+
|
42
|
+
def collect_hints(self, hint: hinting.Hint):
|
43
|
+
if (
|
44
|
+
type(hint) is hinting.DynamicRegisterValueSummaryHint
|
45
|
+
or type(hint) is hinting.DynamicMemoryValueSummaryHint
|
46
|
+
):
|
47
|
+
if hint.new:
|
48
|
+
self.new_hints.append(hint)
|
49
|
+
else:
|
50
|
+
self.not_new_hints.append(hint)
|
51
|
+
|
52
|
+
def run(self, machine):
|
53
|
+
self.du_graph = DefUseGraph()
|
54
|
+
color2genesis = {}
|
55
|
+
|
56
|
+
def hint_dv_info(hint):
|
57
|
+
if type(hint) is hinting.DynamicRegisterValueSummaryHint:
|
58
|
+
return {
|
59
|
+
"new": hint.new,
|
60
|
+
"count": hint.count,
|
61
|
+
"num_micro_executions": hint.num_micro_executions,
|
62
|
+
"type": "reg",
|
63
|
+
"is_read": hint.use,
|
64
|
+
"reg_name": hint.reg_name,
|
65
|
+
"color": hint.color,
|
66
|
+
}
|
67
|
+
elif type(hint) is hinting.DynamicMemoryValueSummaryHint:
|
68
|
+
return {
|
69
|
+
"new": hint.new,
|
70
|
+
"count": hint.count,
|
71
|
+
"num_micro_executions": hint.num_micro_executions,
|
72
|
+
"type": "mem",
|
73
|
+
"is_read": hint.use,
|
74
|
+
"base": hint.base,
|
75
|
+
"index": hint.index,
|
76
|
+
"scale": hint.scale,
|
77
|
+
"offset": hint.offset,
|
78
|
+
"color": hint.color,
|
79
|
+
}
|
80
|
+
else:
|
81
|
+
assert 1 == 0
|
82
|
+
|
83
|
+
for hint in self.new_hints:
|
84
|
+
# this is a new color so its either an input or a write of a computed value
|
85
|
+
|
86
|
+
# some sanity checking
|
87
|
+
assert "def" in hint.message
|
88
|
+
assert hint.color not in color2genesis
|
89
|
+
assert (hint.use and ("read" in hint.message)) or (
|
90
|
+
(not hint.use) and ("write" in hint.message)
|
91
|
+
)
|
92
|
+
|
93
|
+
self.du_graph.add_node(hint.pc)
|
94
|
+
|
95
|
+
dv_info = hint_dv_info(hint)
|
96
|
+
|
97
|
+
if hint.use:
|
98
|
+
# this is a read
|
99
|
+
# hallucinate a node representing the creation of that color
|
100
|
+
color_node = f"input color-{hint.color}"
|
101
|
+
assert dv_info["type"] == "reg" or dv_info["type"] == "mem"
|
102
|
+
|
103
|
+
if dv_info["type"] == "reg":
|
104
|
+
color_node = color_node + " " + dv_info["reg_name"]
|
105
|
+
if dv_info["type"] == "mem":
|
106
|
+
color_node = color_node + " *(" + dv_info["base"]
|
107
|
+
if dv_info["index"] != "None":
|
108
|
+
color_node += f"{dv_info['scale']}*{dv_info['index']}"
|
109
|
+
if dv_info["offset"] > 0:
|
110
|
+
color_node += f"{dv_info['offset']}"
|
111
|
+
color_node += ")"
|
112
|
+
color_node += "_init"
|
113
|
+
self.du_graph.add_node(color_node)
|
114
|
+
# record mapping from this color to its creation info
|
115
|
+
color2genesis[hint.color] = (color_node, dv_info)
|
116
|
+
# and an edge between that color node and this instruction
|
117
|
+
self.du_graph.add_def_use(
|
118
|
+
color_node, hint.pc, color_node, dv_info, hint.color
|
119
|
+
)
|
120
|
+
else:
|
121
|
+
# this is a write of a computed value
|
122
|
+
# record mapping from this color to its creation info
|
123
|
+
color2genesis[hint.color] = (hint.pc, dv_info)
|
124
|
+
|
125
|
+
for hint in self.not_new_hints:
|
126
|
+
# not a new color. so its a flow
|
127
|
+
self.du_graph.add_node(hint.pc)
|
128
|
+
# can't be a def
|
129
|
+
assert "def" not in hint.message
|
130
|
+
# we should never see !new && !use since that is just a value copy
|
131
|
+
# assert hint.use
|
132
|
+
if not hint.use:
|
133
|
+
pass
|
134
|
+
else:
|
135
|
+
dv_info = hint_dv_info(hint)
|
136
|
+
(def_node, def_info) = color2genesis[hint.color]
|
137
|
+
self.du_graph.add_def_use(
|
138
|
+
def_node, hint.pc, def_info, dv_info, hint.color
|
139
|
+
)
|
140
|
+
|
141
|
+
# hint out the def-use graph
|
142
|
+
self.hinter.send(
|
143
|
+
hinting.DefUseGraphHint(
|
144
|
+
graph=nx.node_link_data(self.du_graph, edges="links"),
|
145
|
+
message="concrete-summary-def-use-graph",
|
146
|
+
)
|
147
|
+
)
|
148
|
+
|
149
|
+
with open("colorizer_def_use.dot", "w") as dot:
|
150
|
+
|
151
|
+
def writeit(foo):
|
152
|
+
dot.write(foo + "\n")
|
153
|
+
|
154
|
+
writeit("digraph{")
|
155
|
+
writeit(" rankdir=LR")
|
156
|
+
|
157
|
+
node2nodeid = {}
|
158
|
+
for node in self.du_graph.nodes:
|
159
|
+
# 4461 is pc
|
160
|
+
# {"id": 4461},
|
161
|
+
# An input color rsp is register
|
162
|
+
# {"id": "input color-1 rsp_init"},
|
163
|
+
node_id = f"node_{len(node2nodeid)}"
|
164
|
+
if type(node) is int:
|
165
|
+
# nodeinfo = ("instruction", f"0x{node}")
|
166
|
+
writeit(f' {node_id} [label="0x{node:x}"]')
|
167
|
+
else:
|
168
|
+
assert type(node) is str
|
169
|
+
foo = re.search("input color-([0-9]+) (.*)_init", node)
|
170
|
+
assert foo is not None
|
171
|
+
(cns, reg) = foo.groups()
|
172
|
+
cn = int(cns)
|
173
|
+
# nodeinfo = ("input", (cn, reg))
|
174
|
+
writeit(f' {node_id} [color="blue", label="input({reg})"]')
|
175
|
+
node2nodeid[node] = node_id
|
176
|
+
|
177
|
+
di = nx.get_edge_attributes(self.du_graph, "def_info")
|
178
|
+
ui = nx.get_edge_attributes(self.du_graph, "use_info")
|
179
|
+
for e in self.du_graph.edges:
|
180
|
+
if type(di[e]) is str:
|
181
|
+
foo = re.search("color-([0-9]+) (.*)_init", di[e])
|
182
|
+
(cns, reg) = foo.groups()
|
183
|
+
cn = int(cns)
|
184
|
+
assert cn == ui[e]["color"]
|
185
|
+
else:
|
186
|
+
assert di[e]["color"] == ui[e]["color"]
|
187
|
+
(src, dst, k) = e
|
188
|
+
cn = ui[e]["color"]
|
189
|
+
tl = ""
|
190
|
+
|
191
|
+
def i2s(inf):
|
192
|
+
lab = ""
|
193
|
+
if "type" in inf:
|
194
|
+
if inf["type"] == "reg":
|
195
|
+
lab = inf["reg_name"]
|
196
|
+
if inf["type"] == "mem":
|
197
|
+
lab = "["
|
198
|
+
if inf["base"] != "None":
|
199
|
+
lab += inf["base"]
|
200
|
+
if inf["index"] != "None":
|
201
|
+
lab += f'+{inf["scale"]}*{inf["index"]}'
|
202
|
+
if inf["offset"] != 0:
|
203
|
+
lab += f'+{inf["offset"]:x}'
|
204
|
+
lab += "]"
|
205
|
+
return lab
|
206
|
+
|
207
|
+
hl = i2s(ui[e])
|
208
|
+
tl = i2s(di[e])
|
209
|
+
|
210
|
+
writeit(
|
211
|
+
f' {node2nodeid[src]} -> {node2nodeid[dst]} [label="{cn}",headlabel="{hl}",taillabel="{tl}"]'
|
212
|
+
)
|
213
|
+
|
214
|
+
writeit("}\n")
|
215
|
+
|
216
|
+
def get_graph(self):
|
217
|
+
return self.du_graph
|
@@ -1,100 +1,190 @@
|
|
1
|
-
|
2
|
-
import
|
3
|
-
|
4
|
-
import networkx as nx
|
1
|
+
import sys
|
2
|
+
import typing
|
5
3
|
|
6
4
|
from .. import hinting
|
7
5
|
from . import analysis
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
# goal here is to summarize across multiple micro execution if two
|
8
|
+
# hints map to the same key then they are in same equivalence class so
|
9
|
+
# we elide away things that will be specific to a run like micro exec
|
10
|
+
# number, color (actual dyn value), ptr addresses, etc.
|
11
11
|
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
]
|
13
|
+
def compute_dv_key(hint):
|
14
|
+
if type(hint) is hinting.DynamicRegisterValueHint:
|
15
|
+
return (
|
16
|
+
("type", "reg"),
|
17
|
+
("pc", hint.pc),
|
18
|
+
("size", hint.size),
|
19
|
+
("use", hint.use),
|
20
|
+
("new", hint.new),
|
21
|
+
("reg_name", hint.reg_name),
|
23
22
|
)
|
23
|
+
elif type(hint) is hinting.DynamicMemoryValueHint:
|
24
|
+
return (
|
25
|
+
("type", "mem"),
|
26
|
+
("pc", hint.pc),
|
27
|
+
("size", hint.size),
|
28
|
+
("use", hint.use),
|
29
|
+
("new", hint.new),
|
30
|
+
("base", hint.base),
|
31
|
+
("index", hint.index),
|
32
|
+
("scale", hint.scale),
|
33
|
+
("offset", hint.offset),
|
34
|
+
)
|
35
|
+
elif type(hint) is hinting.MemoryUnavailableHint:
|
36
|
+
return (
|
37
|
+
("type", "mem_unavail"),
|
38
|
+
("pc", hint.pc),
|
39
|
+
("size", hint.size),
|
40
|
+
("is_read", hint.is_read),
|
41
|
+
("base", hint.base_reg_name),
|
42
|
+
("index", hint.index_reg_name),
|
43
|
+
("scale", hint.scale),
|
44
|
+
("offset", hint.offset),
|
45
|
+
)
|
46
|
+
elif type(hint) is hinting.EmulationException:
|
47
|
+
return (("type", "emu_fail"), ("pc", hint.pc), ("exception", hint.exception))
|
24
48
|
|
25
|
-
|
26
|
-
|
27
|
-
|
49
|
+
else:
|
50
|
+
# should never happen
|
51
|
+
assert (
|
52
|
+
(type(hint) is hinting.DynamicRegisterValueHint)
|
53
|
+
or (type(hint) is hinting.DynamicMemoryValueHint)
|
54
|
+
or (type(hint) is hinting.MemoryUnavailableHint)
|
55
|
+
or (type(hint) is hinting.EmulationException)
|
56
|
+
)
|
28
57
|
|
29
58
|
|
30
|
-
class ColorizerSummary(analysis.
|
59
|
+
class ColorizerSummary(analysis.Analysis):
|
31
60
|
name = "colorizer_summary"
|
32
|
-
description = "
|
61
|
+
description = "collect and summarize colorizer output across micro executions"
|
33
62
|
version = "0.0.1"
|
34
63
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
("prob", hint.prob),
|
44
|
-
("type", "reg"),
|
45
|
-
("reg_name", hint.reg_name),
|
46
|
-
]
|
47
|
-
elif type(hint) is hinting.DynamicMemoryValueProbHint:
|
48
|
-
dv_info = [
|
49
|
-
("prob", hint.prob),
|
50
|
-
("type", "mem"),
|
51
|
-
("base", hint.base),
|
52
|
-
("index", hint.index),
|
53
|
-
("scale", hint.scale),
|
54
|
-
("offset", hint.offset),
|
55
|
-
]
|
56
|
-
else:
|
57
|
-
assert 1 == 0
|
58
|
-
if hint.new:
|
59
|
-
# this is a new color so its either an input or a write of a computed value
|
60
|
-
assert "def" in hint.message
|
61
|
-
assert hint.color not in color2nodeDv
|
62
|
-
if hint.use:
|
63
|
-
assert "read" in hint.message
|
64
|
-
# color2nodeDv[hint.color] = (instr_node, dv_info)
|
65
|
-
color2nodeDv[hint.color] = (hint.pc, dv_info)
|
66
|
-
else:
|
67
|
-
assert "write" in hint.message
|
68
|
-
color2nodeDv[hint.color] = (hint.pc, dv_info)
|
69
|
-
# if its a read then
|
70
|
-
# hallucinate a node representing the creation of that color
|
71
|
-
if hint.use:
|
72
|
-
color_node = f"input color-{hint.color}"
|
73
|
-
du_graph.add_node(color_node)
|
74
|
-
color2nodeDv[hint.color] = (color_node, None)
|
75
|
-
# and an edge between that and this instruction
|
76
|
-
du_graph.add_def_use(
|
77
|
-
color_node, hint.pc, color_node, dv_info, hint.color
|
78
|
-
)
|
79
|
-
else:
|
80
|
-
# not a new color. so its a flow
|
81
|
-
assert "def" not in hint.message
|
82
|
-
# we should never see new && !use since that is just a value copy
|
64
|
+
def __init__(self, *args, **kwargs):
|
65
|
+
super().__init__(*args, **kwargs)
|
66
|
+
self.hint_list = []
|
67
|
+
self.exec_ids = set([])
|
68
|
+
self.hinter.register(hinting.DynamicRegisterValueHint, self.collect_hints)
|
69
|
+
self.hinter.register(hinting.DynamicMemoryValueHint, self.collect_hints)
|
70
|
+
self.hinter.register(hinting.MemoryUnavailableHint, self.collect_hints)
|
71
|
+
self.hinter.register(hinting.EmulationException, self.collect_hints)
|
83
72
|
|
84
|
-
|
85
|
-
|
86
|
-
|
73
|
+
def collect_hints(self, hint):
|
74
|
+
self.hint_list.append(hint)
|
75
|
+
self.exec_ids.add(hint.exec_id)
|
87
76
|
|
88
|
-
def
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
77
|
+
def run(self, machine):
|
78
|
+
# Establish true colors 1, 2, 3, ...
|
79
|
+
#
|
80
|
+
# The colors we have in hints are random initial reg or memory
|
81
|
+
# values or values computed from those. This means they don't
|
82
|
+
# correspond across micro-executions. We need them to do so if
|
83
|
+
# we are to summarize.
|
84
|
+
#
|
85
|
+
truecolors = set([])
|
86
|
+
dvh2truecolor = {}
|
87
|
+
color2truecolor = {}
|
88
|
+
for hint in self.hint_list:
|
89
|
+
if hasattr(hint, "color"):
|
90
|
+
if hint.new:
|
91
|
+
# This is a hint with a "new" color meaning the
|
92
|
+
# hint time is when the color was first
|
93
|
+
# observed. If we are trying to match up such new
|
94
|
+
# colors across micro executions, we do so by
|
95
|
+
# matching up the dv keys for them at this
|
96
|
+
# time of first observation.
|
97
|
+
dvk = compute_dv_key(hint)
|
98
|
+
dvh = hash(dvk) % ((sys.maxsize + 1) * 2)
|
99
|
+
if dvh not in dvh2truecolor:
|
100
|
+
# we need to establish a color for this dvh
|
101
|
+
next_color = 1 + len(truecolors)
|
102
|
+
truecolors.add(next_color)
|
103
|
+
dvh2truecolor[dvh] = next_color
|
104
|
+
# make sure to map every hint color to its true color
|
105
|
+
color2truecolor[hint.color] = dvh2truecolor[dvh]
|
106
|
+
else:
|
107
|
+
assert hint.color in color2truecolor
|
93
108
|
|
94
|
-
|
95
|
-
#
|
96
|
-
#
|
109
|
+
# use compute_dv_key to put keys into equiv classes
|
110
|
+
# which works for both new and not-new hints
|
111
|
+
# start off by collecting set of all such classes
|
112
|
+
all_hint_keys = set([])
|
113
|
+
hk_exemplar = {}
|
114
|
+
for hint in self.hint_list:
|
115
|
+
hk = compute_dv_key(hint)
|
116
|
+
all_hint_keys.add(hk)
|
117
|
+
# keep one exemplar for each equivalence class
|
118
|
+
if hk not in hk_exemplar:
|
119
|
+
hk_exemplar[hk] = hint
|
97
120
|
|
98
|
-
|
99
|
-
|
100
|
-
|
121
|
+
hint_keys_sorted = sorted(list(all_hint_keys))
|
122
|
+
|
123
|
+
# given the equivalence classes established by `compute_dv_key`, determine
|
124
|
+
# which of those were observed in each micro-execution
|
125
|
+
hk_observed: typing.Dict[
|
126
|
+
int, typing.Set[typing.Tuple[int, bool, str, bool, str, str, str, int, int]]
|
127
|
+
] = {}
|
128
|
+
for hint in self.hint_list:
|
129
|
+
if hint.exec_id not in hk_observed:
|
130
|
+
hk_observed[hint.exec_id] = set([])
|
131
|
+
# this hint key was observed in micro execution me
|
132
|
+
hk_observed[hint.exec_id].add(compute_dv_key(hint))
|
133
|
+
|
134
|
+
# get counts for hint across micro executions
|
135
|
+
hk_c = {}
|
136
|
+
for hk in hint_keys_sorted:
|
137
|
+
hk_c[hk] = 0
|
138
|
+
for exec_id in self.exec_ids:
|
139
|
+
for hk2 in hk_observed[exec_id]:
|
140
|
+
if hk == hk2:
|
141
|
+
hk_c[hk] += 1
|
142
|
+
|
143
|
+
for hk in hint_keys_sorted:
|
144
|
+
hint = hk_exemplar[hk]
|
145
|
+
if type(hint) is hinting.DynamicRegisterValueHint:
|
146
|
+
self.hinter.send(
|
147
|
+
hinting.DynamicRegisterValueSummaryHint(
|
148
|
+
pc=hint.pc,
|
149
|
+
reg_name=hint.reg_name,
|
150
|
+
color=color2truecolor[hint.color],
|
151
|
+
size=hint.size,
|
152
|
+
use=hint.use,
|
153
|
+
new=hint.new,
|
154
|
+
count=hk_c[hk],
|
155
|
+
num_micro_executions=len(self.exec_ids),
|
156
|
+
message=hint.message + "-summary",
|
157
|
+
)
|
158
|
+
)
|
159
|
+
if type(hint) is hinting.DynamicMemoryValueHint:
|
160
|
+
self.hinter.send(
|
161
|
+
hinting.DynamicMemoryValueSummaryHint(
|
162
|
+
pc=hint.pc,
|
163
|
+
size=hint.size,
|
164
|
+
base=hint.base,
|
165
|
+
index=hint.index,
|
166
|
+
scale=hint.scale,
|
167
|
+
offset=hint.offset,
|
168
|
+
color=color2truecolor[hint.color],
|
169
|
+
use=hint.use,
|
170
|
+
new=hint.new,
|
171
|
+
message=hint.message + "-summary",
|
172
|
+
count=hk_c[hk],
|
173
|
+
num_micro_executions=len(self.exec_ids),
|
174
|
+
)
|
175
|
+
)
|
176
|
+
if type(hint) is hinting.MemoryUnavailableHint:
|
177
|
+
self.hinter.send(
|
178
|
+
hinting.MemoryUnavailableSummaryHint(
|
179
|
+
is_read=hint.is_read,
|
180
|
+
size=hint.size,
|
181
|
+
base_reg_name=hint.base_reg_name,
|
182
|
+
index_reg_name=hint.index_reg_name,
|
183
|
+
offset=hint.offset,
|
184
|
+
scale=hint.bscale,
|
185
|
+
pc=hint.pc,
|
186
|
+
count=hk_c[hk],
|
187
|
+
num_micro_executions=len(self.exec_ids),
|
188
|
+
message=hint.message + "-summary",
|
189
|
+
)
|
190
|
+
)
|
@@ -19,7 +19,6 @@ from .hints import (
|
|
19
19
|
)
|
20
20
|
|
21
21
|
log = logging.getLogger(__name__)
|
22
|
-
hinter = hinting.get_hinter(__name__)
|
23
22
|
|
24
23
|
# Tell angr to be quiet please
|
25
24
|
logging.getLogger("angr").setLevel(logging.WARNING)
|
@@ -121,7 +120,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
121
120
|
size=size,
|
122
121
|
expr=str(expr),
|
123
122
|
)
|
124
|
-
hinter.
|
123
|
+
self.hinter.self(hint)
|
125
124
|
if self.halt_on_hint:
|
126
125
|
raise PathTerminationSignal()
|
127
126
|
else:
|
@@ -204,7 +203,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
204
203
|
start=start // 8,
|
205
204
|
end=end // 8,
|
206
205
|
)
|
207
|
-
hinter.
|
206
|
+
self.hinter.send(hint)
|
208
207
|
if self.halt_on_hint:
|
209
208
|
raise PathTerminationSignal()
|
210
209
|
else:
|
@@ -226,7 +225,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
226
225
|
access="read",
|
227
226
|
expr=str(expr),
|
228
227
|
)
|
229
|
-
hinter.
|
228
|
+
self.hinter.send(hint)
|
230
229
|
if self.halt_on_hint:
|
231
230
|
raise PathTerminationSignal()
|
232
231
|
else:
|
@@ -288,7 +287,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
288
287
|
end=end,
|
289
288
|
expr=str(expr),
|
290
289
|
)
|
291
|
-
hinter.
|
290
|
+
self.hinter.send(hint)
|
292
291
|
bad = True
|
293
292
|
if bad and good:
|
294
293
|
log.error("Write was complete and partial; your labels overlap.")
|
@@ -317,7 +316,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
317
316
|
access="write",
|
318
317
|
expr=str(expr),
|
319
318
|
)
|
320
|
-
hinter.
|
319
|
+
self.hinter.send(hint)
|
321
320
|
if self.halt_on_hint:
|
322
321
|
raise PathTerminationSignal()
|
323
322
|
else:
|
@@ -362,7 +361,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
362
361
|
size=val.get_size(),
|
363
362
|
label=label,
|
364
363
|
)
|
365
|
-
hinter.
|
364
|
+
self.hinter.send(hint)
|
366
365
|
|
367
366
|
if label in fda.fda_labels:
|
368
367
|
log.error(
|
@@ -420,7 +419,7 @@ class FieldDetectionMixin(underlays.AnalysisUnderlay):
|
|
420
419
|
filt.deactivate()
|
421
420
|
|
422
421
|
|
423
|
-
class FieldDetectionFilter(analyses.
|
422
|
+
class FieldDetectionFilter(analyses.Analysis):
|
424
423
|
"""Secondary field definition analysis.
|
425
424
|
|
426
425
|
This picks up patterns that aren't noticeable from any
|
@@ -14,7 +14,7 @@ class MallocModel(state.models.Model):
|
|
14
14
|
platform = platforms.Platform(
|
15
15
|
platforms.Architecture.X86_64, platforms.Byteorder.LITTLE
|
16
16
|
)
|
17
|
-
abi = platforms.ABI.
|
17
|
+
abi = platforms.ABI.NONE
|
18
18
|
|
19
19
|
_arg1_for_arch = {
|
20
20
|
platforms.Architecture.AARCH64: "x0",
|
@@ -201,7 +201,7 @@ class FreeModel(state.models.Model):
|
|
201
201
|
platform = platforms.Platform(
|
202
202
|
platforms.Architecture.X86_64, platforms.Byteorder.LITTLE
|
203
203
|
)
|
204
|
-
abi = platforms.ABI.
|
204
|
+
abi = platforms.ABI.NONE
|
205
205
|
|
206
206
|
def __init__(self, address: int):
|
207
207
|
super().__init__(address)
|