Archive of https://github.com/blackbearreloaded/PS5-Lapy-JB-Daemon — Standalone homebrew jailbreak daemon for PS5. Mimics etaHEN's jailbreak-on-demand API. Multi-firmware (3.00 to 12.00) via ps5-payload-sdk + kstuff. No etaHEN required. https://github.com/blackbearreloaded/PS5-Lapy-JB-Daemon
  • C 61.6%
  • Python 36.1%
  • C++ 1.7%
  • Makefile 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
mpereiraesaa 5b8397b9f2
Merge pull request #47 from mpereiraesaa/codex/lapy-one-shot-elf
Retry inconclusive vnode root probes
2026-10-03 18:26:39 +02:00
docs Use signals for donor lifecycle when pipes are exhausted 2026-09-29 11:37:48 +02:00
examples Add cooperative owned-root elevation daemon for FW 12.02 2026-09-28 13:04:52 +02:00
extern/libhijacker/include Initial release : Lapy JB Daemon v1.2 multi-firmware standalone payload (3.00 -> 12.00) 2026-05-24 20:31:15 +02:00
source Retry inconclusive root layout probes 2026-10-03 18:25:41 +02:00
tests Retry inconclusive root layout probes 2026-10-03 18:25:41 +02:00
tools Retry inconclusive root layout probes 2026-10-03 18:25:41 +02:00
.gitignore build: add source-pinned legacy comparison and native elevation requirements 2026-09-27 17:15:53 +02:00
homebrew.js Initial release : Lapy JB Daemon v1.2 multi-firmware standalone payload (3.00 -> 12.00) 2026-05-24 20:31:15 +02:00
lapy_jb_daemon.elf Initial release : Lapy JB Daemon v1.2 multi-firmware standalone payload (3.00 -> 12.00) 2026-05-24 20:31:15 +02:00
LICENSE Initial release : Lapy JB Daemon v1.2 multi-firmware standalone payload (3.00 -> 12.00) 2026-05-24 20:31:15 +02:00
Makefile Retry inconclusive root layout probes 2026-10-03 18:25:41 +02:00
README.md Retry inconclusive root layout probes 2026-10-03 18:25:41 +02:00
README.txt Validate runtime layouts for SDK-supported firmware 2026-09-28 13:16:27 +02:00

PS5 Lapy JB Daemon — owned-root fork

This fork provides a resident elevation daemon for PS5 firmware supported by the payload SDK. It is intended for homebrew that repeatedly launches processes needing /data access, such as a launcher starting games. Only firmware 12.02 has been validated on a console. Other versions are experimental: the daemon checks its assumed kernel layout with native getgroups and a disposable child before changing a target, and refuses to proceed if the checks fail. The old backend is available only through the explicit make legacy target.

Legacy Lapy directly overwrites a process's root and jail pointers. Repeated use on our console was associated with a panic after roughly 20–29 elevations per boot. This daemon transfers two root vnode references obtained by native rfork into the target; native donor exit releases its displaced sandbox roots. It also requires the target to clone its own credentials before the request. See the design and evidence. The crash mechanism is strongly suggested by the evidence, but no kernel dump proved it.

Donor startup and release now use process signals and waitpid, with no per-request pipes. On FW 12.02, a fresh pipe could be created but writing one byte to it failed with ENOMEM after sustained use; the older daemon then lost its donor acknowledgement and exited. The signal-controlled candidate completed four cooperative /data elevations in that same boot while fresh pipe writes still failed. This avoids that immediate failure path; it does not identify or repair the kernel's pipe allocation problem.

Required cooperation in the homebrew

The request file is /download0/elevate_proc. It replaces the old etahen_jailbreak marker. In the same process that needs elevation, call seteuid(geteuid()) before creating other threads and before writing the request. Check its return value. Then write a JSON request containing that process's PID. The C example shows the minimal integration; the tested Hello World main shows the full request and /data read/write check.

if (seteuid(geteuid()) != 0)
    return -1; /* Do not request elevation. */
/* Now create /download0/elevate_proc containing {"PID":<getpid()>}. */

The same-UID call asks the kernel to give this homebrew process a private credential. Calling seteuid in the daemon would clone the daemon's credential, not the target's. The daemon rejects a target unless it sees the expected private credential, one thread, private filedesc and prison state. Marker consumption alone does not prove success: check actual /data access before using it. The title must enable downloadDataSize for /download0. Only run one Lapy daemon. Old homebrews must adopt the new protocol; this fork does not silently fall back to the legacy kernel writes.

Build and run

Use a PS5 payload SDK and a ps5log/1 client alongside this checkout:

PS5_PAYLOAD_SDK=/path/to/ps5-payload-sdk make check
PS5_PAYLOAD_SDK=/path/to/ps5-payload-sdk make owned-service

The ELF is build/owned_root_daemon-service/lapy-root-daemon.elf. Load it once via an ELF loader; it stays resident and watches PPSA* requests. For a bounded diagnostic build, pass --service --max-requests N to tools/build_owned_daemon.py. The daemon emits machine-readable ps5log/1 events, including completion and reference-balance fields.

Validation and limits

On one owned FW 12.02 PS5, a one-request build completed 32/32 consecutive launch → elevate → /data read/write → close cycles in one boot. Every cycle reported balanced root counters. A bounded resident build then handled 5/5 requests in one daemon process, with /data read/write confirmed after each. A later guarded resident request also passed. The runtime layout preflight then passed on 12.02 and another resident request completed with /data read/write. Those finite test ELFs and hashes are in the design record. The published unbounded service ELF is built from this source; it has not been exercised indefinitely.

The runtime check can reject a firmware whose layout or native reference behavior differs; passing that check is not a substitute for an attended repeatability test on that firmware. Other homebrews, multithreaded callers, concurrent daemons and unusual exit or exec paths are not established by these trials. Historical source research is in ELEVATION.md. License terms are in LICENSE.

One-shot elfldr helper

For a homebrew that already owns its startup flow, the same transaction can run as a one-request ELF helper instead of a resident daemon. The caller sends this ELF to the local elfldr listener on port 9021 and holds the connection open for the versioned prepare/result exchange. It must call seteuid(geteuid()) in the target process after the helper's prepare message; the helper validates the exact title and PID before applying the existing owned-root transaction. The helper exits after its response. This mode still requires the caller-side protocol implementation and is built for one exact title ID.

Build the helper and its release manifests with:

PS5_PAYLOAD_SDK=/path/to/ps5-payload-sdk \
  make owned-helper TARGET_TITLE=PPSA99995

The output is build/owned_root_helper-PPSA99995/lapy.elf. The directory also contains manifest.json for local build records and lapy-manifest.json for publishing alongside lapy.elf as release assets. The release manifest records the ELF and shared protocol hashes, target title, build mode, and the root_layout_probe_retry feature. Consumers should reject assets missing that feature or whose title, ELF digest, or protocol digest does not match.

On one FW 12.02 console, the helper builds with this feature completed 32/32 elevation attempts for PPSA99995, including 30 consecutive launcher launch/close cycles. Every attempt reported balanced root counters and the title confirmed /data access. In one of the 20 most recent cycles, an inconclusive first counter probe retried once and then completed successfully. Other firmware versions and titles remain unvalidated.