* Calculate the size of the instruction from the modRM byte. */
| 712 | * Calculate the size of the instruction from the modRM byte. |
| 713 | */ |
| 714 | int getModRMSize(const uint8_t *bytes, unsigned size) |
| 715 | { |
| 716 | if (1 > size) |
| 717 | return -1; |
| 718 | uint8_t modRM = bytes[0]; |
| 719 | uint8_t mod = (modRM & 0xc0) >> 6; |
| 720 | uint8_t rm = modRM & 0x7; |
| 721 | switch (mod) |
| 722 | { |
| 723 | case 0x03: |
| 724 | return 1; |
| 725 | case 0x00: |
| 726 | switch (rm) |
| 727 | { |
| 728 | case 0x04: |
| 729 | break; |
| 730 | case 0x05: |
| 731 | goto displ32; |
| 732 | default: |
| 733 | return 1; |
| 734 | } |
| 735 | break; |
| 736 | case 0x01: |
| 737 | switch (rm) |
| 738 | { |
| 739 | case 0x04: |
| 740 | break; |
| 741 | default: |
| 742 | if (1 + sizeof(int8_t) > size) |
| 743 | return -1; |
| 744 | return 1 + sizeof(int8_t); |
| 745 | } |
| 746 | break; |
| 747 | case 0x02: |
| 748 | switch (rm) |
| 749 | { |
| 750 | case 0x04: |
| 751 | break; |
| 752 | default: |
| 753 | displ32: |
| 754 | if (1 + sizeof(int32_t) > size) |
| 755 | return -1; |
| 756 | return 1 + sizeof(int32_t); |
| 757 | } |
| 758 | break; |
| 759 | } |
| 760 | if (2 > size) |
| 761 | return -1; |
| 762 | uint8_t sib = bytes[1]; |
| 763 | uint8_t base = sib & 0x3; |
| 764 | switch (mod) |
| 765 | { |
| 766 | case 0x00: |
| 767 | switch (base) |
| 768 | { |
| 769 | case 0x05: |
| 770 | goto displ32_sib; |
| 771 | default: |
no outgoing calls
no test coverage detected