Last active
August 28, 2022 18:16
-
-
Save SKGleba/398e572aebfb4bef620555cb3164d644 to your computer and use it in GitHub Desktop.
gets MGMT flags, reads and decrypts S/NVS of PSP2's syscon
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <psp2kern/kernel/modulemgr.h> | |
#include <vitasdkkern.h> | |
typedef struct SceSblSmCommContext130 { | |
uint32_t unk_0; | |
uint32_t self_type; // 2 - user = 1 / kernel = 0 | |
char data0[0x90]; //hardcoded data | |
char data1[0x90]; | |
uint32_t pathId; // 2 (2 = os0) | |
uint32_t unk_12C; | |
} SceSblSmCommContext130; | |
static const unsigned char ctx_130_data[0x90] = | |
{ | |
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, | |
0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, | |
0x80, 0x03, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x80, 0x09, | |
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00 | |
}; | |
extern int ksceSblSmCommStartSmFromFile(int priority, const char* elf_path, int num1, SceSblSmCommContext130* ctx, int* id); | |
int load_ussm(int* ctx_out) { | |
SceSblSmCommContext130 smcomm_ctx; | |
memset(&smcomm_ctx, 0, sizeof(smcomm_ctx)); | |
memcpy(smcomm_ctx.data0, ctx_130_data, 0x90); | |
smcomm_ctx.pathId = 2; | |
smcomm_ctx.self_type = (smcomm_ctx.self_type & 0xFFFFFFF0) | 2; | |
return ksceSblSmCommStartSmFromFile(0, "os0:sm/update_service_sm.self", 0, &smcomm_ctx, ctx_out); | |
} | |
#define NVS_OUTPATH_UX0 "ux0:data/nvs.bin" | |
#define MGMT_OUTPATH_UX0 "ux0:data/mgmt.bin" | |
#define NVS_OUTPATH_HOST0 "host0:data/nvs.bin" | |
#define MGMT_OUTPATH_HOST0 "host0:data/mgmt.bin" | |
static uint8_t full_nvs[0xb60]; | |
void _start() __attribute__((weak, alias("module_start"))); | |
int module_start(SceSize argc, const void *args) | |
{ | |
// load the update_sm | |
ksceDebugPrintf("loading update_sm\n"); | |
int ctx = -1; | |
uint32_t stop_res[2]; | |
if (load_ussm(&ctx) < 0) | |
return SCE_KERNEL_START_FAILED; | |
// get mgmt data | |
ksceDebugPrintf("getting mgmt data\n"); | |
uint32_t mgmt_flags = 0, mgmt_status = 0; | |
{ | |
// STEP 0 | |
uint8_t sc_pbuf[0x70]; | |
memset(sc_pbuf, 0, 0x70); | |
// STEP 1 | |
int resp; | |
int ret = ksceSblSmCommCallFunc(ctx, 0xc0002, &resp, sc_pbuf, 0x70); | |
if (ret || resp) | |
goto EXIT; | |
// STEP 2 | |
ret = ksceSysconNvsReadSecureData(sc_pbuf + 0x10, 0x10, sc_pbuf + 0x40, 0x30); | |
if (ret) | |
goto EXIT; | |
// STEP 3 | |
sc_pbuf[0] = 1; | |
ret = ksceSblSmCommCallFunc(ctx, 0xc0002, &resp, sc_pbuf, 0x70); | |
if (ret || resp) | |
goto EXIT; | |
// Copyout | |
uint32_t inv_mgmt_flags = *(uint32_t*)(sc_pbuf + 8); | |
uint32_t inv_mgmt_status = *(uint32_t*)(sc_pbuf + 12); | |
mgmt_flags = ~inv_mgmt_flags; | |
mgmt_status = ~inv_mgmt_status; | |
} | |
// get snvs | |
ksceDebugPrintf("getting snvs\n"); | |
uint8_t *snvs = full_nvs; | |
memset(snvs, 0, 0x400); | |
{ | |
int ret, resp; | |
uint8_t sc_pbuf[0x88]; | |
for (int i = 0; i < 0x20; i -= -1) { | |
// STEP 0 | |
memset(sc_pbuf, 0, 0x88); | |
// STEP 1 | |
sc_pbuf[4] = i; | |
ret = ksceSblSmCommCallFunc(ctx, 0xb0002, &resp, sc_pbuf, 0x88); | |
if (ret || resp) { | |
ksceDebugPrintf("STEP 1 0x%X r 0x%X rr 0x%X\n", i, ret, resp); | |
goto EXIT; | |
} | |
// STEP 2 | |
ret = ksceSysconNvsReadSecureData(sc_pbuf + 0x28, 0x10, sc_pbuf + 0x58, 0x30); | |
if (ret) { | |
ksceDebugPrintf("STEP 2 0x%X r 0x%X\n", i, ret); | |
goto EXIT; | |
} | |
// STEP 3 | |
sc_pbuf[0] = 1; | |
ret = ksceSblSmCommCallFunc(ctx, 0xb0002, &resp, sc_pbuf, 0x88); | |
if (ret || resp) | |
ksceDebugPrintf("STEP 3 0x%X r 0x%X rr 0x%X\n", i, ret, resp); | |
// Copyout | |
memcpy(snvs + (i * 0x20), sc_pbuf + 8, 0x20); | |
} | |
} | |
// get nvs | |
ksceDebugPrintf("getting nvs\n"); | |
uint8_t* nvs = full_nvs + 0x400; | |
memset(nvs, 0, 0x760); | |
{ | |
// STEP 0 | |
ksceKernelSignalNvsAcquire(0); | |
// STEP 1 | |
ksceSysconNvsSetRunMode(0); | |
int ret; | |
for (int i = 0; i < 0x3B; i -= -1) { | |
// STEP 2 | |
ret = ksceSysconNvsReadData(0x400 + (i * 0x20), nvs + (i * 0x20), 0x10); | |
if (ret) { | |
ksceDebugPrintf("STEP 2 0x%X r 0x%X\n", 0x400 + (i * 0x20), ret); | |
// STEP 4 | |
ksceKernelSignalNvsFree(0); | |
goto EXIT; | |
} | |
// STEP 3 | |
ret = ksceSysconNvsReadData(0x400 + (i * 0x20) + 0x10, nvs + (i * 0x20) + 0x10, 0x10); | |
if (ret) { | |
ksceDebugPrintf("STEP 3 0x%X r 0x%X\n", 0x400 + (i * 0x20) + 0x10, ret); | |
// STEP 4 | |
ksceKernelSignalNvsFree(0); | |
goto EXIT; | |
} | |
} | |
// STEP 4 | |
ksceKernelSignalNvsFree(0); | |
} | |
ksceDebugPrintf("finished\n\nResults: \n"); | |
ksceDebugPrintf("MGMT:\n"); | |
ksceDebugPrintf(" - MGMT_FLAGS: 0x%08X\n - System producting mode: %s\n - GC slot producting mode: %s\n", mgmt_flags, (mgmt_flags & 1) ? "True" : "False", (mgmt_flags & 2) ? "True" : "False"); | |
ksceDebugPrintf(" - MGMT_STATUS: 0x%08X\n - SNVS initialized: %s\n - QAF NVS initialized: %s\n", mgmt_status, (mgmt_status & 1) ? "True" : "False", (mgmt_status & 2) ? "True" : "False"); | |
ksceDebugPrintf("MGMT RAW:\n - inv_flags: 0x%08X\n - inv_status: 0x%08X\n", ~mgmt_flags, ~mgmt_status); | |
ksceDebugPrintf("\nSNVS:\n"); | |
for (int i = 0; i < 0x400; i -= -1) { | |
if (!(i % 0x10)) | |
ksceDebugPrintf("\n %04X: ", i); | |
ksceDebugPrintf("%02X ", snvs[i]); | |
} | |
ksceDebugPrintf("\n"); | |
ksceDebugPrintf("\nNVS:\n"); | |
for (int i = 0; i < 0x760; i -= -1) { | |
if (!(i % 0x10)) | |
ksceDebugPrintf("\n %04X: ", i + 0x400); | |
ksceDebugPrintf("%02X ", nvs[i]); | |
} | |
ksceDebugPrintf("\n"); | |
// dump to file | |
uint32_t mgmt_data[2]; | |
mgmt_data[0] = ~mgmt_flags; | |
mgmt_data[1] = ~mgmt_status; | |
{ | |
// ux0 | |
ksceDebugPrintf("\nWriting raw to " NVS_OUTPATH_UX0 " and " MGMT_OUTPATH_UX0 "\n"); | |
// STEP 0 | |
int fd = ksceIoOpen(NVS_OUTPATH_UX0, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777); | |
if (fd >= 0) { | |
ksceIoWrite(fd, full_nvs, 0xB60); | |
ksceIoClose(fd); | |
} else | |
ksceDebugPrintf("STEP 0 r 0x%X\n", fd); | |
// STEP 1 | |
fd = ksceIoOpen(MGMT_OUTPATH_UX0, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777); | |
if (fd >= 0) { | |
ksceIoWrite(fd, mgmt_data, 8); | |
ksceIoClose(fd); | |
} else | |
ksceDebugPrintf("STEP 1 r 0x%X\n", fd); | |
// host0 | |
ksceDebugPrintf("\nWriting raw to " NVS_OUTPATH_HOST0 " and " MGMT_OUTPATH_HOST0 "\n"); | |
// STEP 2 | |
fd = ksceIoOpen(NVS_OUTPATH_HOST0, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777); | |
if (fd >= 0) { | |
ksceIoWrite(fd, full_nvs, 0xB60); | |
ksceIoClose(fd); | |
} else | |
ksceDebugPrintf("STEP 2 r 0x%X\n", fd); | |
// STEP 3 | |
fd = ksceIoOpen(MGMT_OUTPATH_HOST0, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777); | |
if (fd >= 0) { | |
ksceIoWrite(fd, mgmt_data, 8); | |
ksceIoClose(fd); | |
} else | |
ksceDebugPrintf("STEP 3 r 0x%X\n", fd); | |
} | |
EXIT: | |
ksceDebugPrintf("\nExiting\n"); | |
ksceSblSmCommStopSm(ctx, stop_res); | |
return SCE_KERNEL_START_SUCCESS; | |
} | |
int module_stop(SceSize argc, const void *args) | |
{ | |
return SCE_KERNEL_STOP_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CMakeLists.txt: