18 Commits
1.08b ... 2.3B

Author SHA1 Message Date
LM
55cfedcdac 2.3B Released 2025-09-04 21:26:38 -04:00
LightningMods
4051e18f02 small fix 2025-06-11 03:13:03 -04:00
LightningMods
a66823580b etaHEN update 2.2B
## New additions
- ALL PS4 cheats should now work now that ASLR is disabled
- Renamed Debug Settings to the etaHEN Toolbox in the settings menu and changed the icon
- Added a PS5 Game menu (named after webMAN) to the toolbox for those that dont want to use itemzflow
- Added a controller shortcuts menu with the following shortcuts (with more than one button combo option for each)
   - Cheats Menu
   - Toolbox
   - PS5 Games menu
   - Toggle Kstuff
- the Utilities menu has been changed to the Settings menu and is now below the Services menu
- Patched the systems game patch checker to not auto update games with etaHEN active
- Updated the Kstuff menu to include the option to pause the PS5 or PS4 sysents independently
- the download Cheats option will now check if its up to date instead of always just redownloading the whole repo everytime
- Added the ability to save remote play info to a USB if one is detected (both the encoded and decoded account ids)
- Added the option to disable the toolbox auto start in the rest mode options

## Fixes and Updates
- Updated Kstuff to 1.5
- Updated PS5Debug to v1.0b4 (6.xx support) by @CTN
- Fixed an Issue that would cause the etaHEN utility daemon to crash if malformed cheat .txt files were present
- etaHEN will now attempt to restart the home menu if loading the toolbox fails
- updated itemzflow self decrypter for 7.xx
- Improved etaHEN Startup time by 1-2 secs
- Updated & Improved lite mode
- Fixed an issue preventing people from enabling cheats after turning off lite mode
- Fixed an issue with Cheats not showing the full description for long descriptions
- [Dev/TestKits] the red activate banner will now only go away when the activation patches are present
- [Dev/TestKits] added activation patches for DevKit FW 3.21, 4.03, 4.51 and 5.50 and Testkit fw 4.03, 4.51, 6.50, 7.61
- Delete daemon crash logs on startup if available
- Updated the config.ini layout for the new additions
2025-06-10 22:45:32 -04:00
LightningMods
ea3b04a60f etaHEN updated to 2.1B
- Added the ability to pause/resume kstuff in the toolbox (Utilities section)
- Updated kstuff and etaHEN for 7.xx support
- Improved stability when auto loading the toolbox (new loading method, should be 20x more stable) requires kstuff, old method will be used as a fallback where kstuff or byepervisor isnt available
- Added more in-depth errors to DPIv2 by  @crayspn
- Fixed kstuff unnecessarily changing *kit target ids (causing devkits to default to release mode)
- Added the DBG0 IP address to the Home menu panel for devkits
- Fixed klog auto starting even when its disabled via toolbox/config
- removed creating unnecessary files when starting etaHEN (should slightly speed up start times)
- Added an option to reload cheats cache and auto add new cheats to the cache files
- Updated PS5Debug by GHEN and re-enabled PS5Debug for 5.xx
- Added a check to see if an operations like downloading the Store/Cheats or reloading the cheats cache is already in progress before starting a new operation
- Added an option to load etaHEN without kstuff (ADVANCED USERS ONLY) i.e cheats or plugins (a file named "no_kstuff" on USB root or /data/etaHEN/ will disable loading kstuff)
- added back PKG Installer patches for 2.xx and 3.xx-4.xx
2025-04-28 14:18:48 -04:00
LM
360e7c0d2d correct a few typos 2025-03-29 15:55:55 -04:00
LightningMods
28c4489a41 Fix showing the plugin auto start options 2025-03-29 01:13:03 -04:00
LightningMods
178499a10c [HOT FIX] temp. remove spoof patches for 3.xx and 4.xx 2025-03-28 19:06:25 -04:00
LightningMods
1d65834fa0 etaHEN 2.0B Official Release
- Added support (and updated kstuff) for 5.xx and 6.xx
- Added menu in the etaHEN toolbox for cheats (`/data/etaHEN/cheats`)
- Added a button to download cheats through the cheats menu when no game is open or no cheats were found for that game
- Added Spoofing features like installing higher fw fpkgs without actually spoofing the system version
- Added the ability to disable toolbox auto start through the toolbox itself or the `config.ini` in `/data/etaHEN` (re-enabling without rebooting requires Itemzflow 1.9+), you can also make the file `toolbox_auto_start` on your USB to disable the toolbox without editing the config
- Updated the toolbox injector to not freeze when being loaded without kstuff
- All internal payloads such as ps5debug and kstuff are now loaded by etaHEN itself instead of sending to the exploit
- Added The Direct package installer V2 (WebGUI version) to the services menu
- the PS5Debug option in the etaHEN toolbox can now load it on demand and without rebooting (disabling requires rebooting)
- PS5Debug was updated to 1.0b2
- PS5Debug has been disabled for 5.xx until a fix is released
- Added LMZA compression so the payload will fit on IoT devices with low storage like ESPs
- DPI by default is now disabled and instead DPIv2 is enabled
- Fixed a small issue causing the remote play menu to display 1 too more =
- Updated the toolbox loading message
- Fixed the /data in app sandboxes option for 3.xx/5.xx/6.xx Big thanks to @BestPig
- Added an *optional* experimental self decrypter for the itemzflow dumper
- Fixed an issue that would cause plugins to fail loading from USB
- Fixed rest mode (must disable the toolbox auto start BEFORE entering rest mode)
- Whitelisted FPKGi
2025-03-28 18:13:56 -04:00
LM
dbe87f90f8 Update README.md 2025-02-24 11:22:17 -05:00
LM
164ff0d5de Added info on enabling script execution 2025-02-16 08:53:48 -05:00
LM
5c55f98e6a Formatting fix 2025-02-15 20:56:46 -05:00
LightningMods
475b61824e Added a Windows Script for sending payloads over PowerShell 2025-02-15 15:00:02 -05:00
LM
9c6a7e858f Update idle sauce host link 2024-12-25 16:37:40 -05:00
LightningMods
73f3878b4d etaHEN 1.9B Release
- the elfldr plugin is no longer required for loading plugins (or anything)
- Added Byepervisor (By @PS5Dev) to etaHEN for 2.xx (auto triggers rest mode too)
- [2.xx ONLY] Added Kernel patches for mprotect, the dir_depth limit and MMAP RWX
- Removed the No longer needed Syscore patches
- Added a Lite mode (kstuff or HEN ONLY) mode
- Removed the DB triggers from etaHEN and moved them to itemzflow for all fws
- etaHEN daemon loading time decreased from 5-6 secs to 1 secs
- Shellcore FPKG Required FW patches By @Echo for 2.xx
- Added a Remote Play menu to the etaHEN toolbox (will activate the account for you)
- Added the external HDD menu to the etaHEN toolbox utilites section
- Added an Extras menu to the etaHEN toolbox utilites section which includes the NP enviroment and additional content manager
- Added a Plugin auto start menu (illusion cheats included with Itemzflow)
- etaHEN will now wait for kstuff to fully load before continuing
- Any Plugin not enabled via the Plugin auto start menu will NOT auto start when you load etaHEN
- Clicking the Install the Store button or loading plugins will no longer freeze until they are done, those are now done asynchronously
- after loading etaHEN the etaHEN toolbox will stop the home menu before injecting (see the notification)
- Improved stability when rebooting or shutting down the PS5
- Removed the Cheats menu to add it back later in the next update (ran out of time)
- Added React bundle (all FWs) & Self (only on 2.xx) decryption support to FTP
- etaHEN can now be loaded via Johns Elf loader (mostly for 2.xx since 4.xx requires kstuff being sent to 9020)
- Added support for the UMTX exploit
- Stability improvements for restarting and shutting down (without plugins enabled)
- a lot of changes made internally to etaHEN to focus on stability

- Added a Testkit menu which wont let retails in (for now)
  - Console Info Overlay
    - On [Custom]
    - On + APU Temp
    - On + Service Ports + temp
    - Off

   - Trial System Software Expiration overlay
    - Off
    - (ON) 1 Day left
    - (ON) 2 Days left
    - (ON) Expired

- Added TestKit privacy overlay, when etaHEN is active the serial number, model name, and MAC address in the overlay will be censored
2024-12-25 15:47:34 -05:00
LM
e64991612b Update README.md 2024-12-25 11:49:26 -05:00
LightningMods
792deaf844 new Icon 2024-12-24 16:17:16 -05:00
LM
f340624870 Merge pull request #22 from gorshco/patch-1
Update README.md
2024-10-29 14:33:45 -04:00
gorshco
aa9ca281d1 Update README.md
Removed duplicate SiSTR0 enrty
2024-10-25 11:36:16 -04:00
11 changed files with 797 additions and 27 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

View File

@@ -0,0 +1,525 @@
# PS5 Package Installation: Writeup
## Introduction
Years ago we got [Flatz's Writeup](https://flatz.github.io/) on Installing PKGs on the PS4, however, the same method no longer works on the PS5, so today I am carrying the torch and releasing an updated PKG Installation writeup for the PS5
## Prerequisites
This implementation requires one of the following privilege escalation methods:
1. **Auth ID Modification**: Modify the auth ID within the `struct ucred` authentication information to match ShellCore's identifier (`0x3800000000000010`)
2. **Other Options**:
- For FPKG applications: Utilize etaHEN's [Jailbreak IPC Command](https://github.com/etaHEN/etaHEN?tab=readme-ov-file#jailbreaking-an-app-fpkg-using-etahen-non-whitelist-method-network-required) functionality
- For integrated solutions: Leverage the automatic privilege handling via [etaHEN Plugins System](https://github.com/etaHEN/etaHEN-Plugins) or [ps5-payload-dev SDK](https://github.com/ps5-payload-dev/sdk)
## Module Requirements
The procedure necessitates loading and initializing the system module:
```
/system/common/lib/libSceAppInstUtil.sprx
```
Note: When developing for the etaHEN Plugin System or building ELF executables with the ps5-payload-dev SDK, this module dependency is automatically resolved when the SceAppInstallUtil stub is properly linked.
## Step 1, Identifying the problem
As established previously, Flatz's BGFT (Background File Transfer) methodology is incompatible with the PS5, with all `sceBgftServiceIntDownloadRegisterTaskBy*` function calls consistently returning error code `0x80990006 (SCE_BGFT_ERROR_NOT_SUPPORTED)` despite proper initialization. Tracing BGFT IPC calls within shellcore revealed that PS5 deliberately returns this error even with the correct authid, representing an intentional change rather than a simple implementation difference; having identified this change as the source of incompatibility, our investigation now shifts toward discovering the alternative package installation implementation that has replaced the previous BGFT methodology.
```cpp
uint FUN_0100ee70(Session *session,int user_id,int entitlement_type,char *id,char *package_type,
char *package_sub_type,char *content_url,char *content_name,char *icon_path,
char *sku_id,char *playgo_scenario_id,char *release_date,size_t package_size,
bgft_task_option_t options,uint slot,void *result) {
undefined auVar1 [32];
long lVar2;
pid_t pid;
uint uVar3;
uint uVar4;
bgft_download_param args;
lVar2 = __stack_chk_guard;
if (session == NULL) {
uVar4 = 0x80990050;
}
else {
pid = (*session->_vptr->getClientPid)(session);
uVar3 = check_authid(pid);
uVar4 = 0x80990007;
if (uVar3 == 1) {
args._60_4_ = 0;
args.content_url = content_url;
auVar1._8_8_ = icon_path;
auVar1._0_8_ = content_name;
auVar1._16_8_ = sku_id;
auVar1._24_8_ = 0;
args._24_32_ = auVar1 << 0x40;
args.options = options;
args.playgo_scenario_id = playgo_scenario_id;
args.release_date = release_date;
args.package_size = package_size;
args.user_id = user_id;
args.entitlement_type = entitlement_type;
args.id = id;
args.package_type = package_type;
args.package_sub_type = package_sub_type;
uVar4 = DownloadRegisterTaskByStorageEx(&args,result);
}
}
if (__stack_chk_guard == lVar2) {
return uVar4;
}
__stack_chk_fail();
}
uint DownloadRegisterTaskByStorageEx(bgft_download_param *param_1,void *param_2) {
printf("[BGFT] ERROR: [%d] ",0x18);
puts("NOT SUPPORTED API");
return 0x80990006;
}
```
## Step 2, what and where is the new function for installing PKGs
From extensive experience developing PS4 homebrew applications, I identified shellui as the component responsible for Debug Settings menu functionality, including package installation services. Initial reverse engineering targeted ShellUI's components through mono module analysis using DnSpy. This revealed the PS5's UI3 Settings implementation—a logical progression from UI (early PS4 firmware) to UI2 (later PS4 firmware). Within this framework, I located the critical PKG installer implementation, specifically the `ExecuteInstall` and `OnUpdate` mono functions with their associated data structures (`mTargetList` containing the package queue and `mInstallIndex` identifying the target package). While these functions expose the requisite installation APIs, it's important to note they cannot be invoked directly through conventional mono method calls, necessitating an alternative implementation approach.
```c#
private Task<int> ExecuteInstall()
{
return Task.Run<int>(delegate()
{
this.Lock();
AppInstUtilWrapper.SceAppInstallPkgInfo sceAppInstallPkgInfo = default(AppInstUtilWrapper.SceAppInstallPkgInfo);
string[] array = new string[30];
string[] array2 = new string[64];
string[] array3 = new string[64];
for (int i = 0; i < array.Length; i++)
{
array[i] = "";
}
for (int j = 0; j < array2.Length; j++)
{
array2[j] = "";
}
for (int k = 0; k < array3.Length; k++)
{
array3[k] = "";
}
int num = AppInstUtilWrapper.AppInstUtilInstallByPackage(this.mTargetList[this.mInstallIndex], "", "", "", "", "", 0U, false, ref sceAppInstallPkgInfo, array, array2, array3);
if (num == 0)
{
this.mTimer = new UITimer(0.1f, true);
UITimer uitimer = this.mTimer;
uitimer.Executed = (UITimer.ExecutedHandler)Delegate.Combine(uitimer.Executed, new UITimer.ExecutedHandler(this.OnUpdate));
this.mTimer.Start();
}
else
{
this.Unlock();
}
return num;
});
}
private bool OnUpdate()
{
ShellCoreUtilWrapper.sceShellCoreUtilResetAutoPowerDownTimer();
AppInstUtilWrapper.SceAppInstallStatusInstalled sceAppInstallStatusInstalled = default(AppInstUtilWrapper.SceAppInstallStatusInstalled);
int num = AppInstUtilWrapper.AppInstUtilGetInstallStatus(this.mContentId, ref sceAppInstallStatusInstalled);
if (num == 0)
{
if (sceAppInstallStatusInstalled.total_size != 0UL)
{
this.mProgressBar.Progress = sceAppInstallStatusInstalled.downloaded_size / sceAppInstallStatusInstalled.total_size;
}
if (sceAppInstallStatusInstalled.status == "playable" || sceAppInstallStatusInstalled.status == "error" || sceAppInstallStatusInstalled.status == "none")
{
this.Unlock();
this.mTimer.Stop();
if (sceAppInstallStatusInstalled.status == "error" || sceAppInstallStatusInstalled.status == "none")
{
int error_code = sceAppInstallStatusInstalled.error_info.error_code;
this.ShowError(error_code);
return false;
}
this.Next();
}
return false;
}
this.Unlock();
this.mTimer.Stop();
this.ShowErrorDialog(num);
return false;
}
```
## Step 3, using sceAppInstUtilInstallByPackage in C/C++
Following the trail from mono to native code required deeper reverse engineering, as direct replication of mono function definitions in C/C++ results in the SCE_APP_INSTALLER_ERROR_PARAM error. This parameter mismatch occurs because mono wrappers handle various transformations that aren't immediately apparent in the high-level code. To resolve this issue, I decompiled the underlying C/C++ implementation that these mono wrappers actually invoke, revealing the true parameter structure and count expected by the system. This step was critical since the native function signatures differ significantly from their managed counterparts, particularly in memory management and parameter marshalling approaches that the mono runtime normally handles transparently.
```cpp
void UndefinedFunction_001b8aa0
(long param_1,long param_2,long param_3,long param_4,long param_5,long param_6,
undefined4 param_7,byte param_8,long param_9,long param_10,long param_11,
long param_12)
{
undefined auVar1 [16];
long lVar2;
undefined *puVar3;
undefined *puVar4;
undefined in_YMM0 [32];
long lStack10144;
long lStack10136;
long lStack10128;
long lStack10120;
long lStack10112;
long lStack10104;
undefined4 uStack10096;
uint uStack10092;
undefined auStack10080 [240];
undefined auStack9840 [192];
undefined auStack9648 [9552];
long lStack96;
lStack96 = f7uOxY9mM1U#1#u;
if ((((((param_1 != 0) && (param_2 != 0)) && (param_3 != 0)) && ((param_4 != 0 && (param_5 != 0)) )
) && ((param_6 != 0 && ((param_9 != 0 && (param_10 != 0)))))) &&
((param_11 != 0 && (param_12 != 0)))) {
auVar1 = vxorps_avx(SUB3216(in_YMM0,0),SUB3216(in_YMM0,0));
uStack10096 = param_7;
uStack10092 = (uint)param_8;
lVar2 = 0;
lStack10144 = param_1;
lStack10136 = param_2;
lStack10128 = param_3;
lStack10120 = param_4;
lStack10112 = param_5;
lStack10104 = param_6;
memset(SUB168(auVar1,0),auStack10080,0,0x2700);
do {
strncpy(auStack10080 + lVar2,*(undefined8 *)(param_10 + lVar2),7);
lVar2 = lVar2 + 8;
} while (lVar2 != 0xf0);
puVar4 = auStack9840;
puVar3 = auStack9648;
lVar2 = 0;
do {
strncpy(puVar4,*(undefined8 *)(param_11 + lVar2 * 8),2);
strncpy(puVar3,*(undefined8 *)(param_12 + lVar2 * 8),0x2f);
lVar2 = lVar2 + 1;
puVar4 = puVar4 + 3;
puVar3 = puVar3 + 0x30;
} while (lVar2 != 0x40);
InstallByPackage(&lStack10144,param_9,auStack10080);
}
if (f7uOxY9mM1U#1#u == lStack96) {
return;
}
__stack_chk_fail();
do {
invalidInstructionException();
} while( true );
}
```
Through careful analysis of the decompiled implementation, it was identified that `sceAppInstUtilInstallByPackage` requires three struct parameters. Tracing the function's implementation patterns revealed the complete parameter definitions and their expected values. Further investigation into the mono implementation provided additional insights regarding parameter functionality: `content_name` defines the display name shown during package installation (typically the application title), while the `url` parameter supports multiple source formats including local paths (`/data/test.pkg`) and remote HTTP URLs (`http://127.0.0.1/test.pkg`). This URL flexibility likely extends to update manifest handling similar to PS4 implementation. Additional parameters like `icon_url` provide customization options for the installation process and UI representation.
```cpp
#define PLAYGOSCENARIOID_SIZE 3
#define CONTENTID_SIZE 0x30
#define LANGUAGE_SIZE 8
#define NUM_LANGUAGES 30
#define NUM_IDS 64
typedef char playgo_scenario_id_t[PLAYGOSCENARIOID_SIZE];
typedef char language_t[LANGUAGE_SIZE];
typedef char content_id_t[CONTENTID_SIZE];
typedef struct {
content_id_t content_id;
int content_type;
int content_platform;
} SceAppInstallPkgInfo;
typedef struct {
const char* uri;
const char* ex_uri;
const char* playgo_scenario_id;
const char* content_id;
const char* content_name;
const char* icon_url;
} MetaInfo;
typedef struct {
language_t languages[NUM_LANGUAGES];
playgo_scenario_id_t playgo_scenario_ids[NUM_IDS];
content_id_t content_ids[NUM_IDS];
unsigned char unknown[6480]; // standard sony practice of wasting memory?
} PlayGoInfo;
sceAppInstUtilInstallByPackage(MetaInfo* arg1, SceAppInstallPkgInfo* pkg_info, PlayGoInfo* arg2);
```
The investigation process extends beyond simply identifying function signatures. Proper implementation requires adhering to the initialization sequence documented in Flatz's original writeup and confirmed in the mono codebase. Specifically, before any installation functions can be called, the AppInstUtil module must be explicitly initialized via `sceAppInstUtilInitialize`. This initialization step is mandatory and must be preceded by loading the module itself (if not already present in memory). This precise initialization sequence is critical for FPKG installation, as improper module initialization will result in crashing.
```cpp
int(*sceAppInstUtilInstallByPackage)(MetaInfo* arg1, SceAppInstallPkgInfo* pkg_info, PlayGoInfo* arg2) = nullptr;
extern bool sceAppInst_done;
int app_inst_module_id = -1;
bool app_inst_util_init(int &m_id) {
int ret;
if (sceAppInst_done) {
m_id = app_inst_module_id;
return true;
}
int lib_appinstutil = sceKernelLoadStartModule("/system/common/lib/libSceAppInstUtil.sprx", 0, NULL, 0, NULL, NULL);
if (lib_appinstutil < 0) {
return PKG_ERROR("AppInstUtil System Module failed to load.", lib_appinstutil);
}
m_id = app_inst_module_id = lib_appinstutil;
ret = sceAppInstUtilInitialize();
if (ret) {
log_debug("sceAppInstUtilInitialize failed: 0x%08X", ret);
goto err;
}
sceAppInst_done = true;
return true;
err:
log_error("error inilizing appinstlutil");
sceAppInst_done = false;
m_id = -1;
return false;
}
int pkginstall(const char* fullpath,
const char* filename) {
int lib_appinstutil = -1;
if (!if_exists(fullpath)) {
return PKG_ERROR("PKG Doesnt exist", -1);
}
log_info("Initializing AppInstUtil...");
if (!app_inst_util_init(lib_appinstutil))
return PKG_ERROR("AppInstUtil", 1337);
log_info("AppInstUtil Initialized...");
sceAppInstUtilInstallByPackage = (int(*)(MetaInfo*, SceAppInstallPkgInfo*, PlayGoInfo*)) LOAD_FUNCTION_AND_CHECK(lib_appinstutil, "sceAppInstUtilInstallByPackage");
PlayGoInfo arg3;
SceAppInstallPkgInfo pkg_info;
memset(&arg3, 0, sizeof(arg3));
for (size_t i = 0; i < NUM_LANGUAGES; i++) {
strncpy(arg3.languages[i], "", sizeof(language_t) - 1);
}
for (size_t i = 0; i < NUM_IDS; i++) {
strncpy(arg3.playgo_scenario_ids[i], "", sizeof(playgo_scenario_id_t) - 1);
strncpy(*arg3.content_ids, "", sizeof(content_id_t) - 1);
}
MetaInfo arg1 = (MetaInfo){
.uri = fullpath,
.ex_uri = "",
.playgo_scenario_id = "",
.content_id = "",
.content_name = filename,
.icon_url = ""
};
int num = sceAppInstUtilInstallByPackage(&arg1, &pkg_info, &arg3);
if (num == 0) {
log_info("install successful");
}
else {
log_info("install failed");
return PKG_ERROR("install_pkg", num);
}
log_info("%s(%s) done.", __FUNCTION__, fullpath);
return 0;
}
```
We also have this nice list of SCE_APP_INSTALLER_ errors provided by ShellUI
```cpp
enum AppInstErrorCodes
{
SCE_APP_INSTALLER_ERROR_UNKNOWN = -2136801279,
SCE_APP_INSTALLER_ERROR_NOSPACE,
SCE_APP_INSTALLER_ERROR_PARAM,
SCE_APP_INSTALLER_ERROR_APP_NOT_FOUND,
SCE_APP_INSTALLER_ERROR_DISC_NOT_INSERTED,
SCE_APP_INSTALLER_ERROR_PKG_INVALID_DRM_TYPE,
SCE_APP_INSTALLER_ERROR_OUT_OF_MEMORY,
SCE_APP_INSTALLER_ERROR_APP_BROKEN,
SCE_APP_INSTALLER_ERROR_PKG_INVALID_CONTENT_TYPE,
SCE_APP_INSTALLER_ERROR_USED_APP_NOT_FOUND,
SCE_APP_INSTALLER_ERROR_ADDCONT_BROKEN,
SCE_APP_INSTALLER_ERROR_APP_IS_RUNNING,
SCE_APP_INSTALLER_ERROR_SYSTEM_VERSION,
SCE_APP_INSTALLER_ERROR_NOT_INSTALL,
SCE_APP_INSTALLER_ERROR_CONTENT_ID_DISAGREE,
SCE_APP_INSTALLER_ERROR_NOSPACE_KERNEL,
SCE_APP_INSTALLER_ERROR_APP_VER,
SCE_APP_INSTALLER_ERROR_DB_DISABLE,
SCE_APP_INSTALLER_ERROR_CANCELED,
SCE_APP_INSTALLER_ERROR_ENTRYDIGEST,
SCE_APP_INSTALLER_ERROR_BUSY,
SCE_APP_INSTALLER_ERROR_DLAPP_ALREADY_INSTALLED,
SCE_APP_INSTALLER_ERROR_NEED_ADDCONT_INSTALL,
SCE_APP_INSTALLER_ERROR_APP_MOUNTED_BY_HOST_TOOL,
SCE_APP_INSTALLER_ERROR_INVALID_PATCH_PKG,
SCE_APP_INSTALLER_ERROR_NEED_ADDCONT_INSTALL_NO_CHANGE_TYPE = -2136801248,
SCE_APP_INSTALLER_ERROR_ADDCONT_IS_INSTALLING,
SCE_APP_INSTALLER_ERROR_ADDCONT_ALREADY_INSTALLED,
SCE_APP_INSTALLER_ERROR_CANNOT_READ_DISC,
SCE_APP_INSTALLER_ERROR_DATA_DISC_NOT_INSTALLED,
SCE_APP_INSTALLER_ERROR_NOT_TRANSFER_DISC_VERSION,
SCE_APP_INSTALLER_ERROR_NO_SLOT_SPACE,
SCE_APP_INSTALLER_ERROR_NO_SLOT_INFORMATION,
SCE_APP_INSTALLER_ERROR_INSTALL_MAIN_MISSING,
SCE_APP_INSTALLER_ERROR_INSTALL_TIME_VALID_IN_FUTURE,
SCE_APP_INSTALLER_ERROR_SYSTEM_FILE_DISAGREE,
SCE_APP_INSTALLER_ERROR_INSTALL_BLANK_SLOT,
SCE_APP_INSTALLER_ERROR_INSTALL_LINK_SLOT,
SCE_APP_INSTALLER_ERROR_INSTALL_PKG_NOT_COMPLETED,
SCE_APP_INSTALLER_ERROR_NOSPACE_IN_EXTERNAL_HDD,
SCE_APP_INSTALLER_ERROR_NOSPACE_KERNEL_IN_EXTERNAL_HDD,
SCE_APP_INSTALLER_ERROR_COMPILATION_DISC_INSERTED,
SCE_APP_INSTALLER_ERROR_COMPILATION_DISC_INSERTED_NOT_VISIBLE_DISC_ICON,
SCE_APP_INSTALLER_ERROR_ACCESS_FAILED_IN_EXTERNAL_HDD,
SCE_APP_INSTALLER_ERROR_MOVE_FAILED_SOME_APPLICATIONS,
SCE_APP_INSTALLER_ERROR_DUPLICATION,
SCE_APP_INSTALLER_ERROR_INVALID_STATE,
SCE_APP_INSTALLER_ERROR_NOSPACE_DISC,
SCE_APP_INSTALLER_ERROR_NOSPACE_DISC_IN_EXTERNAL_HDD,
SCE_APP_INST_UTIL_ERROR_NOT_INITIALIZED = -2136797184,
SCE_APP_INST_UTIL_ERROR_OUT_OF_MEMORY
}
```
## Step 4, using sceAppInstUtilGetInstallStatus in C/C++
The implementation of `sceAppInstUtilGetInstallStatus` maintains close functional parity with its C# counterpart. I converted the managed data structures to their native C/C++ equivalents with proper memory alignment and type definitions. This direct correlation between implementations facilitates consistent behavior across different access methods while maintaining the expected parameter layouts and return value semantics.
```cpp
typedef struct {
int32_t error_code;
int32_t version;
char description[512];
char type[9];
} SceAppInstallErrorInfo;
typedef struct {
char status[16];
char src_type[8];
uint32_t remain_time;
uint64_t downloaded_size;
uint64_t initial_chunk_size;
uint64_t total_size;
uint32_t promote_progress;
SceAppInstallErrorInfo error_info;
int32_t local_copy_percent;
bool is_copy_only;
} SceAppInstallStatusInstalled;
int sceAppInstUtilGetInstallStatus(const char* content_id, SceAppInstallStatusInstalled* status);
```
The `sceAppInstUtilGetInstallStatus` function provides a streamlined interface for monitoring installation progress. It accepts a content ID parameter and populates the previously defined status structure with installation metrics. This content ID can be extracted directly from a PKGs metadata or programmatically obtained through the method outlined in the subsequent implementation section. This status monitoring capability is essential for implementing progress tracking and error handling during the installation.
## Step 5, using both functions to do what BGFT used to do
The integration of `sceAppInstUtilInstallByPackage` and `sceAppInstUtilGetInstallStatus` provides a comprehensive package installation solution equivalent to the system's native Debug Settings implementation. This workflow begins with installation initiation via `sceAppInstUtilInstallByPackage`, which returns immediately while the installation continues asynchronously. The returned content ID serves as the reference key for subsequent status tracking.
By implementing a monitoring loop with `sceAppInstUtilGetInstallStatus`, applications can:
1. Track download progress (percentage complete)
2. Monitor installation state transitions (transferring → promoting → playable)
3. Detect and respond to installation errors
4. Determine when installation has successfully completed
This approach enables developers to create custom installation interfaces with progress visualization, error handling, and completion notifications—effectively replicating the functionality of the system's Debug Settings while providing greater control over the presentation layer and integration with application-specific logic.
```cpp
int ret = sceAppInstUtilInitialize();
if(ret){
printf("sceAppInstUtilInitialize failed: 0x%08X\n", ret);
return -1;
}
PlayGoInfo arg3;
SceAppInstallPkgInfo pkg_info;
(void)memset(&arg3, 0, sizeof(arg3));
for (size_t i = 0; i < NUM_LANGUAGES; i++) {
strncpy(arg3.languages[i], "", sizeof(arg3.languages[i]) - 1);
}
for (size_t i = 0; i < NUM_IDS; i++) {
strncpy(arg3.playgo_scenario_ids[i], "",
sizeof(playgo_scenario_id_t) - 1);
strncpy(*arg3.content_ids, "", sizeof(content_id_t) - 1);
}
MetaInfo in = {
.uri = "/path/to/pkg.pkg",
.ex_uri = "",
.playgo_scenario_id = "",
.content_id = "",
.content_name = "PKG TITLE",
.icon_url = ""
};
int num = sceAppInstUtilInstallByPackage(&in, &pkg_info, &arg3);
if (num == 0) {
puts("Download and Install console Task initiated");
} else {
printf("DPI: Install failed with error code %d\n", num);
}
float prog = 0;
SceAppInstallStatusInstalled status;
while (strcmp(status.status, "playable") != 0) {
sceAppInstUtilGetInstallStatus(pkg_info.content_id, &status);
if (status.total_size != 0) {
prog = ((float)status.downloaded_size / status.total_size) * 100.0f;
}
printf("DPI: Status: %s | error: %d | progress %.2f%% (%llu/%llu)\n",
status.status, status.error_info.error_code,
prog, status.downloaded_size, status.total_size);
}
```
## Credits
- Astrelsky, for all the help they provided, without them it may have taken longer

198
README.md
View File

@@ -1,25 +1,75 @@
# etaHEN - AIO Homebrew enabler
![etaHEN](https://github.com/LightningMods/etaHEN/blob/main/ETAHEN.png)
![etaHEN](https://github.com/LightningMods/etaHEN/blob/main/etaHEN-Icon.jpg)
## 🚀 **Support the Project**
If you find this project useful and would like to support its continued development, consider buying me a coffee!
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/lightningmods)
## Official PS5 exploit website (auto loads etaHEN)
- https://ps5jb.pages.dev/
## Official PS5 exploit website
- https://tinyurl.com/PS5IPV6 (requires you to manually send the payload but has the best stability)
- https://ps5jb.pages.dev/ (auto loads the payload for you, id recommand the IPV6 exploit over UMTX)
## Recommended self-host exploits
- [Modified IPV6 exploit for etaHEN support](https://github.com/LightningMods/PS5-IPV6-Kernel-Exploit)
## Payload PowerShell Script usage for Windows (send_payload.ps1)
if you haven't already, you will need to either enable script execution globally via
```
Set-ExecutionPolicy Bypass
```
in an admin PowerShell window or run the script with this command after replacing the script path
```
powershell.exe -ExecutionPolicy Bypass -File C:\Path\To\send_payload.ps1
```
**Script Usage**
```
.\send_payload.ps1 -Payload "C:\path\to\example.elf" -IP "192.168.xxx.xxx" -Port XXXX
```
**OR**
```
.\send_payload.ps1
cmdlet send_payload.ps1 at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Payload: C:\path\to\example.elf
IP: 192.168.xxx.xxx
Port: XXXX
```
- Common Ports: SB elfldr 9021, exploit elfldr 9020
## Features
- ★ etaHEN toolbox (debug settings replacement)
- Custom etaHEN [Plugins](https://github.com/LightningMods/etaHEN-SDK/tree/main/Plugin_samples)
- [Toolbox] Install the Homebrew Store on the console
- [Toolbox] ★Rest Mode Options
- [Toolbox] Remote Play Menu
- [Toolbox] Plugin / Payload ELF Menu with auto start options
- [Toolbox] External HDD Menu
- [Toolbox] TestKit Menu
- [Toolbox] Cheats Menu (WIP)
- [Toolbox] Controller Shortcuts
- [Toolbox] PS5 webMAN Games menu
- [Toolbox] Custom Game Options Menu
- [Toolbox] Display Title IDs on Home menu
- [Toolbox] Disable toolbox auto start
- [Toolbox] Blu-Ray license activation
- [Toolbox] Disc auto eject for BD-J and LUA based exploits
- [Toolbox] etaHEN credits and supporters
- [Toolbox] Custom debug settings text and icon
- [Toolbox] Auto open menu after etaHEN loads
- [Toolbox] a number of different toolbox settings
- React bundle (all FWs) & Self (only on 2.xx) FTP decryption Support
- 2 seperate daemons for improved stability and reliability
- the Util daemon willl be auto restarted by the main etaHEN daemon
- The Util daemon will be auto restarted by the main etaHEN daemon
- Custom System Software version (custom System info)
- kstuff for fself and fpkg support
- etaHEN log in /data/etaHEN
@@ -33,23 +83,21 @@ If you find this project useful and would like to support its continued developm
- *Optional* FTP server on port 1337
- *Optional* /data allowed inside apps sandboxes
- Klog server on port 9081
- elf loader on port 9027
- elf loader on port 9021 (use Johns elfldr)
- *Optional* PS5Debug
- *started* Itemzflow intergration
- Itemzflow intergration
- *Optional* Discord RPC server on port 8000, click [here](https://github.com/jeroendev-one/ps5-rpc-client) for setup instructions
- *Optional* Direct PKG installer V2 service with WebUI on http://PS5_IP:12800
- *Optional* Direct PKG installer service on port 9090
## etaHEN SDK
make your own custom plugins or payload-like ELFs for the HENV plugin via the [etaHEN SDK](https://github.com/lightningmods/etaHEN-SDK)
make your own custom plugins via the [etaHEN SDK](https://github.com/lightningmods/etaHEN-SDK)
More info [Here](https://github.com/LightningMods/etaHEN-SDK/blob/main/README.md)
## Upcoming features
- [Toolbox ONLY] load plugins without the HENV plugin
- [Toolbox] FPS Counter
- [Toolbox] change debug settings text
- [Toolbox] On-Screen temps and other info
- [Toolbox] On-Screen temps and other info (for retails)
- More userland patches
- (maybe) Jailbreak whitelist for Homebrew
- Improved PS5 Game support (itemzflow)
- More (consider donating)
@@ -57,21 +105,33 @@ More info [Here](https://github.com/LightningMods/etaHEN-SDK/blob/main/README.md
etaHEN's ini settings file can be found at `/data/etaHEN/config.ini` and can be accessed using the built-in FTP
and is automatically created when you run etaHEN for the first time
#### Configuration Layout (toolbox)
| INI Key | Description | Default value
|---------------------|-------------------------------------------------------------|---------------------|
| `PS5Debug` | 0 = disables PS5Debug (Sistr0) auto load 1 = enable PS5Debug auto load | 1 (enabled) |
| `FTP` | 0 = disables etaHEN built-in FTP 1 = enables it | 1 (enabled) |
| `discord_rpc` | 0 = disables Discord RPC server 1 = enables it | 0 (disabled) |
| `testkit` | 0 = not testkit 1 = Real Testkits ONLY | 0 (disabled) |
| `Allow_data_in_sandbox` | 0 = disables /data in an apps sandbox 1 = enables it | 1 (enabled) |
| `DPI` | 0 = disables The Direct PKG Installer service 1 = enables it | 1 (enabled) |
| `Klog` | 0 = disables kernel logging, 1 = enables it | 0 (disabled) |
| `ALLOW_FTP_DEV_ACCESS` | 0 = disables FTP developer access, 1 = enables it | 0 (disabled) |
| `StartOption` | 0=None, 1=Home menu, 2=Settings 3=Toolbox, 4=itemzflow | 0 (None) |
| `Rest_Mode_Delay_Seconds` | Delay in seconds before patching shellui coming out rest mode | 0 (no delay) |
| `Util_rest_kill` | 0 = dont kill the util daemon during rest, 1 = Do kill it on rest | 0 (disabled) |
| `Game_rest_kill` | 0 = dont kill the open game during rest, 1 = Do kill it on rest | 0 (disabled) |
| INI Key | Description | Default value |
|---------------------|-------------------------------------------------------------|---------------|
| `PS5Debug` | 0 = disables PS5Debug (Sistr0) auto load, 1 = enable PS5Debug auto load | 0 (disabled) |
| `FTP` | 0 = disables etaHEN built-in FTP, 1 = enables it | 1 (enabled) |
| `discord_rpc` | 0 = disables Discord RPC server, 1 = enables it | 0 (disabled) |
| `toolbox_auto_start` | 0 = disabled, 1 = enabled | 1 (enabled) |
| `Allow_data_in_sandbox` | 0 = disables /data in an apps sandbox, 1 = enables it | 1 (enabled) |
| `DPI` | 0 = disables The Direct PKG Installer service, 1 = enables it | 0 (disabled) |
| `DPI_v2` | 0 = disables DPI version 2, 1 = enables it | 0 (disabled) |
| `Klog` | 0 = disables kernel logging, 1 = enables it | 0 (disabled) |
| `ALLOW_FTP_DEV_ACCESS` | 0 = disables FTP developer access, 1 = enables it | 0 (disabled) |
| `StartOption` | 0=None, 1=Home menu, 2=Settings, 3=Toolbox, 4=itemzflow | 0 (None) |
| `Rest_Mode_Delay_Seconds` | Delay in seconds before patching shellui coming out rest mode | 0 (no delay) |
| `Util_rest_kill` | 0 = don't kill the util daemon during rest, 1 = Do kill it on rest | 0 (disabled) |
| `Game_rest_kill` | 0 = don't kill the open game during rest, 1 = Do kill it on rest | 0 (disabled) |
| `disable_toolbox_auto_start_for_rest_mode` | 0 = disabled, 1 = enabled | 0 (disabled) |
| `libhijacker_cheats` | 0 = disables libhijacker cheats, 1 = enables it | 0 (disabled) |
| `launch_itemzflow` | 0 = disabled, 1 = enables auto launch of itemzflow | 0 (disabled) |
| `testkit` | 0 = disabled, 1 = enables testkit mode | 0 (disabled) |
| `Display_tids` | 0 = disabled, 1 = enables display of title IDs | 0 (disabled) |
| `APP_JB_Debug_Msg` | 0 = disabled, 1 = enables app jailbreak debug messages | 0 (disabled) |
| `etaHEN_Game_Options` | 0 = disabled, 1 = enables etaHEN game options | 1 (enabled) |
| `auto_eject_disc` | 0 = disabled, 1 = enables automatic disc ejection | 0 (disabled) |
| `Cheats_shortcut_opt` | Multi-select option for cheats shortcut | 0 (CHEATS_SC_OFF) |
| `Toolbox_shortcut_opt` | Multi-select option for toolbox shortcut | 0 (TOOLBOX_SC_OFF) |
| `Games_shortcut_opt` | Multi-select option for games shortcut | 0 (GAMES_SC_OFF) |
| `Kstuff_shortcut_opt` | Multi-select option for kstuff shortcut | 0 (KSTUFF_SC_OFF) |
## DPI API details for tool creators
etaHEN's Direct PKG Installer currently is very simple and is considered a WIP
@@ -88,13 +148,97 @@ the service flow is as follows
```
4. etaHEN will close the client socket after the return json is sent
## Jailbreaking an app (FPKG) using etaHEN (non-whitelist method, Network required)
```
enum Commands : int {
INVALID_CMD = -1,
ACTIVE_CMD = 0,
LAUNCH_CMD,
PROCLIST_CMD,
KILL_CMD,
KILL_APP_CMD,
JAILBREAK_CMD
};
struct HijackerCommand
{
int magic = 0xDEADBEEF;
Commands cmd = INVALID_CMD;
int PID = -1;
int ret = -1337;
char msg1[0x500];
char msg2[0x500];
};
int HJOpenConnectionforBC() {
SceNetSockaddrIn address;
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
address.sin_port = sceNetHtons(9028); //command serve port
memset(address.sin_zero, 0, sizeof(address.sin_zero));
sceNetInetPton(AF_INET, "127.0.0.1", &address.sin_addr.s_addr);
int socket = sceNetSocket("IPC_CMD_SERVER", AF_INET, SOCK_STREAM, 0);
if (sceNetConnect(socket, (SceNetSockaddr*)&address, sizeof(address)) < 0) {
close(socket), socket = -1;
}
return socket;
}
bool HJJailbreakforBC(int& sock) {
// send jailbreak IPC command
HijackerCommand cmd;
cmd.PID = getpid();
cmd.cmd = JAILBREAK_CMD;
if (send(sock, (void*)&cmd, sizeof(cmd), MSG_NOSIGNAL) == -1) {
puts("failed to send command");
return false;
}
else {
// get ret val from daemon
recv(sock, reinterpret_cast<void*>(&cmd), sizeof(cmd), MSG_NOSIGNAL);
close(sock), sock = -1;
if (cmd.ret != 0 && cmd.ret != -1337) {
puts("Jailbreak has failed");
return false;
}
return true;
}
return false;
}
int main()
{
int ret = HJOpenConnectionforBC();
if (ret < 0) {
puts("Failed to connect to daemon");
return -1;
}
if (!HJJailbreakforBC(ret))
{
puts("Jailbreak failed");
return -1;
}
return 0;
}
```
## Contributors
- [Buzzer](https://github.com/buzzer-re)
- [sleirsgoevy](https://github.com/sleirsgoevy)
- [ChendoChap](https://github.com/ChendoChap)
- [astrelsky](https://github.com/astrelsky)
- [illusion](https://github.com/illusion0001)
- CTN & [SiSTR0](https://github.com/SiSTR0) for PS5Debug
- [SiSTR0](https://github.com/SiSTR0) for PS5Debug
- [Nomadic](https://github.com/jeroendev-one) (Discord RPC feature)
## Testers

BIN
etaHEN-2.3B.bin Normal file

Binary file not shown.

BIN
etaHEN-Icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

101
send_payload.ps1 Normal file
View File

@@ -0,0 +1,101 @@
<#
.SYNOPSIS
Sends the contents of a file to a specified IP address and port using PowerShell.
.DESCRIPTION
This script reads the contents of a file and sends it over a TCP connection
to a specified IP address and port. It handles potential errors and
provides basic feedback, including connection failure detection.
.PARAMETER Payload
The path to the file whose contents will be sent.
.PARAMETER IP
The IP address to send the data to.
.PARAMETER Port
The port number to connect to.
.EXAMPLE
.\send_payload.ps1 -Payload "C:\xxx\xxx\payload.elf" -IP "192.168.x.xxx" -Port 9021
.NOTES
- Requires PowerShell 3.0 or later.
- Handles potential exceptions during socket creation and data transmission.
- Consider error handling and security implications in production environments.
#>
param (
[Parameter(Mandatory = $true, HelpMessage = "The path to the payload to send.")]
[string]$Payload,
[Parameter(Mandatory = $true, HelpMessage = "The IP address to send the data to.")]
[string]$IP,
[Parameter(Mandatory = $true, HelpMessage = "The port number to connect to.")]
[int]$Port
)
# Check if the file exists before proceeding
if (!(Test-Path -Path $Payload -PathType Leaf)) {
Write-Host "The specified payload file '$Payload' does not exist, Press any key to exit..." -ForegroundColor Red
exit
}
try {
# Create a TCP client object
$tcpClient = New-Object System.Net.Sockets.TcpClient
Write-Host "Connecting to ${IP}:$Port...."
# Attempt to connect with a timeout
$connectTimeoutMs = 5000 # 5 seconds timeout
$connectResult = $tcpClient.BeginConnect($IP, $Port, $null, $null)
$connected = $connectResult.AsyncWaitHandle.WaitOne($connectTimeoutMs)
if (!$connected) {
# Connection timed out
Write-Host "Failed to connect to ${IP}:$Port within $connectTimeoutMs ms. Connection timed out, Press any key to exit..." -ForegroundColor Red
$tcpClient.Close() # Ensure the client is closed
exit # Exit the script if connection fails
}
# Complete the connection
$tcpClient.EndConnect($connectResult)
# Get the network stream
$stream = $tcpClient.GetStream()
# Read the file content as a byte array
Write-Verbose "Reading file content from $Payload..."
$fileContent = [System.IO.File]::ReadAllBytes($Payload)
# Send the data
Write-Verbose "Sending data..."
$stream.Write($fileContent, 0, $fileContent.Length)
# Flush the stream to ensure all data is sent
$stream.Flush()
Write-Host "Successfully sent file '$Payload' to ${IP}:$Port, press any key to exit"
# Shutdown and close the connection
$stream.Close()
$tcpClient.Close()
}
catch {
Write-Error "An error occurred: $($_.Exception.Message), press any key to exit"
Write-Error $_.Exception.StackTrace
}
finally {
# Ensure resources are cleaned up even if an error occurs
if ($stream) {
try { $stream.Dispose() } catch {} # Handle potential disposal errors
}
if ($tcpClient) {
try { $tcpClient.Close() } catch {} # Handle potential close errors
}
[System.Console]::ReadKey() | Out-Null
}