Skip to content

Commit

Permalink
Bug fixes and improves
Browse files Browse the repository at this point in the history
  • Loading branch information
ac2pic committed Oct 29, 2023
1 parent 0926530 commit a9f8792
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 25 deletions.
2 changes: 1 addition & 1 deletion config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import os
switch "o", "cecie.elf"
switch "mm", "orc"
switch "nimcache", "./cache"
# switch "threads", "off"
switch "threads", "off"

proc getContentId: string =
let servId = getEnv("app_SERVICE_ID")
Expand Down
31 changes: 20 additions & 11 deletions src/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type ServerResponse = object
type SaveListEntry = object
kind: PathComponent
path: string
size: Off
mode: Mode
uid: Uid
gid: Gid
Expand Down Expand Up @@ -70,7 +71,7 @@ proc setupCredentials() =
# Run as root
var cred = get_cred()
cred.sonyCred = cred.sonyCred or uint64(0x40_00_00_00_00_00_00_00)
cred.sceProcType = uint64(0x3800000000000010)
cred.sceProcType = uint64(0x3801000000000013)
discard set_cred(cred)
discard setuid(0)

Expand Down Expand Up @@ -192,6 +193,11 @@ proc updateSave(cmd: ClientRequest, client: AsyncSocket, mountId: string) {.asyn
respondWithError(client, "E:MOUNT_FAILED-" & handle.toHex(8))
else:
for (kind, relativePath) in getRequiredFiles(cmd.sourceFolder, cmd.selectOnly):
if relativePath.startsWith("sce_sys") or relativePath == "memory.dat":
discard setuid(0)
else:
discard setuid(1)

let targetPath = joinPath(mntFolder, relativePath)
if kind == pcDir:
discard mkdir(targetPath.cstring, 0o777)
Expand All @@ -206,6 +212,7 @@ proc updateSave(cmd: ClientRequest, client: AsyncSocket, mountId: string) {.asyn
respondWithError(client, "E:COPY_FAILED")
failed = true
break
discard setuid(0)
discard umountSave(mntFolder, handle, false)
discard rmdir(mntFolder.cstring)
if failed:
Expand All @@ -226,32 +233,34 @@ proc listSaveFiles(cmd: ClientRequest, client: AsyncSocket, mountId: string) {.a
discard mkdir(mntFolder.cstring, 0o777)

let (errPath, handle) = mountSave(SAVE_DIRECTORY, cmd.listTargetSaveName, mntFolder)
var listEntries: seq[SaveListEntry] = newSeq[SaveListEntry]()
var failed = errPath != 0
if errPath != 0:

if failed:
respondWithError(client, "E:MOUNT_FAILED-" & handle.toHex(8))
else:
var listEntries: seq[SaveListEntry] = newSeq[SaveListEntry]()
for (kind, relativePath) in getRequiredFiles(mntFolder, @[]):
var s : Stat
if stat((mntFolder / relativePath).cstring, s) == -1:
respondWithError(client, "E:STAT_FAILED-" & errno.toHex(8))
failed = true
break
listEntries.add SaveListEntry(kind: kind, path: relativePath, mode: s.st_mode, uid: s.st_uid, gid: s.st_gid)
respondWithJson(client, %listEntries)
listEntries.add SaveListEntry(kind: kind, path: relativePath, size: s.st_size, mode: s.st_mode, uid: s.st_uid, gid: s.st_gid)
discard umountSave(mntFolder, handle, false)
discard rmdir(mntFolder.cstring)
if failed:
exitnow(-1)
else:
exitnow(0)
if not failed:
respondWithJson(client, %listEntries)
# Should not do a srOk response since that's redundant
exitnow(-1)

type RequestHandler = proc (cmd: ClientRequest, client: AsyncSocket, mountId: string) {.async.}
var cmds : array[ClientRequestType, RequestHandler]
cmds[rtDumpSave] = dumpSave
cmds[rtUpdateSave] = updateSave
cmds[rtListSaveFiles] = listSaveFiles
var slot: int
var slotTotal: int
var slot: uint
var slotTotal: uint32

proc handleForkCmds(client: AsyncSocket, cmd: ClientRequest) {.async.} =
inc slot
# No matter who mounts
Expand Down
6 changes: 2 additions & 4 deletions src/main.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "./savedata"
import "./utils"
import "./commands"
import "./requests"

import libjbc
import posix
{.passc: "-fstack-protector".}
Expand All @@ -31,7 +32,7 @@ proc setup() =
echo stat("/rootdev/sbl_srv", s)
echo sys_mknod("/dev/sbl_srv", Mode(S_IFCHR or 0o777), s.st_dev)
discard sudo_unmount("rootdev")

# Get max keyset that can be decrypted
discard getMaxKeySet()
var old_cred = get_cred()
Expand All @@ -42,13 +43,10 @@ cred.sonyCred = cred.sonyCred or uint64(0x40_00_00_00_00_00_00_00)
cred.sceProcType = uint64(0x3801000000000013)
discard set_cred(cred)
discard setuid(0)


setup()
discard set_cred(old_cred)



proc handleClient(clientContext : tuple[address: string, client: AsyncSocket]) {.async.} =
# Wait for message
# let address = clientContext.address
Expand Down
24 changes: 15 additions & 9 deletions src/savedata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var sceFsInitCreatePfsSaveDataOpt: proc(opt: ptr CreatePfsSaveDataOpt) : cint {.
var sceFsCreatePfsSaveDataImage : proc(opt: ptr CreatePfsSaveDataOpt, volumePath: cstring, idk:cint, volumeSize: culonglong, decryptSealedKey : array[32,byte]) : cint {.cdecl.}

type MountSaveDataOpt = object
idk: bool
readOnly: bool
budgetid: cstring

var sceFsInitMountSaveDataOpt: proc(opt: ptr MountSaveDataOpt) : cint {.cdecl.}
Expand Down Expand Up @@ -103,20 +103,25 @@ proc createSave*(folder: string, saveName: string, blocks: cint) : cint =
discard close(fd);
return 0

proc mountSave*(folder: string, saveName: string, mountPath: string) : tuple[path: cint, error : cint] =
proc decryptSealedKeyAtPath*(keyPath: string, decryptedSealedKey: var array[32,byte]) : cint =
var sealedKey : array[96, byte]
var volumeKeyPath : string = joinPath(folder, saveName & ".bin")
var volumePath : string = joinPath(folder, saveName)
var fd = sys_open(volumeKeyPath.cstring, O_RDONLY, 0)
var fd = sys_open(keyPath.cstring, O_RDONLY, 0)
if fd == -1:
return (-1, errno)
return -1
discard read(fd,sealedKey.addr, sealedKey.len)
discard close(fd)

var decryptedSealedKey: array[32, byte]
var ret = decryptSealedKey(sealedKey, decryptedSealedKey)
if ret == -1:
return (-2, errno)
return -2
return 0

proc mountSave*(folder: string, saveName: string, mountPath: string) : tuple[path: cint, error : cint] =
var volumeKeyPath : string = joinPath(folder, saveName & ".bin")
var volumePath : string = joinPath(folder, saveName)
var decryptedSealedKey: array[32,byte]
var ret = decryptSealedKeyAtPath(volumeKeyPath, decryptedSealedKey)
if ret < 0:
return (ret, errno)
var opt : MountSaveDataOpt
discard sceFsInitMountSaveDataOpt(opt.addr)
var bid: string = "system"
Expand All @@ -126,6 +131,7 @@ proc mountSave*(folder: string, saveName: string, mountPath: string) : tuple[pat
return (-3, ret)
return (0, 0)


proc umountSave*(mountPath: string, handle: cint, ignoreErrors: bool) : cint =
var opt: UmountSaveDataOpt
discard sceFsInitUmountSaveDataOpt(opt.addr)
Expand Down
95 changes: 95 additions & 0 deletions src/syscalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,57 @@ proc sys_open*(path: cstring, flags: cint, mode: cint = 0): cint {.cdecl, export
"""
toCError(result, err)

proc sys_read*(fd: cint, buffer: pointer, sz: int): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 3;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_pread*(fd: cint, buffer: pointer, sz: int, offset: Off): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 475;"
"mov r10, rcx;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_write*(fd: cint, buffer: pointer, sz: int): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 4;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_pwrite*(fd: cint, buffer: pointer, sz: int, offset: Off): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 476;"
"mov r10, rcx;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_close*(fd: cint): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 6;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_symlink*(src: cstring, dest: cstring): cint {.cdecl, exportc.} =
var err: bool
Expand All @@ -31,6 +82,16 @@ proc sys_symlink*(src: cstring, dest: cstring): cint {.cdecl, exportc.} =
"""
toCError(result, err)

proc sys_unmount*(dir: cstring, flags: cint): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 22;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_link*(src: cstring, dest: cstring): cint {.cdecl, exportc.} =
var err: bool
asm """
Expand All @@ -40,6 +101,17 @@ proc sys_link*(src: cstring, dest: cstring): cint {.cdecl, exportc.} =
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_rename*(src: cstring, dest: cstring): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 128;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_chroot*(newRoot: cstring): cint {.cdecl, exportc.} =
var err: bool
asm """
Expand All @@ -60,6 +132,7 @@ proc sys_mknod*(path: cstring, mode: Mode, dev: Dev): cint {.cdecl, exportc.} =
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

proc sys_fork*(): cint {.cdecl, exportc.} =
var err: bool
asm """
Expand All @@ -68,4 +141,26 @@ proc sys_fork*(): cint {.cdecl, exportc.} =
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""

proc sys_get_authinfo*(pid : Pid, authinfo: pointer) : cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 587;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
proc sys_sysctl*(name: var cint, namelen: cuint,
oldp: pointer, oldlenp: var csize_t,
newp: pointer, newlen: csize_t): cint {.cdecl, exportc.} =
var err: bool
asm """
".intel_syntax;"
"mov rax, 202;"
"mov r10, rcx;"
"syscall;"
: "=a"(`result`), "=@ccc"(`err`)
"""
toCError(result, err)

{.pop.}

0 comments on commit a9f8792

Please sign in to comment.