| 592 | } |
| 593 | |
| 594 | void ImmCodec::emit_handler(X64Emitter& e, const VMConfig& vm) const { |
| 595 | const auto& r = vm.dispatcher_regs(); |
| 596 | |
| 597 | // slot index → scratch_a; width byte → scratch_b |
| 598 | emit_fetch_byte_dec(e, vm, r.scratch_a); |
| 599 | emit_fetch_byte_dec(e, vm, r.scratch_b); |
| 600 | |
| 601 | // fetch the 4 obfuscation components, 8 bytes each, then compute |
| 602 | // a + b xor c - d |
| 603 | e.sub_reg_imm32(rx::rsp, 48); // 32 for components, 16 for align |
| 604 | |
| 605 | // a -> [rsp+16] |
| 606 | emit_fetch_uN_dec( |
| 607 | e, |
| 608 | vm, |
| 609 | rx::rax, |
| 610 | 8 |
| 611 | ); |
| 612 | e.mov_mem_reg( |
| 613 | rx::rsp, |
| 614 | 16, |
| 615 | rx::rax, |
| 616 | true |
| 617 | ); |
| 618 | |
| 619 | // b -> [rsp+24] |
| 620 | emit_fetch_uN_dec( |
| 621 | e, |
| 622 | vm, |
| 623 | rx::rax, |
| 624 | 8 |
| 625 | ); |
| 626 | e.mov_mem_reg( |
| 627 | rx::rsp, |
| 628 | 24, |
| 629 | rx::rax, |
| 630 | true |
| 631 | ); |
| 632 | |
| 633 | // c -> [rsp+32] |
| 634 | emit_fetch_uN_dec( |
| 635 | e, |
| 636 | vm, |
| 637 | rx::rax, |
| 638 | 8 |
| 639 | ); |
| 640 | e.mov_mem_reg( |
| 641 | rx::rsp, |
| 642 | 32, |
| 643 | rx::rax, |
| 644 | true |
| 645 | ); |
| 646 | |
| 647 | // d -> [rsp+40] |
| 648 | emit_fetch_uN_dec( |
| 649 | e, |
| 650 | vm, |
| 651 | rx::rax, |
no test coverage detected