add grw0 format option

This commit is contained in:
Li 2024-01-29 18:12:53 +13:00
parent 780619d18d
commit 8be1c81acb
17 changed files with 323 additions and 31 deletions

View File

@ -218,7 +218,7 @@ int extract_gc_keys(GcKeys* keys) {
if(!verify_klic_keys(keys)) return -3;
// verify rif buffer
if(has_gro0())
if(file_exist("gro0:"))
if(!verify_rif_keys(keys)) return -2;

View File

@ -15,11 +15,19 @@
// exfatfs does each 0x20000 reading internally - Princess of Sleeping
static uint8_t DEVICE_DUMP_BUFFER[0x20000]__attribute__((aligned(0x40)));
uint8_t device_exist(char* block_device) {
int dfd = OpenDevice(block_device, SCE_O_RDONLY);
if(dfd < 0)
return 0;
CloseDevice(dfd);
return 1;
}
uint64_t device_size(char* block_device) {
uint64_t device_size = 0;
int dfd = OpenDevice(block_device);
int dfd = OpenDevice(block_device, SCE_O_RDONLY);
if(dfd < 0)
return 0;
GetDeviceSize(dfd, &device_size);
@ -35,7 +43,7 @@ int dump_device_network(char* ip_address, unsigned short port, char* block_devic
sceClibPrintf("Begining NETWORK dump of %s to %s:%u\n", block_device, ip_address, port);
// open gc
int device_fd = OpenDevice(block_device);
int device_fd = OpenDevice(block_device, SCE_O_RDONLY);
sceClibPrintf("device_fd = %x\n", device_fd);
if(device_fd < 0) ERROR(device_fd);
@ -107,7 +115,7 @@ int dump_device(char* block_device, char* output_path, GcKeys* keys, void (*prog
if(gc_fd < 0) ERROR(gc_fd);
// open gc
int device_fd = OpenDevice(block_device);
int device_fd = OpenDevice(block_device, SCE_O_RDONLY);
sceClibPrintf("device_fd = %x\n", device_fd);
if(device_fd < 0) ERROR(device_fd);
@ -158,5 +166,47 @@ error:
if(device_fd >= 0)
CloseDevice(device_fd);
return ret;
}
int wipe_device(char* block_device, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
int ret = 0;
uint64_t total_write = 0;
// sanity safety check
if(memcmp(block_device, "sdstor0:gcd", strlen("sdstor0:gcd")) != 0)
return -1;
sceClibPrintf("Begining wipe of %s\n", block_device);
// open device
int device_fd = OpenDevice(block_device, SCE_O_WRONLY); // SCARY
sceClibPrintf("device_fd = %x\n", device_fd);
if(device_fd < 0) ERROR(device_fd);
// get device size
uint64_t device_size = 0;
GetDeviceSize(device_fd, &device_size);
sceClibPrintf("device_size = %llx\n", device_size);
if(device_size == 0) ERROR(-1);
if(progress_callback != NULL) progress_callback(block_device, block_device, total_write, device_size);
memset(DEVICE_DUMP_BUFFER, 0x00, sizeof(DEVICE_DUMP_BUFFER));
// enter write loop
do {
int wr = WriteDevice(device_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // write raw to device
if(wr == 0) ERROR(-2);
if(wr < 0) ERROR(wr);
total_write += wr;
if(progress_callback != NULL) progress_callback(block_device, block_device, total_write, device_size);
} while(total_write < device_size);
error:
if(device_fd >= 0)
CloseDevice(device_fd);
return ret;
}

View File

@ -3,7 +3,10 @@
#define BLOCK_DEVICE_GC "sdstor0:gcd-lp-ign-entire"
#define BLOCK_DEVICE_MEDIAID "sdstor0:gcd-lp-act-mediaid"
#define BLOCK_DEVICE_GRW0 "sdstor0:gcd-lp-ign-gamerw"
#define BLOCK_DEVICE_GRO0 "sdstor0:gcd-lp-ign-gamero"
uint64_t device_size(char* block_device);
int dump_device_network(char* ip_address, unsigned short port, char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
int dump_device(char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
int wipe_device(char* block_device, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
uint8_t device_exist(char* block_device);

View File

@ -8,11 +8,14 @@ int GetLastCmd20Input(char* cmd20_input);
int ResetCmd20Input();
void DecryptSecondaryKey0(void* data, uint32_t key_id, void* packet9, void* out);
int OpenDevice(char* device);
int OpenDevice(char* device, int permission);
int ReadDevice(int device_handle, uint8_t* data, int size);
int WriteDevice(int device_handle, uint8_t* data, int size);
int CloseDevice(int device_handle);
void GetDeviceSize(int device_handle, uint64_t* device_size);
int FormatDevice(char* device);
typedef struct SceSblSmCommGcData {
int always1;
int command;

View File

@ -5,14 +5,6 @@
#include "io.h"
#include "err.h"
int has_gro0() {
return file_exist("gro0:");
}
int has_grw0() {
return file_exist("grw0:");
}
int file_exist(char* path) {
SceIoStat stat;
int res = sceIoGetstat(path, &stat);
@ -21,9 +13,9 @@ int file_exist(char* path) {
}
int wait_for_partition(char* partiton) {
for(int i = 0; i < 300; i++) {
for(int i = 0; i < 50; i++) {
if(file_exist(partiton)) break;
sceKernelDelayThread(10000);
sceKernelDelayThread(5000);
}
return file_exist(partiton);
}

View File

@ -1,9 +1,5 @@
#define MAX_PATH (512)
int has_gro0();
int has_grw0();
int file_exist(char* path);
void remove_illegal_chars(char* str);

View File

@ -16,6 +16,7 @@
#include "device.h"
#include "net.h"
#include "bgm.h"
#include "f00dbridge.h"
void get_output_filename(char* output, char* format, int size_output) {
char title_id[64];
@ -172,6 +173,31 @@ void handle_menu_set_output(char* fmt, int what) {
}
void handle_wipe_option(int what) {
char* block_device = NULL;
switch(what) {
case RESET_MEDIAID:
block_device = BLOCK_DEVICE_MEDIAID;
break;
case RESET_GRW0:
block_device = BLOCK_DEVICE_GRW0;
break;
default:
return;
}
int res = do_device_wipe(block_device, (what == RESET_GRW0) );
char msg[0x1028];
if(res < 0) {
snprintf(msg, sizeof(msg), "There was an error ( res = 0x%08X )", block_device, res);
do_confirm_message("Error!", msg);
}
else{
snprintf(msg, sizeof(msg), "Formatted: \"%s\" ...", block_device);
do_confirm_message("Format Success!", msg);
}
}
void handle_menu_select_option() {
char* fmt = "";
@ -207,6 +233,8 @@ void handle_menu_select_option() {
};
if(selected == DUMP_WHOLE_GC || selected == DUMP_KEYS_ONLY || selected == DUMP_MEDIAID || selected == DUMP_GRW0)
handle_menu_set_output(fmt, selected);
if(selected == RESET_MEDIAID || selected == RESET_GRW0)
handle_wipe_option(selected);
}

View File

@ -100,11 +100,11 @@ int draw_gc_options(int* selected, char* title, uint8_t has_grw0, uint8_t has_me
ADDOPT(has_mediaid, "Backup MediaId Section (.MEDIAID)");
ADDOPT(0 && has_mediaid, "Restore MediaId Section (.MEDIAID)");
ADDOPT(0 && has_mediaid, "Format MediaId Section");
ADDOPT(has_mediaid, "Format MediaId Section");
ADDOPT(has_grw0, "Backup Writable Section (.IMG)");
ADDOPT(0 && has_grw0, "Restore Writable Section (.IMG)");
ADDOPT(0 && has_grw0, "Format Writable Section");
ADDOPT(has_grw0, "Format Writable Section");
end_draw();
@ -185,6 +185,24 @@ int draw_network_settings(int* selected, char* ip_address, unsigned short port)
RETURNOPT();
}
void draw_wipe_progress(char* device, char* output_filename, uint64_t progress, uint64_t total) {
start_draw();
draw_background();
char output_txt[128];
snprintf(output_txt, sizeof(output_txt), "Wiping %s ...", device);
draw_title(output_txt);
snprintf(output_txt, sizeof(output_txt), "Writing \"%.30s\" ...", output_filename);
draw_text_center(200, output_txt);
draw_progress_bar(210, progress, total);
snprintf(output_txt, sizeof(output_txt), "%llu / %llu (%i%%)", progress, total, (int)( (((float)progress) / ((float)total)) * 100.0));
draw_text_center(260, output_txt);
end_draw();
}
void draw_dump_progress(char* device, char* output_filename, uint64_t progress, uint64_t total) {
@ -236,12 +254,18 @@ int do_network_options(char* ip_address, unsigned short port) {
int do_gc_options() {
char title_id[64];
char title[64];
mount_gro0();
mount_grw0();
read_gameinfo(title_id, title);
uint8_t have_grw0 = has_grw0();
remove_illegal_chars(title);
PROCESS_MENU(draw_gc_options, title, have_grw0, 1);
uint8_t has_grw0 = device_exist(BLOCK_DEVICE_GRW0);
uint8_t has_mediaid = device_exist(BLOCK_DEVICE_MEDIAID);
PROCESS_MENU(draw_gc_options, title, has_grw0, has_mediaid);
}
void do_ime() {
@ -254,6 +278,31 @@ void do_confirm_message(char* title, char* msg) {
get_key();
}
int do_device_wipe(char* block_device, uint8_t format) {
umount_gro0();
umount_grw0();
disable_power_off();
mount_devices();
lock_shell();
int res = wipe_device(block_device, draw_wipe_progress);
if(format)
FormatDevice(block_device);
unlock_shell();
enable_power_off();
mount_gro0();
mount_grw0();
umount_devices();
return res;
}
int do_device_dump(char* block_device, char* output_file, uint8_t vci, char* ip_address, unsigned short port) {
GcKeys keys;

View File

@ -4,6 +4,7 @@ void do_gc_insert_prompt();
int do_gc_options();
int do_select_output_location(char* format, char* output, uint64_t device_size);
int do_device_dump(char* block_device, char* output_file, uint8_t vci, char* ip_address, unsigned short port);
int do_device_wipe(char* block_device, uint8_t format);
void do_confirm_message(char* title, char* msg);
int do_network_options(char* ip_address, unsigned short port);
void do_ime();

View File

@ -24,12 +24,17 @@ add_executable(${PROJECT_NAME}
f00d.c
io.c
cobra.c
format.c
cmd56.c
)
target_link_libraries(${PROJECT_NAME}
SKPLForKernel_stub
taihenForKernel_stub
taihenModuleUtils_stub
SceRtcForDriver_stub
SceSysmemForDriver_stub
SceModulemgrForDriver_stub
SceThreadmgrForDriver_stub
SceSblSmCommForKernel_stub
SceIofilemgrForDriver_stub

135
kern/format.c Normal file
View File

@ -0,0 +1,135 @@
/*
* psp2format
* Copyright (C) 2021, Princess of Sleeping
*/
#include <vitasdkkern.h>
#include <taihen.h>
int module_get_offset(SceUID pid, SceUID modid, int segidx, size_t offset, uintptr_t *addr);
typedef struct SceFatFormatParam { // size is 0x30-bytes
SceUInt64 data_0x00;
const char *path;
void *pWorkingBuffer;
SceSize workingBufferSize;
SceSize bytePerCluster;
SceSize bytePerSector;
SceUInt32 data_0x1C; // Unknown. Cleared by internal.
SceUInt32 fat_time;
SceUInt32 data_0x24; // Unknown. Must be zero.
SceUInt32 processing_state;
SceUInt32 sce_fs_type;
} SceFatFormatParam;
#define SCE_FAT_FORMAT_TYPE_FAT12 (1)
#define SCE_FAT_FORMAT_TYPE_FAT16 (2)
#define SCE_FAT_FORMAT_TYPE_FAT32 (3)
#define SCE_FAT_FORMAT_TYPE_EXFAT (4)
int ksceRtcGetCurrentClockLocalTime(SceDateTime *time);
SceUInt32 (* sceAppMgrMakeFatTime)(const SceDateTime *time);
int (* sceAppMgrExecFsFatFormat)(SceFatFormatParam *pParam);
int FatfsExecFormatInternal(const char *s, void *pWorkingBuffer, SceSize workingBufferSize, SceSize bytePerCluster, SceUInt32 sce_fs_type){
int res, old;
SceDateTime time;
SceFatFormatParam ff_param;
res = ksceKernelSetPermission(0x80);
if(res < 0){
return res;
}
old = res;
memset(&time, 0, sizeof(time));
res = ksceRtcGetCurrentClockLocalTime(&time);
if(res < 0){
goto error;
}
memset(pWorkingBuffer, 0, workingBufferSize);
memset(&ff_param, 0, sizeof(ff_param));
ff_param.data_0x00 = 0LL;
ff_param.path = s;
ff_param.pWorkingBuffer = pWorkingBuffer;
ff_param.workingBufferSize = workingBufferSize;
ff_param.bytePerCluster = bytePerCluster;
ff_param.bytePerSector = 0;
ff_param.data_0x1C = 0;
ff_param.fat_time = sceAppMgrMakeFatTime(&time);
ff_param.data_0x24 = 0;
ff_param.processing_state = 0;
ff_param.sce_fs_type = sce_fs_type;
if(bytePerCluster == 0){
if(sce_fs_type == SCE_FAT_FORMAT_TYPE_EXFAT){
ff_param.bytePerCluster = 0x20000;
}else if(sce_fs_type == SCE_FAT_FORMAT_TYPE_FAT32){
ff_param.bytePerCluster = 0x8000;
}else if(sce_fs_type == SCE_FAT_FORMAT_TYPE_FAT16 || sce_fs_type == SCE_FAT_FORMAT_TYPE_FAT12){
ff_param.bytePerCluster = 0x1000;
}
}
res = sceAppMgrExecFsFatFormat(&ff_param);
if(res >= 0)
res = ksceIoSync(s, 0);
error:
ksceKernelSetPermission(old);
return res;
}
int FatfsExecFormat(const char *s, SceSize bytePerCluster, SceUInt32 sce_fs_type) {
int res;
SceUID memid;
void *pWorkingBase;
res = ksceKernelAllocMemBlock("SceFatfsFormatWorkingMemBlock", SCE_KERNEL_MEMBLOCK_TYPE_KERNEL_RW, 0x40000, NULL);
if(res < 0){
return res;
}
memid = res;
res = ksceKernelGetMemBlockBase(memid, &pWorkingBase);
if(res >= 0)
res = FatfsExecFormatInternal(s, pWorkingBase, 0x40000, bytePerCluster, sce_fs_type);
ksceKernelFreeMemBlock(memid);
return res;
}
int FormatDevice(char* device) {
int state = 0;
ENTER_SYSCALL(state);
static char k_device[1028];
ksceKernelStrncpyUserToKernel(k_device, (const void*)device, sizeof(k_device));
if(memcmp(k_device, "sdstor0:gcd", 11) != 0)
return -1;
int res = FatfsExecFormat(k_device, 0x8000, SCE_FAT_FORMAT_TYPE_EXFAT);
EXIT_SYSCALL(state);
return res;
}
void get_module_functions() {
SceUID module_id;
module_id = ksceKernelSearchModuleByName("SceAppMgr");
if(module_id > 0){
module_get_offset(KERNEL_PID, module_id, 0, 0x39B54 | 1, (uintptr_t*)&sceAppMgrMakeFatTime);
module_get_offset(KERNEL_PID, module_id, 0, 0x3E238 | 1, (uintptr_t*)&sceAppMgrExecFsFatFormat);
}
}

3
kern/format.h Normal file
View File

@ -0,0 +1,3 @@
#include <vitasdkkern.h>
int FormatDevice(char* device);
void get_module_functions();

View File

@ -4,9 +4,9 @@
#include <vitasdkkern.h>
int k_open_device(char* device) {
int k_open_device(char* device, int permission) {
int prev = ksceKernelSetPermission(0x80);
int fd = ksceIoOpen(device, SCE_O_RDONLY, 0777);
int fd = ksceIoOpen(device, permission, 0777);
ksceKernelSetPermission(prev);
return fd;
}
@ -18,6 +18,13 @@ int k_read_device(int device_handle, uint8_t* data, int size) {
return res;
}
int k_write_device(int device_handle, uint8_t* data, int size) {
int prev = ksceKernelSetPermission(0x80);
int res = ksceIoWrite(device_handle, data, size);
ksceKernelSetPermission(prev);
return res;
}
int k_close_device(int device_handle){
int prev = ksceKernelSetPermission(0x80);
ksceIoClose(device_handle);
@ -36,14 +43,30 @@ uint64_t k_get_device_size(int device_handle) {
// io syscalls
int OpenDevice(char* device) {
int OpenDevice(char* device, int permission) {
static char k_device[1028];
ksceKernelStrncpyUserToKernel(k_device, (const void*)device, sizeof(k_device));
return k_open_device(k_device);
return k_open_device(k_device, permission);
}
int WriteDevice(int device_handle, uint8_t* data, int size) {
void* k_data = NULL;
size_t k_size = 0;
uint32_t k_offset = 0;
int uid = ksceKernelUserMap("F00DBRIDGE_WRITE", 3, data, size, &k_data, &k_size, &k_offset);
if(uid < 0)
return uid;
int res = k_write_device(device_handle, (k_data + k_offset) , size);
ksceKernelMemBlockRelease(uid);
return res;
}
int ReadDevice(int device_handle, uint8_t* data, int size) {
void* k_data = NULL;
size_t k_size = 0;

View File

@ -1,4 +1,5 @@
int OpenDevice(char* device);
int OpenDevice(char* device, int permission);
int ReadDevice(int device_handle, uint8_t* data, int size);
int WriteDevice(int device_handle, uint8_t* data, int size)
int CloseDevice(int device_handle);
uint64_t GetDeviceSize(int device_handle);

View File

@ -20,6 +20,7 @@ f00dbridge:
- ResetCmd20Input
- OpenDevice
- ReadDevice
- WriteDevice
- CloseDevice
- GetDeviceSize
- FormatDevice

View File

@ -4,12 +4,14 @@
#include <vitasdkkern.h>
#include "cmd56.h"
#include "cobra.h"
#include "format.h"
void _start() __attribute__((weak, alias("module_start")));
int module_start(SceSize argc, const void *args)
{
cobra_patch(); // revert cobra blackfin patch
cmd56_patch(); // patch cmd56 ..
get_module_functions(); // get format stuff
return SCE_KERNEL_START_SUCCESS;
}

View File

@ -82,8 +82,8 @@ int main(int argc, char *argv[])
while(1)
{
int connectionFd = ACCEPT_SOCKET(listenFd);
pthread_t thread_fd;
pthread_create(&thread_fd, NULL, receive_file, &connectionFd);
pthread_t threadFd;
pthread_create(&threadFd, NULL, receive_file, &connectionFd);
sleep(1);
}