Last active
May 11, 2023 16:38
-
-
Save Reisyukaku/dba796a54d2c92e2c356153a418ca034 to your computer and use it in GitHub Desktop.
Write Save
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
/* | |
* 1. Boot game | |
* 2. Wait a second or so (for the game tid to register but before the code mounts the savedata) | |
* 3. Home button | |
* 4. Run this script | |
* 5. ??? | |
* 6. PROFIT | |
*/ | |
var tid = '0000000000000000'; //Change Title ID here | |
utils.log("stage1, hijack fsppr and set perms"); | |
sc.getFSPPR(); | |
sc.ipcMsg(1).sendPid().data(0).sendTo('fsp-srv').assertOk(); | |
var pid = sc.read4(sc.ipcBufAddr, 0xC >> 2); | |
utils.log('Got process PID: '+pid.toString(16)); | |
var buf1_sz = 0x1C; | |
var buf2_sz = 0x2C; | |
var buf = sc.malloc(buf1_sz + buf2_sz); | |
var buf2 = utils.add2(buf, buf1_sz); | |
//buffer init | |
sc.write4(1, buf, 0x0>>2); | |
sc.write8([0xFFFFFFFF, 0xFFFFFFFF], buf, 0x4 >> 2); //This is the permissions value. | |
sc.write4(buf1_sz, buf, 0xC >> 2); | |
sc.write4(buf1_sz, buf, 0x14 >> 2); | |
sc.write4(1, buf2, 0x0 >> 2); | |
sc.write8([0xFFFFFFFF, 0xFFFFFFFF], buf2, 0x4 >> 2); //This is the permissions value -- actual perms = buf2_val & buf1_val | |
sc.write4(0xFFFFFFFF, buf2, 0x14 >> 2); | |
sc.write4(0xFFFFFFFF, buf2, 0x18 >> 2); | |
sc.write4(0xFFFFFFFF, buf2, 0x24 >> 2); | |
sc.write4(0xFFFFFFFF, buf2, 0x28 >> 2); | |
sc.ipcMsg(256).data(0).sendTo('fsp-pr').assertOk().show(); | |
sc.ipcMsg(1).data(pid).sendTo('fsp-pr').assertOk().show(); | |
sc.ipcMsg(0).data(2, [pid,0], utils.parseAddr(tid), buf1_sz, buf2_sz, pid, pid, 0, 0, 0, 0, 0).aDescriptor(buf, buf1_sz).aDescriptor(buf2, buf2_sz).sendTo('fsp-pr').assertOk().show(); | |
sc.free(buf); | |
sc.free(buf2); | |
utils.log("stage2, open save data"); | |
utils.log("GetLastUserProfile"); | |
res = sc.ipcMsg(4).sendTo('acc:u1').assertOk(); | |
var userID = res.data; | |
utils.log('MountSaveData'); | |
res = sc.ipcMsg(51).datau64(1, utils.parseAddr(tid), [userID[0], userID[1]], [userID[2], userID[3]], [0,0], 1, 0, 0, 0).sendTo('fsp-srv').assertOk(); | |
copyFiles = function(saveDir, sdDir){ | |
var entryCount = utils.trunc32(sdDir.GetEntryCount().assertOk()); | |
if (entryCount > 0) { | |
var entryBuf = new Uint32Array(0x310 * entryCount); | |
sdDir.GetEntries(entryBuf, entryCount).assertOk(); | |
for (i = 0; i < entryCount; i++) { | |
var fn = utils.u8a2nullstr(new Uint8Array(entryBuf.buffer, 0x310 * i, 0x300)); | |
var eType = entryBuf[(0x310 * i + 0x304) >> 2]; | |
if (eType === 1) { | |
//files | |
utils.log('[Writing file] ' + sdDir.path + fn + ' -> ' + saveDir.path + fn); | |
var fp = saveDir.fs.OpenFile(saveDir.path + fn).assertOk(); | |
var fp_sd = sdDir.fs.OpenFile(sdDir.path + fn).assertOk(); | |
try { | |
var size = fp_sd.GetSize().assertOk(); | |
var buf = fp_sd.Read(size).assertOk(); | |
fp.Write(0, buf, size).assertOk(); | |
utils.log('Wrote ' + size + ' bytes'); | |
} finally { | |
fp.Close(); | |
fp_sd.Close(); | |
} | |
} else { | |
//folders | |
utils.log('[Opening folder] '+fn); | |
var f = saveDir.fs.OpenDir(saveDir.path + fn + '/').assertOk(); | |
var f_sd = sdDir.fs.OpenDir(sdDir.path + fn + '/').assertOk(); | |
try { | |
copyFiles(f, f_sd); | |
} finally { | |
f.Close(); | |
f_sd.Close(); | |
} | |
} | |
} | |
} | |
}; | |
sc.withHandle(res.movedHandles[0], (ifile) => { | |
utils.log("Mounting SD card"); | |
try { | |
var sd_mnt = sc.ipcMsg(18).sendTo('fsp-srv').assertOk(); | |
} catch(e) { | |
throw new Error("Failed to open SD card. Is it inserted?"); | |
} | |
sd_mnt.withHandles((r, m, c) => { | |
var fs = new sc.IFileSystem(sc, ifile); | |
var fs_sd = new sc.IFileSystem(sc, m[0]); | |
var dir = fs.OpenDir('/').assertOk(); | |
var dir_sd = fs_sd.OpenDir('/Saves/'+tid+'/').assertOk(); | |
try{ | |
copyFiles(dir, dir_sd); | |
} finally { | |
dir.Close(); | |
dir_sd.Close(); | |
} | |
utils.log('Closing file systems'); | |
fs.Commit(); | |
fs.Close(); | |
fs_sd.Close(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I always get this mistake:
ERROR: [15, 'sc.getFSPPR is not a function. (In \ 'sc.getFSPPR()\', \ 'sc.getFSPPR\' is undefined)' ]