* Get the index of any pcrel intermediate if it exists, else 0. */
| 619 | * Get the index of any pcrel intermediate if it exists, else 0. |
| 620 | */ |
| 621 | unsigned getInstrPCRelativeIndex(const uint8_t *bytes, unsigned size) |
| 622 | { |
| 623 | uint8_t rex = 0; |
| 624 | bool addr32 = false; |
| 625 | int i = decodePrefix(bytes, size, rex, addr32); |
| 626 | if (i < 0) |
| 627 | return false; |
| 628 | Encoding encoding = ENCODING_SINGLE_BYTE; |
| 629 | uint8_t opcode; |
| 630 | i = decodeOpcode(bytes, size, i, encoding, opcode); |
| 631 | if (i < 0) |
| 632 | return false; |
| 633 | |
| 634 | // Special handling of PC-relative JMPs and CALLs: |
| 635 | switch (encoding) |
| 636 | { |
| 637 | case ENCODING_SINGLE_BYTE: |
| 638 | switch (size - i) |
| 639 | { |
| 640 | case 1: |
| 641 | switch (opcode) |
| 642 | { |
| 643 | case 0xE3: // JRCXZ |
| 644 | case 0xEB: // JMP pcrel8 |
| 645 | case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: |
| 646 | case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: |
| 647 | case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: |
| 648 | case 0x7F: // Jcc pcrel8 |
| 649 | return i; |
| 650 | default: |
| 651 | break; |
| 652 | } |
| 653 | break; |
| 654 | case 4: |
| 655 | switch (opcode) |
| 656 | { |
| 657 | case 0xE8: // CALL pcrel32 |
| 658 | case 0xE9: // JMP pcrel32 |
| 659 | return i; |
| 660 | default: |
| 661 | break; |
| 662 | } |
| 663 | break; |
| 664 | } |
| 665 | break; |
| 666 | case ENCODING_TWO_BYTES_0F: |
| 667 | switch (size - i) |
| 668 | { |
| 669 | case 4: |
| 670 | switch (opcode) |
| 671 | { |
| 672 | case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: |
| 673 | case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: |
| 674 | case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: |
| 675 | case 0x8F: // Jcc pcrel32 |
| 676 | return i; |
| 677 | default: |
| 678 | break; |
no test coverage detected