Signed and unsigned modules

A program and a library each have an unsigned form and a signed form, so four file kinds appear:

Extension What it is Signed
.elf A program (an executable). No
.self A program wrapped in a signed container. Yes
.prx A library or module. No
.sprx A library or module wrapped in a signed container. Yes

.prx and .sprx are libraries: you load one at run time or link against it. .elf and .self are programs: the application’s eboot.bin is one. The leading s marks the signed form of each.

Unsigned and signed

An unsigned file is a plain ELF. The linker produces this form: an eboot.bin is an ELF program, and a library the linker builds is a .prx, also an ELF.

A signed file wraps that ELF in a container: a header, a segment table, the ELF header and program headers, extended information, and the program’s segment data. There are two signed forms:

  • Developer-accepted (readable). The container’s digest and signature slots are zero-filled and its segment data is plaintext. A development console accepts it. The toolchain produces and reads this form.
  • Retail (encrypted). The container is signed with a certificate and its segment data is encrypted. A retail console requires this form. Its contents cannot be read without its key, so the tools report the form but cannot open it.

Which form a console runs

A development console runs an unsigned ELF wrapped in a developer-accepted signed container. A retail console runs only a retail signed, encrypted container.

The normal build produces an unsigned ELF, and the packager wraps it in a developer-accepted signed container while it assembles the package. You rarely sign a file by hand; you do so only to produce a loose .self or .sprx outside a package.

Reading any readable form

The inspector and the module reader take either a plain ELF or a developer-accepted signed container. A signed container is unwrapped to its ELF first, so a .sprx reads the same way as a .prx:

sharpprospero-bindgen elf --file mylib.sprx
sharpprospero-bindgen prx --module mylib.sprx --inspect

The elf command prints the container line so the form is clear:

File:      mylib.sprx
Container: signed (.self / .sprx)
Class:     ELF64
Type:      SCE dynamic module

self --inspect reports which of the forms a file is, including a retail encrypted container it cannot open:

sharpprospero-bindgen self --inspect --file mylib.sprx

Converting between the forms

sharpprospero-bindgen self --sign    --in app.elf  --out app.self
sharpprospero-bindgen self --extract --in app.self --out app.elf

self --sign wraps an unsigned ELF in a developer-accepted signed container. --app-version, --fw-version and --authority set the extended-info fields (hexadecimal); --no-normalize keeps the ELF header exactly as supplied instead of adjusting the machine, OS/ABI and type for the module loader.

self --extract recovers the ELF from a developer-accepted signed container. A signed container stores only the loadable program segments, so the recovered ELF carries the same headers and loadable content, which is what the inspector reads; it is not a byte copy of the original file, because section headers and the padding between segments are not stored.

A retail signed, encrypted container cannot be signed or extracted here: signing it needs a certificate, and extracting it needs its key.


Copyright © SvenGDK 2026. Distributed under the GPL-3.0-or-later license.

This site uses Just the Docs, a documentation theme for Jekyll.