GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — length-disassembler/ldisasm.cpp at master · gh-nomad/length-disassembler
This repository was archived by the owner on Apr 6, 2020. It is now read-only.
Expand file tree/ Copy pathldisasm.cppMore file actions 97 lines (84 loc) · 3.59 KB / Copy pathldisasm.cppFile metadata and controls97 lines (84 loc) · 3.59 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 #include "ldisasm.h" #define R (*b >> 4) // Four high-order bits of an opcode to index a row of the opcode table #define C (*b & 0xF) // Four low-order bits to index a column of the table static const uint8_t prefixes[] = { 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, 0x66, 0x67 }; static const uint8_t op1modrm[] = { 0x62, 0x63, 0x69, 0x6B, 0xC0, 0xC1, 0xC4, 0xC5, 0xC6, 0xC7, 0xD0, 0xD1, 0xD2, 0xD3, 0xF6, 0xF7, 0xFE, 0xFF }; static const uint8_t op1imm8[] = { 0x6A, 0x6B, 0x80, 0x82, 0x83, 0xA8, 0xC0, 0xC1, 0xC6, 0xCD, 0xD4, 0xD5, 0xEB }; static const uint8_t op1imm32[] = { 0x68, 0x69, 0x81, 0xA9, 0xC7, 0xE8, 0xE9 }; static const uint8_t op2modrm[] = { 0x0D, 0xA3, 0xA4, 0xA5, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF }; bool findByte(const uint8_t* arr, const size_t N, const uint8_t x) { for (size_t i = 0; i < N; i++) { if (arr[i] == x) { return true; } }; return false; } void parseModRM(uint8_t** b, const bool addressPrefix) { uint8_t modrm = *++*b; if (!addressPrefix || (addressPrefix && **b >= 0x40)) { bool hasSIB = false; //Check for SIB byte if (**b < 0xC0 && (**b & 0b111) == 0b100 && !addressPrefix) hasSIB = true, (*b)++; if (modrm >= 0x40 && modrm <= 0x7F) // disp8 (ModR/M) (*b)++; else if ((modrm <= 0x3F && (modrm & 0b111) == 0b101) || (modrm >= 0x80 && modrm <= 0xBF)) //disp16,32 (ModR/M) *b += (addressPrefix) ? 2 : 4; else if (hasSIB && (**b & 0b111) == 0b101) //disp8,32 (SIB) *b += (modrm & 0b01000000) ? 1 : 4; } else if (addressPrefix && modrm == 0x26) *b += 2; }; size_t ldisasm(const void* const address, const bool x86_64_mode) { size_t offset = 0; bool operandPrefix = false, addressPrefix = false, rexW = false; uint8_t* b = (uint8_t*)(address); //Parse legacy prefixes & REX prefixes for (int i = 0; i < 14 && findByte(prefixes, sizeof(prefixes), *b) || ((x86_64_mode) ? (R == 4) : false); i++, b++) { if (*b == 0x66) operandPrefix = true; else if (*b == 0x67) addressPrefix = true; else if (R == 4 && C >= 8) rexW = true; } //Parse opcode(s) if (*b == 0x0F) // 2,3 bytes { b++; if (*b == 0x38 || *b == 0x3A) // 3 bytes { if (*b++ == 0x3A) offset++; parseModRM(&b, addressPrefix); } else // 2 bytes { if (R == 8) //disp32 offset += 4; else if ((R == 7 && C < 4) || *b == 0xA4 || *b == 0xC2 || (*b > 0xC3 && *b <= 0xC6) || *b == 0xBA || *b == 0xAC) //imm8 offset++; //Check for ModR/M, SIB and displacement if (findByte(op2modrm, sizeof(op2modrm), *b) || (R != 3 && R > 0 && R < 7) || *b >= 0xD0 || (R == 7 && C != 7) || R == 9 || R == 0xB || (R == 0xC && C < 8) || (R == 0 && C < 4)) parseModRM(&b, addressPrefix); } } else // 1 byte { //Check for immediate field if ((R == 0xE && C < 8) || (R == 0xB && C < 8) || R == 7 || (R < 4 && (C == 4 || C == 0xC)) || (*b == 0xF6 && !(*(b + 1) & 48)) || findByte(op1imm8, sizeof(op1imm8), *b)) //imm8 offset++; else if (*b == 0xC2 || *b == 0xCA) //imm16 offset += 2; else if (*b == 0xC8) //imm16 + imm8 offset += 3; else if ((R < 4 && (C == 5 || C == 0xD)) || (R == 0xB && C >= 8) || (*b == 0xF7 && !(*(b + 1) & 48)) || findByte(op1imm32, sizeof(op1imm32), *b)) //imm32,16 offset += (rexW) ? 8 : (operandPrefix ? 2 : 4); else if (R == 0xA && C < 4) offset += (rexW) ? 8 : (addressPrefix ? 2 : 4); else if (*b == 0xEA || *b == 0x9A) //imm32,48 offset += operandPrefix ? 4 : 6; //Check for ModR/M, SIB and displacement if (findByte(op1modrm, sizeof(op1modrm), *b) || (R < 4 && (C < 4 || (C >= 8 && C < 0xC))) || R == 8 || (R == 0xD && C >= 8)) parseModRM(&b, addressPrefix); } return (size_t)((ptrdiff_t)(++b + offset) - (ptrdiff_t)(address)); } |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |