Skip to content

Commit

Permalink
Fixed a lot of games
Browse files Browse the repository at this point in the history
new entry point
added fast/normal mode
  • Loading branch information
Maschell committed Oct 17, 2015
1 parent 424402e commit a25fcc1
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 213 deletions.
12 changes: 9 additions & 3 deletions README
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Saviine 0.1
Saviine 0.2

Compatible with 5.3.2 fw

dumps WiiU Saves and is a mod of cafiine. Thanks to everyone who worked on cafiine!

Compilation :
- in order to compile cafiine you need to put the cafiine folder in your libwiiu project
- libwiiu/cafiine/installer must be compiled like the other libwiiu examples (with the build.py script)
- in order to compile saviine you need to put the saviine folder in your libwiiu project
- libwiiu/saviine/installer must be compiled like the other libwiiu examples (with the build.py script)

Pre-made version :
- in www/saviine, it is already compiled, just put the folder in your server
Expand All @@ -15,10 +15,16 @@ Note :
- you can change the server ip directly in the application.
- start the saviine in folder with a short path, some savedata files have some really long names (170+ chracters)
- backup your savedata before dumping it!!! I'm not responsible for any lost data.
- fastmode doesn't work for all games.

How to use :
Usage:
Normal mode: saviine_server.exe
Fast mode: saviine_server.exe fastmode

- launch the kernel exploit in the brower
- open saviine server in your computer, check your ip
(you can start the server in fastmode (faster dumper), this doesn't work for all games. Only use it when the savegame is really big (e.g. Super Smash Bros for WiiU) )
- relaunch browser and launch saviine app, set saviine server ip in the application with up/down/left/right, and press A to install saviine
-> browser should exit
- launch a game or application
Expand Down
191 changes: 114 additions & 77 deletions saviine/client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFla
extern FSStatus FSReadFile(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error);
extern FSStatus FSSetPosFile(FSClient *pClient, FSCmdBlock *pCmd, int fd, int pos, int error);
extern FSStatus FSCloseFile (FSClient *pClient, FSCmdBlock *pCmd, int fd, int error);
extern FSStatus FSOpenFile(FSClient *pClient, FSCmdBlock *pCmd, char *path, const char *mode, int *handle, int error);
extern void OSDynLoad_Acquire (char* rpl, unsigned int *handle);
extern void OSDynLoad_FindExport (unsigned int handle, int isdata, char *symbol, void *address);
void GX2WaitForVsync(void);
static void dump_saves(void *pClient, void *pCmd,int error, int client);
// Async
typedef void (*FSAsyncCallback)(void *pClient, void *pCmd, int result, void *context);
typedef struct
{
FSAsyncCallback userCallback;
void *userContext;
void *ioMsgQueue;
} FSAsyncParams;

DECL(int, FSAInit, void) {
if ((int)bss_ptr == 0x0a000000) {
Expand Down Expand Up @@ -43,9 +54,6 @@ DECL(int, FSADelClient, int client) {

return real_FSADelClient(client);
}
DECL(int, FSAOpenFile, int client, const char *path, const char *mode, int *handle) {
return real_FSAOpenFile(client, path, mode, handle);
}

static int client_num_alloc(void *pClient) {
int i;
Expand All @@ -57,9 +65,11 @@ static int client_num_alloc(void *pClient) {
}
return -1;
}

static void clietn_num_free(int client) {
bss.pClient_fs[client] = 0;
}

static int client_num(void *pClient) {
int i;

Expand All @@ -69,12 +79,53 @@ static int client_num(void *pClient) {
return -1;
}

DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) {

if ((int)bss_ptr != 0x0a000000) {
int client = client_num(pClient);
if (client < MAX_CLIENT && client >= 0) {
if(bss.savesDumped == 0){
dump_saves(pClient,pCmd,error,client);
bss.savesDumped = 1;
}
}
}

struct fs_async_t {
void (*callback)(int status, int command, void *request, void *response, void *context);
void *context;
void *queue;
};
return real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
}

static void init_Save(){
int (*SAVEInit)();
unsigned int save_handle;
char buffer[50];
int i = 0;
buffer[i++] = 'n';
buffer[i++] = 'n';
buffer[i++] = '_';
buffer[i++] = 's';
buffer[i++] = 'a';
buffer[i++] = 'v';
buffer[i++] = 'e';
buffer[i++] = '.';
buffer[i++] = 'r';
buffer[i++] = 'p';
buffer[i++] = 'l';
buffer[i++] = '\0';
OSDynLoad_Acquire(buffer, &save_handle);
i = 0;
buffer[i++] = 'S';
buffer[i++] = 'A';
buffer[i++] = 'V';
buffer[i++] = 'E';
buffer[i++] = 'I';
buffer[i++] = 'n';
buffer[i++] = 'i';
buffer[i++] = 't';
buffer[i++] = '\0';

OSDynLoad_FindExport(save_handle, 0, buffer, &SAVEInit);
SAVEInit();
}

#define DUMP_BLOCK_SIZE (0x200 * 100)
#define DUMP_BLOCK_SIZE_SLOW (0x20 * 100)
Expand All @@ -89,7 +140,7 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
new_mode[1] = '\0';

FSDirEntry dir_entry;
while (FSReadDir(pClient, pCmd, dir_handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
while (FSReadDir(pClient, pCmd, dir_handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
{
char full_path[255];
int i=0;
Expand All @@ -105,14 +156,15 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
full_path[i++] = '\0';

log_string(bss.socket_fsa[client], full_path, BYTE_LOG_STR);

if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
char type[4];
type[0] = 'd';
type[1] = 'i';
type[2] = 'r';
type[3] = '\0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
dump_dir(pClient,client,pCmd,full_path,error,my_handle);
dump_dir(pClient,client, pCmd,full_path,-1,my_handle);
}else{
char type[5];
type[0] = 'f';
Expand All @@ -121,70 +173,38 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
type[3] = 'e';
type[4] = '\0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);

//DUMP
ret = FSOpenFile(pClient, pCmd, full_path, new_mode, &my_handle, error);
if (ret >= 0) {
int my_ret = 1;
ret = real_FSOpenFile(pClient, pCmd, full_path, new_mode, &my_handle, FS_RET_ALL_ERROR);
if (ret >= 0) {
int my_ret = cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
log_string(bss.socket_fsa[client], full_path, BYTE_LOG_STR);

int size = (my_ret == 1 ? DUMP_BLOCK_SIZE : DUMP_BLOCK_SIZE_SLOW);
cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
void* buffer = memalign(sizeof(char) * size, 0x40);
int ret2;
while ((ret2 = FSReadFile(pClient, pCmd, buffer, 1, size, my_handle, 0, error)) > 0)
void * buffer = memalign(sizeof(char) * size, 0x40);
int ret2;
while ((ret2 = FSReadFile(pClient, pCmd, buffer, 1, size, my_handle, 0, 0)) > 0)
cafiine_send_file(bss.socket_fsa[client], buffer, ret2, my_handle);
cafiine_fclose(bss.socket_fsa[client], &ret2, my_handle);
FSSetPosFile(pClient, pCmd, my_handle, 0, error);
cafiine_fclose(bss.socket_fsa[client], &ret2, my_handle);
FSSetPosFile(pClient, pCmd, my_handle, 0, FS_RET_ALL_ERROR);
free(buffer);
FSCloseFile(pClient, pCmd, my_handle, -1);
}
}
FSCloseFile(pClient, pCmd, my_handle, -1);
}else{
type[0] = '9' + ret;
type[1] = '0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
}
}

}
FSCloseDir(pClient, pCmd, dir_handle, FS_RET_NO_ERROR);
}else{
/*
char error[3];
error[0] = '-';
error[1] = (ret*-1) + '0';
error[2] = '\0'; */
//log_string(bss.socket_fsa[client], foo, BYTE_LOG_STR);
return -1;
}
FSCloseDir(pClient, pCmd, dir_handle, FS_RET_NO_ERROR);
}
return 0;
}

DECL(int, FSInit, void) {
if ((int)bss_ptr == 0x0a000000) {
bss_ptr = memalign(sizeof(struct bss_t), 0x40);
memset(bss_ptr, 0, sizeof(struct bss_t));
}
return real_FSInit();
}
DECL(int, FSShutdown, void) {
return real_FSShutdown();
}
DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
int res = real_FSAddClientEx(r3, r4, r5);

if ((int)bss_ptr != 0x0a000000 && res >= 0) {
int client = client_num_alloc(r3);
if (client < MAX_CLIENT && client >= 0) {
cafiine_connect(&bss.socket_fs[client]);
}
}
return res;
}
DECL(int, FSDelClient, void *pClient) {
if ((int)bss_ptr != 0x0a000000) {
int client = client_num(pClient);
if (client < MAX_CLIENT && client >= 0) {
cafiine_disconnect(bss.socket_fs[client]);
clietn_num_free(client);
}
}
return real_FSDelClient(pClient);
}

static void dump_saves(void *pClient, void *pCmd,int error, int client){
init_Save();

int i = 0;
char save_path[255];
char save_user[9];
Expand Down Expand Up @@ -238,7 +258,7 @@ static void dump_saves(void *pClient, void *pCmd,int error, int client){
int id = 1;
do{
//log_string(bss.socket_fsa[client], save_path, BYTE_LOG_STR);
if (dump_dir(pClient,client,pCmd,save_path,error,50) == 0);// id = 257; // break if successful
if (dump_dir(pClient,client,pCmd,save_path,-1,50) == 0);// id = 257; // break if successful
int first = id/16;
int seconds = id%16;
if(first <= 9)
Expand Down Expand Up @@ -276,18 +296,36 @@ static void dump_saves(void *pClient, void *pCmd,int error, int client){
log_string(bss.socket_fsa[client], info, BYTE_LOG_STR);
}

DECL(int, FSGetStat, void *pClient, void *pCmd, char *path, void *stats, int error) {
DECL(int, FSInit, void) {
if ((int)bss_ptr == 0x0a000000) {
bss_ptr = memalign(sizeof(struct bss_t), 0x40);
memset(bss_ptr, 0, sizeof(struct bss_t));
}
return real_FSInit();
}
DECL(int, FSShutdown, void) {
return real_FSShutdown();
}
DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
int res = real_FSAddClientEx(r3, r4, r5);

if ((int)bss_ptr != 0x0a000000 && res >= 0) {
int client = client_num_alloc(r3);
if (client < MAX_CLIENT && client >= 0) {
cafiine_connect(&bss.socket_fs[client]);
}
}
return res;
}
DECL(int, FSDelClient, void *pClient) {
if ((int)bss_ptr != 0x0a000000) {
int client = client_num(pClient);

if (client < MAX_CLIENT && client >= 0) {
if(bss.savesDumped == 0){
dump_saves(pClient,pCmd,error,client);
bss.savesDumped = 2;
}
}
cafiine_disconnect(bss.socket_fs[client]);
clietn_num_free(client);
}
}
return real_FSGetStat(pClient, pCmd, path, stats, error);
return real_FSDelClient(pClient);
}

#define MAKE_MAGIC(x) { x, my_ ## x, &real_ ## x }
Expand All @@ -300,9 +338,8 @@ struct magic_t {
MAKE_MAGIC(FSAInit),
MAKE_MAGIC(FSAShutdown),
MAKE_MAGIC(FSAAddClient),
MAKE_MAGIC(FSADelClient),
MAKE_MAGIC(FSAOpenFile),
MAKE_MAGIC(FSGetStat),
MAKE_MAGIC(FSADelClient),
MAKE_MAGIC(FSOpenFile),
MAKE_MAGIC(FSInit),
MAKE_MAGIC(FSShutdown),
MAKE_MAGIC(FSAddClientEx),
Expand Down
2 changes: 1 addition & 1 deletion saviine/client/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct bss_t {
void cafiine_connect(int *socket);
void cafiine_disconnect(int socket);
int cafiine_fopen(int socket, int *result, const char *path, const char *mode, int *handle);
void cafiine_send_handle(int sock, int client, const char *path, int handle);
int cafiine_send_handle(int sock, int client, const char *path, int handle);
void cafiine_send_file(int sock, char *file, int size, int fd);
int cafiine_fread(int socket, int *result, void *buffer, int size, int count, int fd);
int cafiine_fclose(int socket, int *result, int fd);
Expand Down
23 changes: 16 additions & 7 deletions saviine/client/saviine.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ static int cafiine_handshake(int sock);
//#define BYTE_STATFILE 0x05
//#define BYTE_EOF 0x06
//#define BYTE_GETPOS 0x07
//#define BYTE_REQUEST 0x08
//#define BYTE_REQUEST_SLOW 0x09
#define BYTE_REQUEST 0x08
#define BYTE_REQUEST_SLOW 0x09
#define BYTE_HANDLE 0x0A
#define BYTE_DUMP 0x0B
#define BYTE_PING 0x0C
Expand Down Expand Up @@ -80,11 +80,11 @@ static int cafiine_handshake(int sock) {
}


void cafiine_send_handle(int sock, int client, const char *path, int handle)
int cafiine_send_handle(int sock, int client, const char *path, int handle)
{
while (bss.lock) GX2WaitForVsync();
bss.lock = 1;

CHECK_ERROR(sock == -1);

// create and send buffer with : [cmd id][handle][path length][path data ...]
Expand All @@ -104,14 +104,23 @@ void cafiine_send_handle(int sock, int client, const char *path, int handle)
ret = sendwait(sock, buffer, 1 + 4 + 4 + len_path);
CHECK_ERROR(ret < 0);

// wait reply
// wait reply
ret = recvbyte(sock);
CHECK_ERROR(ret != BYTE_SPECIAL);
if(ret == BYTE_REQUEST){
ret = 1;
}else{
ret = 2;
}
// wait reply
int special_ret = recvbyte(sock);
CHECK_ERROR(special_ret != BYTE_SPECIAL);
bss.lock = 0;
return ret;
}

error:
bss.lock = 0;
return;
return -1;
}

void cafiine_send_file(int sock, char *file, int size, int fd) {
Expand Down
Loading

0 comments on commit a25fcc1

Please sign in to comment.