Skip to main content

SysPlant - Your syscall factory

Project description

..:: SysPlant ::..

Your Syscall Factory (feat. Canterlot's Gate)

Canterlot's Gate

PyPI version Supported Python versions Build Status Project Licence PyPI downloads Code Quality MCP Server Code style: Black Documentation Status

SysPlant is a python generation tool of the currently known syscall hooking methods. It currently supports following gates (aka: iterators):

  • Hell's Gate : Lookup syscall by first opcodes
  • Halos's Gate : Lookup syscall by first opcodes and search nearby if first instruction is a JMP
  • Tartarus' Gate : Lookup syscall by first opcodes and search nearby if first or third instruction is a JMP
  • FreshyCalls : Lookup syscall by name (start with Nt and not Ntdll), sort addresses to retrieve syscall number
  • SysWhispers2 : Lookup syscall by name (start with Zw), sort addresses to retrieve syscall number
  • SysWhispers3 : SysWhispers2 style but introduce direct/indirect/random jump with static offset
  • Canterlot's Gate ! :unicorn: :rainbow: (from an initial idea of MDSEC article) but who was missing a pony name : Lookup syscall using Runtime Exception Table (sorted by syscall number) and detect offset to syscall instruction for random jumps.
  • Custom Allows you to choose an iterator and a syscall stub method (direct / indirect / random / egg_hunter) which describe the way your NtFunctions will be effectively called.

:warning: DISCLAIMER
Please only use this tool on systems you have permission to access.
Usage is restricted to Pentesting or Education only.
All credits are based on my own research, please feel free to claim any method if I made mistakes...


Introduction

This personal project aims to be a simple tool to better understand & generate different syscall retrieval methods, and being able to play with direct / indirect / egg_hunter syscall stub. The first goal was to get my hands into NIM and then it overflow to C and Rust :wink: ...
SysPlant has been developped for Linux users, some stuff might be broken within Windows or Mac. PR are welcome if you found anything that does not work as expected.

Supported Languages

Language Status Cross-compile from Linux
NIM :white_check_mark: Stable nim c -d=release -d=danger -d=strip --opt=size -d=mingw --cpu=amd64
C :white_check_mark: Stable x86_64-w64-mingw32-gcc -Wall -s -static -masm=intel
Rust :white_check_mark: Stable cargo build --release --target x86_64-pc-windows-gnu

MCP Server

SysPlant ships with a built-in Model Context Protocol (MCP) server, allowing AI coding assistants (Claude Code, Cursor, Windsurf, etc.) to generate syscall code directly from their chat interface.

# stdio (default — plug into your AI client)
python bridge_mcp_sysplant.py

# SSE or Streamable HTTP for web-based clients
python bridge_mcp_sysplant.py --transport sse --port 9090

See the full guide: Sysplant as a MCP server

General usage

$ sysplant -h

usage: main.py [-h] [--debug | --verbose | --quiet] {list,generate} ...

..:: SysPlant - Your Syscall Factory ::..

positional arguments:
  {list,generate}

options:
  -h, --help       show this help message and exit

Output options:
  --debug          Display all DEBUG messages upon execution
  --verbose        Display all INFO messages upon execution
  --quiet          Remove all messages upon execution
$ sysplant generate -h

usage: main.py generate [-h] [-x86 | -wow | -x64] [-nim | -c | -rust]
                        [-p {all,donut,common} | -f FUNCTIONS] [-x] -o OUTPUT
                        {hell,halo,tartarus,freshy,syswhispers,syswhispers3,canterlot,custom}
                        ...

options:
  -h, --help            show this help message and exit
  -x, --scramble        Randomize internal function names to evade static analysis
  -o OUTPUT, --output OUTPUT
                        Output path for generated file

Architecture options:
  -x86                  Set mode to 32bits
  -wow                  Set mode to WoW64 (execution of 32bits on 64bits)
  -x64                  Set mode to 64bits (Default True)

Language options:
  -nim                  Generate NIM code (Default: true)
  -c                    Generate C code
  -rust                 Generate Rust code

Syscall options:
  -p {all,donut,common}, --preset {all,donut,common}
                        Preset functions to generate (Default: common)
  -f FUNCTIONS, --functions FUNCTIONS
                        Comma-separated functions

Example output

Here is an example of C syscall generation using Canterlot's Gate iterator:

$ sysplant generate -c -o syscalls.c canterlot

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠶⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⣀⡀⠀⢀⣠⣤⣴⣶⣶⡦⠤⢤⣤⣀⣀⣼⠀⠀⡽⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠫⣯⠙⡟⢿⣿⣿⡿⠁⠀⢠⣾⣿⣿⣿⡿⠀⠀⢹⠘⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣼⣿⣷⣧⡀⢱⠈⠀⠀⠀⣿⣿⣿⣿⣿⡀⠀⠀⢸⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  ⠀⠀..:: SysPlant - Your Syscall Factory ::..
⠀⣼⣿⣿⣿⣿⣿⣿⡄⢀⣀⣠⣿⣿⣿⠿⢿⣷⣤⡀⠈⠀⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢠⣿⣿⣿⣿⣿⣿⠿⠛⠉⠉⠀⡇⣾⣿⣦⣀⣿⡄⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀              Sysplant (2023) - 0x42en
⢸⣿⣿⣿⠿⢯⣷⢄⠀⠀⠀⠀⡄⢻⣿⣯⣻⣿⡧⠄⠀⢸⠀
⠘⣿⠟⠁⠀⠚⢻⣦⣱⣄⠀⠀⢣⠈⠛⣽⣿⠿⠭⠀⣠⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡤⠶⠶⠶⠶⢤⣄⡀⠀⠀⠀⠀⠀ Canterlot's Gate (2022) - @MDSecLabs
⠀⠁⠀⠀⠀⠀⠀⠻⣿⣿⠀⠀⠈⠂⠀⠀⢀⣄⣠⣴⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠶⠋⠁⠀⠀⠀⠀⠀⠀⠀⠉⠳⢦⡀⠀                            @0x42en
⠀⠀⠀⠀⠀⠀⠀⠀⣸⠋⠄⢠⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⡴⠃⠀⣠⣤⣶⣶⣾⣶⣶⣦⣄⠀⠀⠀⠹⣆⠀⠀⠀⠀  Syswhispers3 (2022) - @klezVirus
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠲⠴⠯⠤⠤⢶⢾⣿⣿⣿⣿⣿⠏⠷⣄⢀⣀⣀⣀⡀⣼⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠸⣧⠀⠀   Syswhispers2 (2021) - @Jackson_T
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠏⠈⠉⣡⣾⣿⠏⠀⢰⣿⠉⣩⠀⠉⢙⣿⡿⠛⠉⠉⠙⠛⢿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⢻⣇⠀                         @modexpblog
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡟⠀⠀⣿⣿⡿⠋⠀⢀⣾⡿⠀⣉⣀⣇⠘⠋⣿⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⡆⠀⠀⢸⣿⡆ Tartarus' Gate (2021) - @trickster0
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠘⢯⡀⠀⢀⣾⣿⠇⣴⠨⣿⣿⡯⠀⢸⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣷    Halo's Gate (2021) - @Sektor7net
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡆⠀⠀⠀⠈⠻⢦⣾⣿⠏⠀⠈⢈⣝⡟⠁⣶⣾⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⡀   FreshyCalls (2020) - @crummie5
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡀⢄⣀⡀⠀⠀⠉⠁⠀⠰⣄⠀⠁⠀⠀⢀⡏⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⠃⠀⠀⣸⣿⣿⡇   Hell's Gate (2020) - @RtlMateusz
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⡀⢹⠁⠀⢠⠶⠤⠤⢴⡾⢦⡀⠀⠀⣼⠦⡄⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⠀⠀⠀⣿⣿⣿⠇                        @am0nsec
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⠇⠀⠀⢸⡄⠀⠀⠀⠙⢆⠙⢦⡀⠀⠀⠙⣦⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⡇⠀⠀⢰⣿⡿⠋⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡟⠀⠀⠀⡟⢻⡀⠀⠀⠀⠈⢳⡀⢳⡀⠀⠀⠈⢧⡀⠀⠀⠀⠀⠀⣿⣿⣿⠁⠀⢀⣼⠟⠁⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡞⠀⠀⠀⠀⡇⠀⢧⠀⠀⠀⠀⠀⢷⠀⢳⠀⠀⠀⠈⢧⠀⠀⠀⠀⢀⣿⣿⡏⢀⣴⠟⠁⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡞⠀⠀⠀⠀⢸⠇⠀⠸⡆⠀⠀⠀⠀⢸⠀⢸⡇⠀⠀⠀⠘⣧⠀⠀⠀⢸⣿⣿⡷⠛⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡞⠀⠀⠀⠀⠀⣾⠀⠀⠀⣧⠀⠀⠀⠀⢸⠀⠀⡇⠀⠀⠀⠀⢸⡆⠀⠀⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠎⠀⠀⠀⠀⠀⣰⠇⠀⠀⠀⣿⠀⠀⠀⠀⣏⣀⣸⠇⠀⠀⠀⠀⠀⣷⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠤⣤⣤⣤⡤⠴⠛⠛⠛⠛⠉⠁⠀⠀⠀⠀⠈⠉⢿⣄⣀⣠⣤⡤⠶⠋⠀⠀⠀⠀⠀⠀⠀⠀


[+] Summary of params used
        . Language: C
        . Architecture: x64
        . Selected syscall iterator: canterlot
        . Selected syscall caller stub: random
        . Common supported functions selected
        . Randomize internal function: False
[+] Syscall file written to syscalls.c.h

What is iterator option ?

Sysplant is based on existing mechanisms for syscall number and addresses retrieval. I do not claim any of their discovery, I just harmonize all this methods in a single tool to be able to generate them easily using templates. These mechanisms are called iterator, if you look at the code you'll probably understand why :wink:
If you want to go further in the explanations of what is a syscall ? you should check @Alice Climent blogpost about syscalls techniques

What is method option ?

Once your iterator has been choosen you can then specify a method option based on the existing way to call syscalls. All the iterator are supported which let you select whatever you want as a final syscall stub.

  1. Direct: the syscall is made directly in the Sysplant ASM call. You only need the syscall number but AV/EDR might see you...
  2. Indirect: the Sysplant ASM call jump to the begining of Ntdll stub. You only need syscall address and no longer call syscall in your code but AV/EDR might hook these functions
  3. Random: the Sysplant ASM call jump to a random syscall instruction of Ntdll stubs. You need the syscall number and 1 syscall instruction address. You then no longer call syscall in your code and can avoid hooked functions.
  4. Egg Hunter: the inline syscall instruction is replaced by a random 8-byte marker (the egg). At runtime, call SPT_SanitizeSyscalls() before any Nt* function to scan the .text section and patch every egg back to syscall; ret. This avoids static signatures on the 0F 05 opcode while keeping direct-call performance.

Sysplant Stubs

Documentation

I've tried to keep an up to date documentation, so please READ THE DOC. You will find there many information about the tool's usages and a complete description of the classes and methods.

Some specifics usages are described:

Credits

Massive shout-out to these useful projects that helps me during this journey, or individuals for their reviews

:construction: TODO

This project is in WIP state...
Some PR & reviews are more than welcome :tada: !

  • Add internal names randomization
  • Setup documentation
  • Setup tests
  • Add x86 support
  • Add WoW64 support
  • Setup NIM templates
  • Setup C templates
  • Setup Rust templates
  • Setup Go / CPP / C# / Whatever templates

License

This project is licensed under the GPLv3 License, for individuals only. If you want to integrate this work in your commercial project please contact me through 0x42en[at]gmail.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sysplant-0.5.0.tar.gz (166.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sysplant-0.5.0-py3-none-any.whl (208.6 kB view details)

Uploaded Python 3

File details

Details for the file sysplant-0.5.0.tar.gz.

File metadata

  • Download URL: sysplant-0.5.0.tar.gz
  • Upload date:
  • Size: 166.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sysplant-0.5.0.tar.gz
Algorithm Hash digest
SHA256 73df71eea00317a46d4896d48c771429f5959f8a625f52de1026a03e293d60ce
MD5 e4fe2c543aff26d37898a710519255e2
BLAKE2b-256 8c00ba74f9181078c5d049137df054918e03d3eb3b803eca70648f62cc8bc507

See more details on using hashes here.

File details

Details for the file sysplant-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: sysplant-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 208.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sysplant-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ca4f78b642d7355a954b0e56164d8a3ac6c6c1b961bbd01bb24f38530779969
MD5 04a54a20a1b408709fd672c262f245be
BLAKE2b-256 6265ef42c7beb7b7eaa81517c02520cfc201e73312dcbaa8db68d40e1bc7e7a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page