|
| 1 | +# -*- coding: UTF-8 -*- |
| 2 | +try: |
| 3 | + import angr |
| 4 | + import pygraphviz as pgv |
| 5 | + import networkx as nx |
| 6 | + _IMP = True |
| 7 | +except ImportError: |
| 8 | + _IMP = False |
| 9 | +import matplotlib.pyplot as plt |
| 10 | + |
| 11 | +from .__common__ import Binary, CACHE_DIR, COLORS, MIN_ZONE_WIDTH |
| 12 | +from ..__conf__ import save_figure |
| 13 | + |
| 14 | + |
| 15 | +_DEFAULT_ALGORITHM, _DEFAULT_ENGINE = "fast", "default" |
| 16 | +_ENGINES = ["default", "pcode", "vex"] |
| 17 | + |
| 18 | + |
| 19 | +def arguments(parser): |
| 20 | + parser.add_argument("executable", help="executable sample to be plotted") |
| 21 | + parser.add_argument("-a", "--algorithm", default=_DEFAULT_ALGORITHM, choices=["emulated", "fast"], |
| 22 | + help="engine for CFG extraction by Angr") |
| 23 | + parser.add_argument("-e", "--engine", default=_DEFAULT_ENGINE, choices=_ENGINES, |
| 24 | + help="engine for CFG extraction by Angr") |
| 25 | + return parser |
| 26 | + |
| 27 | + |
| 28 | +@save_figure |
| 29 | +def plot(executable, algorithm=_DEFAULT_ALGORITHM, engine=_DEFAULT_ENGINE, **kwargs): |
| 30 | + """ plot the Control Flow Graph (CFG) of an executable """ |
| 31 | + from math import ceil, log2 |
| 32 | + engine = {k: getattr(angr.engines, "UberEngine" if k != "pcode" else f"UberEngine{k.capitalize()}") \ |
| 33 | + for k in _ENGINES}[engine] |
| 34 | + project = angr.Project(executable, auto_load_libs=False, engine=engine) |
| 35 | + cfg = getattr(project.analyses, f"CFG{algorithm.capitalize()}")() |
| 36 | + labels, node_colors = {}, [] |
| 37 | + for node in cfg.graph.nodes(): |
| 38 | + labels[node] = f"{node.name}\n0x{node.addr:x}" if hasattr(node, "name") and node.name else f"0x{node.addr:x}" |
| 39 | + node_colors.append("red" if node.function_address == node.addr else "lightblue") |
| 40 | + n = max(10, min(30, ceil(log2(n_nodes := len(cfg.graph.nodes()) + 1) * 2))) |
| 41 | + plt.figure(figsize=(n, n)) |
| 42 | + nx.draw(cfg.graph, nx.kamada_kawai_layout(cfg.graph), font_size=8, with_labels=True, labels=labels, |
| 43 | + node_size=max(300, 15000 // n_nodes), node_color=node_colors) |
| 44 | + |
0 commit comments