8000 GitHub - triskellib/triskel: A graphing library for Control Flow Graphs
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

triskellib/triskel

Repository files navigation

Shows a black logo in light color mode and a white one in dark color mode.

PyPI - Version Discord

Triskel is a Control Flow Graph (CFG) layout engine. It provides you with coordinates to draw CFGs in your reverse-engineering tools.

  • CFG specific layout, emphasizing Single Entry Single Exit Regions
  • Python bindings
  • Export to PNG / SVG (with cairo)
  • DearImgui integration
  • LLVM integration

Quick start

Python

$ pip install pytriskel
from pytriskel.pytriskel import *

builder = make_layout_builder()

# Build the graph
n1 = builder.make_node("Hello")
n2 = builder.make_node("World")
builder.make_edge(n1, n2)

# Measure node size using font size
png_renderer = make_png_renderer()
builder.measure_nodes(png_renderer)

# Export an image
layout = builder.build()
layout.save(png_renderer, "out.png")

C++

#include <triskel/triskel.hpp>

int main(void) {
    auto builder  = triskel::make_layout_builder();

    auto n1 = builder->make_node("Hello");
    auto n2 = builder->make_node("World");
    builder->make_edge(n1, n2)

    auto renderer = triskel::make_svg_renderer();
    builder->measure_nodes(renderer)
    auto layout   = builder->build();

    layout->render_and_save(*renderer, "./out.svg");

    return 1;
}

Theory

Triskel is the implementation for the paper Towards better CFG layouts.

The key idea behind Triskel is to split the CFG into Single Entry Single Exit regions. We are then able to layout each region taking advantage of a divide and conquer approach.

Walkthrough

Initially we have a directed graph

Directed graph

The first step involves identifying Single Entry Single Exit (SESE) regions. (See the implementation here: sese.cpp) In the diagram, the region is in blue. Notice how a single edge enters and exits the blue border.

SESE region identification

We can then split each region out of the graph. At this step we have multiple smaller directed graphs. Note that how in the graph of the SESE region, we had to add 2 virtual nodes to represent the entry and exit points. In the other graph, we added an additional node to represent the region (still in blue).

Splitting the graph

The next step involves laying out each SESE region's graph using Sugiyama algorithm (See the implementation here: sugiyama.cpp). Note how we have to layout the SESE region first in order to know the coordinates of the blue node.

Divide and conquer

Finally, we can superimpose the layouts to obtain the final layout.

Final layout

Compilation

Triskel relies on the following dependencies (the provided binaries also have their own dependencies)

Triskel can then be compiled with cmake

$ git clone https://github.com/triskeles/triskel
$ cd triskel
$ cmake -B build
$ cmake --build build

You can then link to Triskel

target_link_libraries(foo PRIVATE triskel)

CMake options

To compile with all options and external dependencies check the dockerfile.

ENABLE_LLVM

Adds LLVM integration.

This also adds LLVM 19 as a dependency.

ENABLE_IMGUI

Adds ImGui integration, used for making GUIs.

This adds the following dependencies:

ENABLE_CAIRO

Adds Cairo integration, used for exporting images.

Binaries

Triskel comes with many example binaries to help illustrate usage.

These binaries all require an additional dependency:

Used for testing and evaluation.

This binary lays out each function in an LLVM module and outputs a CSV containing performance reviews.

It can also be used on a single function to analyze the lay out with perf.

Dependencies

This binary only requires triskel built with ENABLE_LLVM=ON.

An example implementation of a GUI using Dear ImGui.

This application has a very limited disassembler for x64 binaries.

Dependencies

This binary requires triskel built with ENABLE_LLVM=ON and ENABLE_IMGUI=ON.

It also needs LIEF and Capstone for the disassembler.

A binary that generates images for CFGs using cairo.

Dependencies

This binary requires triskel built with ENABLE_LLVM=ON and ENABLE_CAIRO=ON.

It also requires capstone and LIEF

Python bindings

You can download the python bindings using pip:

$ pip install pytriskel

Contact

Cite Triskel

@inproceedings{royer:hal-04996939,
  AUTHOR = {Royer, Jack and Tronel, Fr{\'e}d{\'e}ric and Vin{\c c}ont, Ya{\"e}lle},
  TITLE = {{Towards Better CFG Layouts}},
  BOOKTITLE = {{Workshop on Binary Analysis Research 2025}},
  ADDRESS = {San Diego (CA), United States},
  MONTH = Feb,
  YEAR = {2025},
  URL = {https://hal.science/hal-04996939},
  DOI = {10.14722/bar.2025.23011},
}
0