-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# themadump | ||
![](https://raw.githubusercontent.com/catmagicspell/themadump/master/app/resource/screenshot.png)</br> | ||
This homebrew allows you to dump your PSP's active theme to your Memory Stick.<br/> | ||
It should work on every PSP firmware **regardless of whether it's CFW or OFW**. | ||
|
||
[Download and Installation](https://github.com/catmagicspell/themadump/releases/latest) | ||
|
||
# Credits | ||
- [reha](https://github.com/rreha) and [PonpiK](https://github.com/PonpiK) of **[Cat Magic Spell](https://github.com/catmagicspell)** for leading the project and testing<br/> | ||
- Zenax for the **[ICON0](https://raw.githubusercontent.com/catmagicspell/themadump/master/app/resource/ICON0.PNG)**<br/> | ||
- [Acid_Snake](https://github.com/JoseAaronLopezGarcia) and [others who contributed to the LibPspExploit](https://github.com/PSP-Archive/LibPspExploit?tab=readme-ov-file#credits) for **[LibPspExploit](https://github.com/PSP-Archive/LibPspExploit)**<br/> | ||
- [krazynez](https://github.com/krazynez) for **[wallpaper_dumper](https://github.com/krazynez/wallpaper_dumper)**<br/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
TARGET = themadump | ||
SRCDIR = ./source | ||
INCDIR = ./include | ||
LIBDIR = ./library | ||
RESDIR = ./resource | ||
|
||
CFILES := $(wildcard $(SRCDIR)/*.c) | ||
OBJS := $(CFILES:.c=.o) | ||
|
||
CFLAGS = -Ofast -w | ||
LIBS = -lpspexploit -lpsprtc | ||
USE_PSPSDK_LIBC = 1 | ||
USE_PSPSDK_LIBS = 1 | ||
|
||
BUILD_PRX = 1 | ||
PSP_FW_VERSION = 370 | ||
PSP_LARGE_MEMORY = 0 | ||
|
||
EXTRA_TARGETS = EBOOT.PBP | ||
PSP_EBOOT_TITLE = ThemaDump | ||
PSP_EBOOT_ICON= $(RESDIR)/ICON0.png | ||
#PSP_EBOOT_PIC1= $(RESDIR)/PIC1.png | ||
#PSP_EBOOT_SND0= $(RESDIR)/SND0.at3 | ||
|
||
PSPSDK=$(shell psp-config --pspsdk-path) | ||
include $(PSPSDK)/lib/build.mak |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef COMMON_H | ||
#define COMMON_H | ||
#pragma once | ||
|
||
#include <pspsdk.h> | ||
#include <pspkernel.h> | ||
#include <libpspexploit.h> | ||
|
||
#define RGB(r, g, b) (0xFF000000 | ((b) << 16) | ((g) << 8) | (r)) | ||
#define RED RGB(255, 0, 0) | ||
#define GREEN RGB(0, 255, 0) | ||
#define BLUE RGB(0, 0, 255) | ||
#define BLACK RGB(0, 0, 0) | ||
#define ORANGE RGB(255, 127, 0) | ||
#define WHITE RGB(255, 255, 255) | ||
#define YELLOW RGB(255, 255, 0) | ||
#define GRAY RGB(103, 120, 137) | ||
|
||
#define BackColor(color) pspDebugScreenSetBackColor(color) | ||
#define TextColor(color) pspDebugScreenSetTextColor(color) | ||
#define printf pspDebugScreenPrintf | ||
|
||
#define VER_MAJOR 1 | ||
#define VER_MINOR 0 | ||
|
||
extern void kthread(void); | ||
extern KernelFunctions *k_tbl; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
#ifndef LIBPSPEXPLOIT_H | ||
#define LIBPSPEXPLOIT_H | ||
#pragma once | ||
|
||
#include <pspsdk.h> | ||
#include <psputils.h> | ||
#include <pspkerror.h> | ||
#include <psploadcore.h> | ||
#include <psploadexec.h> | ||
#include <psploadexec_kernel.h> | ||
#include <psputility.h> | ||
#include <psputility_modules.h> | ||
#include <psputility_savedata.h> | ||
#include <pspsysmem.h> | ||
#include <pspmodulemgr.h> | ||
#include <pspctrl.h> | ||
#include <pspiofilemgr.h> | ||
#include <string.h> | ||
|
||
#define KERNELIFY(x) (((u32)x) | 0x80000000) | ||
|
||
// j addr | ||
#define JUMP(f) (0x08000000 | (((unsigned int)(f) >> 2) & 0x03ffffff)) | ||
|
||
// j addr getter (for kernel range, use in combination with KERNELIFY, works with j & jal) | ||
#define JUMP_TARGET(i) (((unsigned int)(i) & 0x03ffffff) << 2) | ||
|
||
// jal addr | ||
#define JAL(f) (0x0C000000 | (((unsigned int)(f) >> 2) & 0x03ffffff)) | ||
|
||
#define MAKE_JUMP(a, f) _sw(JUMP(f), a); | ||
#define MAKE_CALL(a, f) _sw(JAL(f), a); | ||
|
||
// jal checker | ||
#define IS_JAL(i) ((((unsigned int)i) & 0xFC000000) == 0x0C000000) | ||
#define IS_JUMP(i) ((((unsigned int)i) & 0xFC000000) == 0x08000000) | ||
|
||
// syscall number | ||
#define SYSCALL(n) ((n << 6) | 12) | ||
|
||
// nop | ||
#define NOP 0 | ||
|
||
// jr ra | ||
#define JR_RA 0x03E00008 | ||
|
||
// v0 result setter | ||
#define LI_V0(n) ((0x2402 << 16) | ((n) & 0xFFFF)) | ||
|
||
#define MAKE_DUMMY_FUNCTION_RETURN_0(a) \ | ||
_sw(JR_RA, a); \ | ||
_sw(LI_V0(0), a + 4); | ||
|
||
#define MAKE_DUMMY_FUNCTION_RETURN_1(a) \ | ||
_sw(JR_RA, a); \ | ||
_sw(LI_V0(1), a + 4); | ||
|
||
// Array Element Counter | ||
#define NELEMS(n) ((sizeof(n)) / sizeof(n[0])) | ||
|
||
// is UID | ||
#define IsUID(uid) ((uid > 0 && uid < 0x05000000) && ((uid & 1) == 1)) | ||
|
||
// Min & Max Macros | ||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
#define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
|
||
#undef UNUSED | ||
#define UNUSED(arg) ((void)(arg)) | ||
|
||
// by Bubbletune | ||
#define U_EXTRACT_IMPORT(x) ((((u32)_lw((u32)x)) & ~0x08000000) << 2) | ||
#define K_EXTRACT_IMPORT(x) (((((u32)_lw((u32)x)) & ~0x08000000) << 2) | 0x80000000) | ||
#define U_EXTRACT_CALL(x) ((((u32)_lw((u32)x)) & ~0x0C000000) << 2) | ||
#define K_EXTRACT_CALL(x) (((((u32)_lw((u32)x)) & ~0x0C000000) << 2) | 0x80000000) | ||
#define K_EXTRACT_BRANCH(x) ((((((u32)_lw((u32)x)) & 0x0000FFFF) << 2) + x + 4) | 0x80000000) | ||
|
||
// by Acid_Snake | ||
// the opcode is filled with two 0's to the right and shifted to make it a byte long | ||
#define GET_OPCODE(x) ((_lw(x) & 0xFC000000) >> 24) | ||
#define GET_FUNCTION_OPCODE(x) (_lw(x) & 0x3F) | ||
|
||
#define MAKE_JUMP_PATCH(a, f) _sw(0x08000000 | (((u32)(f) & 0x0FFFFFFC) >> 2), a); | ||
#define PTR_ALIGN_64(p) ((void *)((((u32)p) + 64 - 1) & (~(64 - 1)))) | ||
|
||
// by Davee | ||
#define HIJACK_FUNCTION(a, f, ptr) \ | ||
{ \ | ||
u32 func = a; \ | ||
static u32 patch_buffer[3]; \ | ||
_sw(_lw(func), (u32)patch_buffer); \ | ||
_sw(_lw(func + 4), (u32)patch_buffer + 8); \ | ||
MAKE_JUMP_PATCH((u32)patch_buffer + 4, func + 8); \ | ||
_sw(0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF), func); \ | ||
_sw(0, func + 4); \ | ||
ptr = (void *)patch_buffer; \ | ||
} | ||
|
||
#define REDIRECT_SYSCALL(a, f) \ | ||
_sw(JR_RA, a); \ | ||
_sw(SYSCALL(sceKernelQuerySystemCall(f)), a + 4); | ||
|
||
#define MAKE_DUMMY_FUNCTION(a, r) \ | ||
{ \ | ||
u32 func = a; \ | ||
if (r == 0) \ | ||
{ \ | ||
_sw(JR_RA, func); \ | ||
_sw(0x00001021, func + 4); \ | ||
} \ | ||
else \ | ||
{ \ | ||
_sw(JR_RA, func); \ | ||
_sw(0x24020000 | r, func + 4); \ | ||
} \ | ||
} | ||
|
||
#define REDIRECT_FUNCTION(a, f) \ | ||
{ \ | ||
u32 func = a; \ | ||
_sw(0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF), func); \ | ||
_sw(0, func + 4); \ | ||
} | ||
|
||
// Common Kernel Functions | ||
typedef struct KernelFunctions | ||
{ | ||
// iofilemgr.prx Functions | ||
SceUID (*KernelIOOpen)(const char *, int, int); // 0 | ||
int (*KernelIOWrite)(SceUID, const void *, unsigned); // 4 | ||
int (*KernelIORead)(SceUID, void *, unsigned); // 8 | ||
int (*KernelIOLSeek)(int fd, s64 offset, int whence); // 12 | ||
int (*KernelIOClose)(SceUID); // 16 | ||
SceUID (*KernelIODopen)(char *); // 20 | ||
int (*KernelIODread)(SceUID, SceIoDirent *); // 24 | ||
int (*KernelIODclose)(SceUID); // 28 | ||
int (*KernelIOMkdir)(const char *, SceMode); // 32 | ||
int (*KernelIORmdir)(const char *path); // 36 | ||
int (*KernelIOGetStat)(const char *file, SceIoStat *stat); // 40 | ||
int (*KernelIORemove)(const char *file); // 44 | ||
int (*IoAssign)(const char *dev1, const char *dev2, const char *dev3, int mode, void *unk1, long unk2); // 48 | ||
int (*IoUnassign)(const char *dev); // 52 | ||
|
||
// sysmem.prx Functions | ||
SceUID (*KernelAllocPartitionMemory)(SceUID partitionid, const char *name, int type, SceSize size, void *addr); // 56 | ||
void *(*KernelGetBlockHeadAddr)(SceUID blockid); // 60 | ||
int (*KernelFreePartitionMemory)(int); // 64 | ||
void (*KernelIcacheInvalidateAll)(void); // 68 | ||
void (*KernelDcacheWritebackInvalidateAll)(void); // 72 | ||
int (*KernelGzipDecompress)(unsigned char *dest, unsigned int destSize, const unsigned char *src, void *unknown); // 76 | ||
void (*KernelDcacheInvalidateRange)(const void *p, unsigned int size); // 80 | ||
|
||
// threadman.prx Functions | ||
SceUID (*KernelCreateThread)(const char *name, SceKernelThreadEntry entry, | ||
int initPriority, int stackSize, SceUInt attr, SceKernelThreadOptParam *option); // 84 | ||
int (*KernelStartThread)(SceUID thid, SceSize arglen, void *argp); // 88 | ||
int (*KernelDelayThread)(int); // 92 | ||
int (*KernelDeleteThread)(int); // 96 | ||
int (*KernelExitThread)(int); // 100 | ||
void (*waitThreadEnd)(int, int *); // 104 | ||
} KernelFunctions; | ||
|
||
// extern KernelFunctions* k_tbl; | ||
|
||
// Generic utils | ||
#define pspXploitFindFirstJAL(addr) pspXploitFindAnyJAL(addr, 0, 0) | ||
#define pspXploitFindFirstJALReverse(addr) pspXploitFindAnyJAL(addr, 1, 0) | ||
#define pspXploitFindJAL(addr, pos) pspXploitFindAnyJAL(addr, 0, pos) | ||
#define pspXploitFindJALReverse(addr, pos) pspXploitFindAnyJAL(addr, 1, pos) | ||
#define pspXploitFindFirstJALForFunction(modname, libname, nid) findFirstJAL(FindFunction(modname, libname, nid)) | ||
#define pspXploitFindJALForFunction(modname, libname, nid, pos) findJAL(FindFunction(modname, libname, nid), pos) | ||
#define pspXploitFindFirstJALReverseForFunction(modname, libname, nid) findFirstJALReverse(FindFunction(modname, libname, nid)) | ||
#define pspXploitFindJALReverseForFunction(modname, libname, nid, pos) findJALReverse(FindFunction(modname, libname, nid), pos) | ||
u32 pspXploitFindAnyJAL(u32 addr, int reversed, int skip); | ||
u32 pspXploitFindFirstBEQ(u32 addr); | ||
u32 pspXploitFindRefInGlobals(char *libname, u32 addr, u32 ptr); | ||
void pspXploitPatchAccurateError(u32 text_addr, u32 text_size, u16 error); | ||
int pspXploitIsKernel(); | ||
|
||
// User Utils | ||
u32 pspXploitFindImportRange(char *libname, u32 nid, u32 lower, u32 higher); | ||
u32 pspXploitFindImportVolatileRam(char *libname, u32 nid); | ||
u32 pspXploitFindImportUserRam(char *libname, u32 nid); | ||
int pspXploitOpenP5(int mode); | ||
int pspXploitCloseP5(); | ||
u32 pspXploitFindFunctionFromUsermode(const char *library, u32 nid, void *buf, u32 size); | ||
|
||
// Kernel Utils | ||
void pspXploitScanKernelFunctions(KernelFunctions *kfuncs); | ||
u32 pspXploitFindModuleByName(const char *modulename); | ||
u32 pspXploitFindTextAddrByName(const char *modulename); | ||
u32 pspXploitFindFunction(const char *module, const char *library, u32 nid); | ||
int pspXploitSetUserLevel(int level); | ||
|
||
// kernel_read.c | ||
uint64_t pspXploitKernelRead64(uint32_t addr); | ||
void pspXploitDumpKernel(u32 *dst, u32 *src, u32 size); | ||
|
||
// kernel_write.c | ||
int pspXploitInitKernelExploit(); | ||
int pspXploitDoKernelExploit(); | ||
void pspXploitExecuteKernel(u32 kernelContentFunction); | ||
void pspXploitRepairKernel(); | ||
#endif |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#include <common.h> | ||
|
||
int (*_sceIoAssign)(const char *, const char *, const char *, int, void *, long) = NULL; | ||
int (*_sceIoUnassign)(const char *) = NULL; | ||
int (*_sceIoOpen)(const char *, int, SceMode) = NULL; | ||
int (*_sceIoClose)(SceUID) = NULL; | ||
int (*_sceIoRead)(SceUID, void *, SceSize) = NULL; | ||
int (*_sceIoWrite)(SceUID, const void *, SceSize) = NULL; | ||
int (*_sceIoMkdir)(const char *, SceMode) = NULL; | ||
int (*_sceKernelDelayThread)(int) = NULL; | ||
|
||
void tthread(void) | ||
{ | ||
printf("Assigning flash1..."); | ||
_sceIoUnassign("flash1:"); | ||
SceUID f1 = _sceIoAssign("flash1:", "lflash0:0,1", "flashfat1:", 0, NULL, 0); | ||
if (f1 < 0) | ||
{ | ||
TextColor(RED); | ||
printf(" failed! (0x%08x)\n\n", f1); | ||
TextColor(WHITE); | ||
printf("Please try running the program again. Exiting..."); | ||
printf("Press any button to exit."); | ||
return; | ||
} | ||
else | ||
{ | ||
TextColor(GREEN); | ||
printf(" success!\n"); | ||
} | ||
|
||
TextColor(WHITE); | ||
printf("Reading custom_theme.dat..."); | ||
|
||
SceUID ret = _sceIoOpen("flash1:/vsh/theme/custom_theme.dat", PSP_O_RDONLY, 0777); | ||
if (ret < 0) | ||
{ | ||
TextColor(RED); | ||
printf(" failed! (0x%08x)\n\n", ret); | ||
TextColor(WHITE); | ||
printf("Maybe a custom theme wasn't set?\n"); | ||
printf("Press any button to exit."); | ||
return; | ||
} | ||
else | ||
{ | ||
TextColor(GREEN); | ||
printf(" success!\n"); | ||
} | ||
|
||
TextColor(WHITE); | ||
printf("Dumping custom_theme.dat..."); | ||
|
||
int read; | ||
u8 buf[512]; | ||
|
||
_sceKernelDelayThread(500000); | ||
SceUID theme = _sceIoOpen("ms0:/PSP/THEME/custom_theme.ptf", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC, 0777); | ||
if (theme < 0) | ||
{ | ||
_sceIoMkdir("ms0:/PSP/THEME", 0777); | ||
theme = _sceIoOpen("ms0:/PSP/THEME/custom_theme.ptf", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC, 0777); | ||
} | ||
|
||
while ((read = _sceIoRead(ret, buf, 512)) > 0) | ||
_sceIoWrite(theme, buf, read); | ||
|
||
_sceIoClose(ret); | ||
_sceIoClose(theme); | ||
_sceIoUnassign("flash1:"); | ||
_sceKernelDelayThread(3000000); | ||
|
||
TextColor(GREEN); | ||
printf(" success!\n\n"); | ||
TextColor(WHITE); | ||
printf("Saved as ms0:/PSP/THEME/custom_theme.ptf\n"); | ||
printf("Press any button to exit."); | ||
} | ||
|
||
void kthread(void) | ||
{ | ||
_sceIoAssign = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0xB2A628C1); | ||
_sceIoUnassign = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x6D08A871); | ||
_sceIoOpen = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x109F50BC); | ||
_sceIoClose = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); | ||
_sceIoRead = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x6A638D83); | ||
_sceIoWrite = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); | ||
_sceIoMkdir = pspXploitFindFunction("sceIOFileManager", "IoFileMgrForKernel", 0x06A70004); | ||
_sceKernelDelayThread = pspXploitFindFunction("sceThreadManager", "ThreadManForUser", 0xCEADEB47); | ||
|
||
SceUID kthreadID = k_tbl->KernelCreateThread("themadump_kthread", (void *)KERNELIFY(&tthread), 1, 0x20000, PSP_THREAD_ATTR_VFPU, NULL); | ||
if (kthreadID >= 0) | ||
{ | ||
k_tbl->KernelStartThread(kthreadID, 0, NULL); | ||
k_tbl->waitThreadEnd(kthreadID, NULL); | ||
} | ||
} |
Oops, something went wrong.