A C# SDK and toolchain for building both application modules and payloads that run on the console. Write everything in C#; the toolchain compiles it ahead of time, links it with its own linker, and produces either an installable package or a position-independent ELF — no separate runtime, linker, or stub library needed. A build requires only the .NET 10 SDK.
An application module compiles to a self-contained eboot.bin packed into an installable *.pkg.
flowchart LR
A[C# source] -->|NativeAOT compile| B[ELF object]
B -->|SDK linker| C[eboot.bin]
C -->|container wrap| W[Signed module]
W -->|packager| D[*.pkg]
- Compile — NativeAOT compiles the C# to a self-contained x86_64 ELF object. On Windows the build runs this step through WSL automatically.
- Link — the SDK linker supplies its own start object, a compatibility object, and stubs for every device-service import.
- Wrap — the module goes into the signed container the loader expects.
- Package — the packager assembles the
eboot.bin,sce_sysmetadata, andsce_modulelibraries into an installable*.pkg(or a plain folder with-Output Folder).
A payload compiles to a position-independent .elf that a loader maps into a running process over the
network. No packaging step — just send it.
flowchart LR
A[C# source] -->|NativeAOT compile| B[ELF object]
B -->|SDK linker| C[payload.elf]
C -->|payload --send| D[Running on device]
- Compile — same NativeAOT step as application modules.
- Link — the linker produces a position-independent
.elfwith the CRT start object, which provides the kernel log, the raw syscall gateway, and the pipe-primitive kernel access. - Deploy —
payload --sendpushes the.elfto a loader listening on the device.
The payload SDK provides the full kernel access surface (process walk, credential escalation, virtual memory, page tables), filesystem and mount operations, POSIX I/O, networking, bypass hooks, multi-firmware offsets (FW 1.00 through 12.70), and service daemons. See Modules and payloads for when each form is the right choice.
- .NET 10 SDK (Windows or Linux, x64 only).
- The compile step runs on Linux; on Windows the build runs it through WSL automatically.
Run pwsh doctor.ps1 to check the environment. See docs/setup.md for the full install.
Check the setup and build the SDK:
pwsh doctor.ps1
dotnet build SharpProspero.slnx
cp -r samples/prospero-app MyGame
setx SHARPPROSPERO_ROOT "<this folder>"
pwsh $SHARPPROSPERO_ROOT/build/build-app.ps1 -ProjectPath MyGame/SampleApp.csproj
The application itself is a few lines:
using SharpProspero.Application;
using SharpProspero.Graphics;
internal sealed class HelloApp : ProsperoApp
{
protected override void OnFrame(FrameContext context)
{
Surface surface = context.Surface;
surface.Clear(Color.FromRgb(0x0E, 0x11, 0x16));
surface.DrawTextCentered("Hello from C#", 500, 5, Color.White);
}
}
internal static class Program
{
private static void Main()
{
using var app = new HelloApp();
app.Run();
}
}cp -r samples/prospero-payload-echo MyPayload
pwsh $SHARPPROSPERO_ROOT/build/build-app.ps1 -ProjectPath MyPayload/SampleApp.csproj -Payload
A minimal payload:
using System.Runtime.InteropServices;
using SharpProspero.Payload;
namespace SampleApp;
internal static unsafe class Program
{
[UnmanagedCallersOnly(EntryPoint = "__managed__Main")]
public static int Main(void* args)
{
PayloadCrt.Klog("hello from payload\n\0"u8);
return 0;
}
}See docs/getting-started.md for the full walkthrough.
| Command | What it does |
|---|---|
link |
Link objects into an eboot.bin, a .prx library, or a payload .elf. |
prx |
Read a .prx or .sprx, list its exports, and generate a C# wrapper. |
elf |
Inspect an ELF or signed module: segments, sizes, symbols, strings, and strip. |
self |
Report a file's form, sign an ELF into its container, or extract back to ELF. |
param |
Check and apply application metadata (sce_sys/param.json). |
gnf |
Build a GNF texture from PNG, QOI, TGA, or BMP (with resize and sRGB). |
vag |
Convert WAV to VAG or VAG to WAV. |
shader |
Report a compiled shader's kind, version, sizes, and register usage. |
payload |
Send a built payload .elf to a loader over the network. |
nid |
Compute the export identifier for a symbol name. |
stub |
Build an import library for a module from a name list. |
crt |
Write the CRT start object. |
compat |
Write the compatibility object. |
diff |
Report exports added, removed, and moved between two modules. |
modules |
Check that every required module ships with the application. |
sysver |
Settle the system version against the modules the application ships. |
offsets |
Dump a module's export identifiers and addresses. |
retarget |
Change the system version a module records. |
Run any command with --help for its full options. See docs/commands.md for every
command grouped by task.
Start here:
- Getting started — from nothing to a running module.
- Setup — the full install for Windows and Linux.
- Application Modules — the API surface for homebrew titles.
- Payloads — the kernel access surface, multi-firmware offsets, and the full payload API.
Then by area:
GPL-3.0-or-later. Copyright (C) SvenGDK 2026.