Skip to content

youkill081/steg-lang

Repository files navigation

Steg

Steg Logo

Hide code in images. Run them.

C++ CMake Plaforms License fr


Overview

Steg is much more than a steganography tool; it's a complete compilation toolchain whose target code isn't binary, but a PNG image !

Write code in Steg (high level language), compile it, and inject it silently into the pixels of an image. The resulting image is visually almost identical to the original, but executable with the StegVM interpreter !

   Steg Code (.steg) <- Your code !
        │
        ▼
  ┌─────────────────────────────────────────────────────┐
  │              Steg Compiler                          │
  │   Lexer → Parser → AST → Semantics → IR → Backend   │
  └─────────────────────────────────────────────────────┘
        │
        ▼
  StegASM Code  (.stegasm) <- You can also write directly in StegASM !
        │
        ▼
  ┌─────────────────────────────────────────────────────┐
  │                StegASM Assembly                     │
  └─────────────────────────────────────────────────────┘
        │
        ▼
  StegASM Bytecode
        │
        ▼
  ┌─────────────────┐        ┌──────────────┐
  │  Steganography  │ <----  │  PNG Image   │
  │  (injection)    │        │  (host)      │
  └─────────────────┘        └──────────────┘
        │
        ▼
  PNG Image  (executable) ← hidden program here
        │
        ▼
  ┌─────────────────┐
  │  Steg VM        │ <---- Interpreter
  └─────────────────┘

Demo

GIFs may take a little while to load


Load WolfenSteg from the image and play it.


Demo of Tetris (game created directly in StegASM)


Table of contents


Project component

Binary Description
Steg The unified entry point for the project allows launching Steg/StegASM, executing within images, and also building within images!
StegLSP LSP server for .steg files, directly connected to the steg compiler!

Although primarily built from scratch, the project incorporates a few external libraries as submodules :

  • stb - Read/Write pixels for steganography, also handle multiple image types
  • raylib - Graphics engine, windows, inputs...
  • lsp-framework - LSP server base framework
  • googletest - Testing framework

Compilation

CMake 4.0+ is required.

The program was designed for Windows and Linux and is cross-platform (created images are compatible with both platforms).
On Window it is recommended to use MinGW to have the best performance in the interpreter.

git submodule update --init --recursive
cmake -B build -DENABLE_INSTRUCTION_COUNTER=OFF
cmake --build build --config Release

Compilation options

Instruction counter

An instructions-per-second (IPS) counter is available. It displays every second, the number of instructions that have been executed.
It was designed to add as little overhead as possible, but it is disabled by default.
To enable it, just add the flag -DENABLE_INSTRUCTION_COUNTER=ON.


Usage - Steg

Steg is the main binary of the project. It plays a multitude of roles such as compiling or launching images.

USAGE:
  steg run <file.stegasm|file.steg> [-d]
  steg build <file.stegasm|file.steg> <input.png> <output.png>
  steg run_img <img.png>

OPTIONS:
  -d    Enable debug mode for compiler (Display, reg allocation, IR and AST code)

Run a program

Compiles and executes a source file directly, without using an image:

steg run mon_programme.steg
steg run mon_programme.stegasm

The launch is directly compatible with .steg and .stegasm files.

Build an executable image

Compiles a program (Steg or StegASM) and injects it into a PNG image:

steg build mon_programme.steg input.png output.png
steg build mon_programme.stegam input.png output.png

The input image does not have to be a .png but the output image must be a .png.

run an image

Extract and execute a program from an image :

steg run_img img.png
steg img.png # Short version

On Windows, it is possible to select "Run with" on the image to launch the program.

debug mode

the flag -d activates a full display of the compilation pipeline:

steg run mon_programme.steg -d
steg build mon_programme.steg input.png output.png -d

The program will display the following information

  • The generated IR
  • The register allocation
  • The assembler

Warning: Displaying this information can become very resource-intensive with large programs!


The steg language

Steg is the high-level language of the project. It is compiled into StegASM via a full compilation pipeline :

Lexer -> Parseur -> AST -> semantics analysis -> IR -> StegASM Backend 

Sources files use .steg extension.

A steg documentation is available here.


StegASM the low-level language

StegASM is the low-level language of the project. It is represents the instruction set available in the StegVM VM.
Heavily inspired by the "standard" assembler, it exposes the registers and instructions of StegVM.

Sources file use .stegasm extension.

A StegASM documentation is available here.


StegLSP - the language server

StegLSP is a LSP server for .steg files.
Thanks to this LSP server, you can have the following on most modern IDEs:

  • Syntax Coloring
  • Semantics Analysis -> flow control, types, parameters, etc...
  • Warnings : Like implicit conversions

Examples

WolfenSteg - Steg

wolfenSteg is a Ray-casting 3D game engine entirely written in Steg.
This is the technical showcase of the project, proving that the VM and the compilation chain can handle intensive mathematical calculations in real time.

WolfenSteg This image contains the game

Performance and capacity

  • Real-time ray-casting: The engine runs smoothly at 60 FPS.
  • Raw power: The StegVM VM achieves peak performance of 250 million instructions per second (IPS).

Gameplay :

  • Select a random level at game launch
  • Colision system and movement handling
  • Can open doors and go through them
  • Basic fighting system to kill enemies (you can switch weapons with the 1 - 2 - 3 - 4 keys)

Play

You can either launch the WolfenSteg.png image directly :

steg run_img ./examples/wolfensteg/wolfensteg.png

Or you can compile it yourself ! :

steg run ./examples/wolfensteg/WolfenSteg.steg

Tetris - StegASM

Tetris is the demonstration of StegASM.

Tetris

The code StegASM of the Tetris is available here : ./examples/tetris/tetris.stegasm

You can therefore launch the image directly :

steg run_img ./examples/tetris/tetris.png

Or compile it yourself :

steg run ./examples/tetris/tetris.stegasm

⚠️ Run the "run" commands from the repo root, otherwise the .stegasm imports will be invalid.

Thanks

Many thanks to Ewan Clein for the Steg logo design -> https://www.linkedin.com/in/ewan-clein-architecture/

About

Hide and execute code inside PNG images - A full compiler + VM Chain in C++

Topics

Resources

License

Stars

Watchers

Forks

Contributors