/*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ #include "types.h" #include "video.h" #include "debug.h" u8 *r8[] = {"al","cl","dl","bl","ah","ch","dh","bh"}; u8 *r16[] = {"ax","cx","dx","bx","sp","bp","si","di"}; u8 *r32[] = {"eax","ecx","edx","ebx","esp","ebp","esi","edi"}; u8 *rseg[] = {"ds","es","fs","gs","ss","cs","ip"}; /*******************************************************************************/ /* Efface un breakpoint sur une adresse */ void cleardebugreg(u8* address) { for(u8 i=0;i<4;i++) if (getdebugreg(i)==address) setdebugreg(i,0x0, DBG_CLEAR); } /*******************************************************************************/ /* Permet de manipuler dr0-dr7 pour mettre en place des breakpoints */ u8* getdebugreg(u8 number) { u8* address; if (number==0) asm("mov %%eax,%%dr0; movl %%eax,%[address]":[address] "=m" (address)::); else if (number==1) asm("mov %%eax,%%dr1; movl %%eax,%[address]":[address] "=m" (address)::); else if (number==2) asm("mov %%eax,%%dr2; movl %%eax,%[address]":[address] "=m" (address)::); else if (number==3) asm("mov %%eax,%%dr3; movl %%eax,%[address]":[address] "=m" (address)::); return address; } /*******************************************************************************/ /* Permet de manipuler dr0-dr7 pour mettre en place des breakpoints */ void setdebugreg(u8 number,u8 *address, u8 type) { u32 dr7=0; asm("movl %%dr7,%%eax; mov %%eax,%[dr7]":[dr7] "=m" (dr7)::); if (type==DBG_WRITE || type==DBG_READWRITE) dr7|=0b11<<8; if (type!=DBG_CLEAR) dr7|=0b11<<(number<<1); else dr7&=~(0b11<<(number<<1)); dr7&=~(0b11<<(16+(number<<2))); dr7|=type<<(16+(number<<2)); dr7&=~(0b11<<(16+((number<<2)+2))); asm("movl %[dr7],%%eax; mov %%eax,%%dr7"::[dr7] "m" (dr7):); if (number==0) asm("movl %[address],%%eax; mov %%eax,%%dr0"::[address] "m" (address):); else if (number==1) asm("movl %[address],%%eax; mov %%eax,%%dr1"::[address] "m" (address):); else if (number==2) asm("movl %[address],%%eax; mov %%eax,%%dr2"::[address] "m" (address):); else if (number==3) asm("movl %[address],%%eax; mov %%eax,%%dr3"::[address] "m" (address):); else return; } /*******************************************************************************/ /* Fonctions de déboguage */ u16 decodeModSM(bool show, u8 *a, u8 *op, u16 order, u32 Gsz, u32 Esz){ u32 len = 0; u32 reg = 0; u32 scale = 0; u8 *b = a; u8 *E, *G, *indx, *base, *disp = "\0"; u8 ebuf[32] = {0}; setG(); if(Esz){ switch(*b&0xc7){ case 0x00: E = "[bx+si]"; break; case 0x01: E = "[bx+di]"; break; case 0x02: E = "[bp+si]"; break; case 0x03: E = "[bp+di]"; break; case 0x04: E = "[si]"; break; case 0x05: E = "[di]"; break; case 0x06: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); E = ebuf; ++b; break; case 0x07: E = "[bx]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x44: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); E = ebuf; case 0x80: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x84: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); E = ebuf; ++b; break; case 0xc0: E = "al"; break; case 0xc1: E = "cl"; break; case 0xc2: E = "dl"; break; case 0xc3: E = "bl"; break; case 0xc4: E = "ah"; break; case 0xc5: E = "ch"; break; case 0xc6: E = "dh"; break; case 0xc7: E = "bh"; break; default: if (show) print("Invalid Mod R/M byte."); return; } } else{ switch(*b & 0xc7){ case 0x00: E = "[eax]"; break; case 0x01: E = "[ecx]"; break; case 0x02: E = "[edx]"; break; case 0x03: E = "[ebx]"; break; case 0x04: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s]", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s]", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); } E = ebuf; break; case 0x05: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); E = ebuf; b += 3; break; case 0x06: E = "[esi]"; break; case 0x07: E = "[edi]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); E = ebuf; case 0x44: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); E = ebuf; break; case 0x80: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); E = ebuf; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x84: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); b += 3; E = ebuf; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0xc0: E = Esz == 1 ? "ax": "eax"; break; case 0xc1: E = Esz == 1 ? "cx": "ecx"; break; case 0xc2: E = Esz == 1 ? "dx": "edx"; break; case 0xc3: E = Esz == 1 ? "bx": "ebx"; break; case 0xc4: E = Esz == 1 ? "sp": "esp"; break; case 0xc5: E = Esz == 1 ? "bp": "ebp"; break; case 0xc6: E = Esz == 1 ? "si": "esi"; break; case 0xc7: E = Esz == 1 ? "di": "edi"; break; default: if (show) print("Invalid Mod R/M byte."); return; } } if(order){ snprintf(op, opBufSz, "%s", E); len = strlen(op); if(Gsz){ snprintf(op+len, opBufSz-len, ", %s", G); } } else{ snprintf(op, opBufSz, "%s, ", G); len = strlen(op); snprintf(op+len, opBufSz-len, "%s", E); } return b-a; } u32 decodeModSM_float(bool show, u8 *a, u8 *op, u32 order, u32 Gsz, u32 Esz){ u32 len = 0; u32 reg = 0; u32 scale = 0; u8 *b = a; u8 *E, *G, *indx, *base, *disp = "\0"; u8 ebuf[32] = {0}; setG(); if(Esz){ switch(*b&0xc7){ case 0x00: E = "[bx+si]"; break; case 0x01: E = "[bx+di]"; break; case 0x02: E = "[bp+si]"; break; case 0x03: E = "[bp+di]"; break; case 0x04: E = "[si]"; break; case 0x05: E = "[di]"; break; case 0x06: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); E = ebuf; ++b; break; case 0x07: E = "[bx]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x44: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); E = ebuf; case 0x80: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x84: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0xc0: E = "st(0)"; break; case 0xc1: E = "st(1)"; break; case 0xc2: E = "st(2)"; break; case 0xc3: E = "st(3)"; break; case 0xc4: E = "st(4)"; break; case 0xc5: E = "st(5)"; break; case 0xc6: E = "st(6)"; break; case 0xc7: E = "st(7)"; break; default: if (show) print("Invalid Mod R/M byte."); return; } } else{ switch(*b & 0xc7){ case 0x00: E = "[eax]"; break; case 0x01: E = "[ecx]"; break; case 0x02: E = "[edx]"; break; case 0x03: E = "[ebx]"; break; case 0x04: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s]", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s]", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); } E = ebuf; break; case 0x05: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); E = ebuf; b += 3; break; case 0x06: E = "[esi]"; break; case 0x07: E = "[edi]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); E = ebuf; case 0x44: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); E = ebuf; break; case 0x80: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); E = ebuf; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x84: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); b += 3; E = ebuf; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0xc0: E = "st(0)"; break; case 0xc1: E = "st(1)"; break; case 0xc2: E = "st(2)"; break; case 0xc3: E = "st(3)"; break; case 0xc4: E = "st(4)"; break; case 0xc5: E = "st(5)"; break; case 0xc6: E = "st(6)"; break; case 0xc7: E = "st(7)"; break; default: if (show) print("Invalid Mod R/M byte."); return; } } if(order){ snprintf(op, opBufSz, "%s", E); len = strlen(op); if(Gsz){ snprintf(op+len, opBufSz-len, ", %s", G); } } else{ snprintf(op, opBufSz, "%s, ", G); len = strlen(op); snprintf(op+len, opBufSz-len, "%s", E); } return b-a; } u32 decodeModSM_memonly(bool show, u8 *a, u8 *op, u32 order, u32 Gsz, u32 Esz){ u32 len = 0; u32 reg = 0; u32 scale = 0; u8 *b = a; u8 *E, *G, *indx, *base, *disp = "\0"; u8 ebuf[32] = {0}; setG(); if(Esz){ switch(*b&0xc7){ case 0x00: E = "[bx+si]"; break; case 0x01: E = "[bx+di]"; break; case 0x02: E = "[bp+si]"; break; case 0x03: E = "[bp+di]"; break; case 0x04: E = "[si]"; break; case 0x05: E = "[di]"; break; case 0x06: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); E = ebuf; ++b; break; case 0x07: E = "[bx]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); E = ebuf; break; case 0x44: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); E = ebuf; case 0x80: snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x84: snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u16 *)++b); E = ebuf; ++b; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u16 *)++b); E = ebuf; ++b; break; default: if (show) print("Invalid Mod R/M byte."); return; } } else{ switch(*b&0xc7){ case 0x00: E = "[eax]"; break; case 0x01: E = "[ecx]"; break; case 0x02: E = "[edx]"; break; case 0x03: E = "[ebx]"; break; case 0x04: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s]", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s]", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); } E = ebuf; break; case 0x05: snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); E = ebuf; b += 3; break; case 0x06: E = "[esi]"; break; case 0x07: E = "[edi]"; break; case 0x40: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); E = ebuf; break; case 0x41: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); E = ebuf; break; case 0x42: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); E = ebuf; break; case 0x43: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); E = ebuf; case 0x44: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); E = ebuf; break; case 0x45: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); E = ebuf; break; case 0x46: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); E = ebuf; break; case 0x47: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); E = ebuf; break; case 0x80: snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x81: snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); E = ebuf; break; case 0x82: snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x83: snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x84: ++b; decodeSIB(); if(!indx){ snprintf(ebuf, sizeof(ebuf), "[%s", base); } else if(!base){ if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s", indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); } } else if(!scale){ snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); } else{ snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); } len = strlen(ebuf); snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); b += 3; E = ebuf; break; case 0x85: snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x86: snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; case 0x87: snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); E = ebuf; b += 3; break; default: if (show) print("Invalid Mod R/M byte."); return; } } if(order){ snprintf(op, opBufSz, "%s", E); len = strlen(op); if(Gsz){ snprintf(op+len, opBufSz-len, ", %s", G); } } else{ snprintf(op, opBufSz, "%s, ", G); len = strlen(op); snprintf(op+len, opBufSz-len, "%s", E); } return b-a; } /*******************************************************************************/ /* Décode une adresse mémoire au format intel */ u32 disasm(u8 *a, u8 *string, bool show){ u8 *f_entry; u16 entry; u8 *b = a; u32 len = 0; u32 flip_addr_sz = 0; u32 flip_imm_sz = 0; u32 EG = 1; u32 B = 1; u8 *s, *prefix, *seg_oride = "\0"; u8 op1[opBufSz] = {0}; if(*b == 0xf3){ prefix = "rep"; ++b; } else if(*b == 0xf2){ prefix = "repnz"; ++b; } else if(*b == 0xf0){ prefix = "lock"; ++b; } if(*b == 0x67){ flip_addr_sz = 1; ++b; } if (*b == 0x66){ flip_imm_sz = 1; ++b; } switch(*b){ case 0x2e: seg_oride = "cs"; ++b; break; case 0x36: seg_oride = "ss"; ++b; break; case 0x3e: seg_oride = "ds"; ++b; break; case 0x26: seg_oride = "es"; ++b; break; case 0x64: seg_oride = "fs"; ++b; break; case 0x65: seg_oride = "gs"; ++b; } if(*b == 0x0f){ if (show) print("Extended opcodes not implimented.\r\n"); return; } else{ switch(*b){ case 0x00: s = "add"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x01: s = "add"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x02: s = "add"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x03: s = "add"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x04: s = "add"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x05: s = "add"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x06: s = "push es"; break; case 0x07: s = "pop es"; break; case 0x08: s = "or"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x09: s = "or"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x0a: s = "or"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x0b: s = "or"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x0c: s = "or"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x0d: s = "or"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x0e: s = "push cs"; break; case 0x10: s = "adc"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x11: s = "adc"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x12: s = "adc"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x13: s = "adc"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x14: s = "adc"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x15: s = "adc"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x16: s = "push ss"; break; case 0x17: s = "pop ss"; break; case 0x18: s = "sbb"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x19: s = "sbb"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x1a: s = "sbb"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x1b: s = "sbb"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x1c: s = "sbb"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x1d: s = "sbb"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x1e: s = "push ds"; break; case 0x1f: s = "pop ds"; break; case 0x20: s = "and"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x21: s = "and"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x22: s = "and"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x23: s = "and"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x24: s = "and"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x25: s = "and"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x27: s = "daa"; break; case 0x28: s = "sub"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x29: s = "sub"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x2a: s = "sub"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x2b: s = "sub"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x2c: s = "sub"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x2d: s = "sub"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x2f: s = "das"; break; case 0x30: s = "xor"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x31: s = "xor"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x32: s = "xor"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x33: s = "xor"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x34: s = "xor"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x35: s = "xor"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x37: s = "aaa"; break; case 0x38: s = "cmp"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x39: s = "cmp"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x3a: s = "cmp"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x3b: s = "cmp"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x3c: s = "cmp"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0x3d: s = "cmp"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0x3f: s = "aas"; break; case 0x40: s = flip_imm_sz ? "inc ax": "inc eax"; break; case 0x41: s = flip_imm_sz ? "inc cx": "inc ecx"; break; case 0x42: s = flip_imm_sz ? "inc dx": "inc edx"; break; case 0x43: s = flip_imm_sz ? "inc bx": "inc ebx"; break; case 0x44: s = flip_imm_sz ? "inc sp": "inc esp"; break; case 0x45: s = flip_imm_sz ? "inc bp": "inc ebp"; break; case 0x46: s = flip_imm_sz ? "inc si": "inc esi"; break; case 0x47: s = flip_imm_sz ? "inc di": "inc edi"; break; case 0x48: s = flip_imm_sz ? "dec ax": "dec eax"; break; case 0x49: s = flip_imm_sz ? "dec cx": "dec ecx"; break; case 0x4a: s = flip_imm_sz ? "dec dx": "dec edx"; break; case 0x4b: s = flip_imm_sz ? "dec bx": "dec ebx"; break; case 0x4c: s = flip_imm_sz ? "dec sp": "dec esp"; break; case 0x4d: s = flip_imm_sz ? "dec bp": "dec ebp"; break; case 0x4e: s = flip_imm_sz ? "dec si": "dec esi"; break; case 0x4f: s = flip_imm_sz ? "dec di": "dec edi"; break; case 0x50: s = flip_imm_sz ? "push ax": "push eax"; break; case 0x51: s = flip_imm_sz ? "push cx": "push ecx"; break; case 0x52: s = flip_imm_sz ? "push dx": "push edx"; break; case 0x53: s = flip_imm_sz ? "push bx": "push ebx"; break; case 0x54: s = flip_imm_sz ? "push sp": "push esp"; break; case 0x55: s = flip_imm_sz ? "push bp": "push ebp"; break; case 0x56: s = flip_imm_sz ? "push si": "push esi"; break; case 0x57: s = flip_imm_sz ? "push di": "push edi"; break; case 0x58: s = flip_imm_sz ? "pop ax": "pop eax"; break; case 0x59: s = flip_imm_sz ? "pop cx": "pop ecx"; break; case 0x5a: s = flip_imm_sz ? "pop dx": "pop edx"; break; case 0x5b: s = flip_imm_sz ? "pop bx": "pop ebx"; break; case 0x5c: s = flip_imm_sz ? "pop sp": "pop esp"; break; case 0x5d: s = flip_imm_sz ? "pop bp": "pop ebp"; break; case 0x5e: s = flip_imm_sz ? "pop si": "pop esi"; break; case 0x5f: s = flip_imm_sz ? "pop di": "pop edi"; break; case 0x60: s = flip_imm_sz ? "pushaw": "pusha"; break; case 0x61: s = flip_imm_sz ? "popaw": "popa"; break; case 0x63: s = "arpl"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x68: s = "push"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "%x", *(u32 *)++b); b += 3; } break; case 0x69: s = "imul"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); len = strlen(op1); if(flip_imm_sz){ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); ++b; } else{ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); b += 3; } break; case 0x6a: s = "push"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)*b); case 0x6b: s = "imul"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0x6c: s = flip_addr_sz ? "ins bytes ptr es:[di], dx": "insb"; break; case 0x6d: if(flip_addr_sz){ s = flip_imm_sz ? "ins word ptr es:[di], dx": "ins dword ptr es:[di], dx"; } else{ s = flip_imm_sz ? "insw": "insd"; } break; case 0x6e: s = flip_addr_sz ? "outs dx, byte ptr [si]": "outsb"; break; case 0x6f: if(flip_addr_sz){ s = flip_imm_sz ? "outs dx, word ptr [si]": "outs dx, dword ptr [si]"; } else{ s = flip_imm_sz ? "outsw": "outsd"; } break; case 0x70: s = "jo"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x71: s = "jno"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x72: s = "jb"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x73: s = "jnb"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x74: s = "jz"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x75: s = "jnz"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x76: s = "jbe"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x77: s = "ja"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x78: s = "js"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x79: s = "jns"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x7a: s = "jp"; ++b; break; case 0x7b: s = "jnp"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x7c: s = "jl"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x7d: s = "jnl"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x7e: s = "jle"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x7f: s = "jnle"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0x80: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "add"; break; case 1: s = "or"; break; case 2: s = "adc"; break; case 3: s = "sbb"; break; case 4: s = "and"; break; case 5: s = "sub"; break; case 6: s = "xor"; break; case 7: s = "cmp"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0x81: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "add"; break; case 1: s = "or"; break; case 2: s = "adc"; break; case 3: s = "sbb"; break; case 4: s = "and"; break; case 5: s = "sub"; break; case 6: s = "xor"; break; case 7: s = "cmp"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); if(flip_imm_sz){ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); ++b; } else{ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); b += 3; } break; case 0x82: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "add"; break; case 1: s = "or"; break; case 2: s = "adc"; break; case 3: s = "sbb"; break; case 4: s = "and"; break; case 5: s = "sub"; break; case 6: s = "xor"; break; case 7: s = "cmp"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0x83: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "add"; break; case 1: s = "or"; break; case 2: s = "adc"; break; case 3: s = "sbb"; break; case 4: s = "and"; break; case 5: s = "sub"; break; case 6: s = "xor"; break; case 7: s = "cmp"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0x84: s = "test"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x85: s = "test"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x86: s = "xchg"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x87: s = "xchg"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x88: s = "mov"; b += decodeModSM(show, ++b, op1, 1, 1, flip_addr_sz); break; case 0x89: s = "mov"; b += decodeModSM(show, ++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x8a: s = "mov"; b += decodeModSM(show, ++b, op1, 0, 1, flip_addr_sz); break; case 0x8b: s = "mov"; b += decodeModSM(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x8c: s = "mov"; b += decodeModSM(show, ++b, op1, 1, 4, flip_addr_sz); break; case 0x8d: s = "lea"; b += decodeModSM_memonly(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0x8e: s = "mov"; b += decodeModSM(show, ++b, op1, 0, 4, flip_addr_sz); break; case 0x8f: s = "pop"; b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); break; case 0x90: s = flip_imm_sz ? "xchg ax, ax": "nop"; break; case 0x91: s = flip_imm_sz ? "xchg ax, cx": "xchg eax, ecx"; break; case 0x92: s = flip_imm_sz ? "xchg ax, dx": "xchg eax, edx"; break; case 0x93: s = flip_imm_sz ? "xchg ax, bx": "xchg eax, ebx"; break; case 0x94: s = flip_imm_sz ? "xchg ax, sp": "xchg eax, esp"; break; case 0x95: s = flip_imm_sz ? "xchg ax, bp": "xchg eax, ebp"; break; case 0x96: s = flip_imm_sz ? "xchg ax, si": "xchg eax, esi"; break; case 0x97: s = flip_imm_sz ? "xchg ax, di": "xchg eax, edi"; break; case 0x98: s = flip_imm_sz ? "cbw": "cwde"; break; case 0x99: s = flip_imm_sz ? "cwd": "cdq"; break; case 0x9a: s = "call"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+2), *(u16 *)++b); b += 3; } else{ snprintf(op1, sizeof(op1), "far ptr %x:%x", *(u16 *)(b+4), *(u32 *)++b); b += 5; } break; case 0x9b: s = "wait"; break; case 0x9c: s = flip_imm_sz ? "pushfw": "pushf"; break; case 0x9d: s = flip_imm_sz ? "popfw": "popf"; break; case 0x9e: s = "sahf"; break; case 0x9f: s = "lahf"; break; case 0xa0: s = "mov"; snprintf(op1, sizeof(op1), "al, ds:%x", *(u32 *)++b); b += 3; break; case 0xa1: s = "mov"; snprintf(op1, sizeof(op1), flip_imm_sz ? "ax, ds:%x": "eax, ds:%x", *(u32 *)++b); b += 3; break; case 0xa2: s = "mov"; snprintf(op1, sizeof(op1), "ds:%x, al", *(u32 *)++b); b += 3; break; case 0xa3: s = "mov"; snprintf(op1, sizeof(op1), flip_imm_sz ? "ds:%x, ax": "ds:%x, eax", *(u32 *)++b); b += 3; break; case 0xa4: s = flip_addr_sz ? "movs byte ptr es:[di], byte ptr [si]": "movsb"; break; case 0xa5: if(flip_addr_sz){ s = flip_imm_sz ? "movs word ptr es:[di], word ptr [si]": "movs dword ptr es:[di], dword ptr [si]"; } else{ s = flip_imm_sz ? "movsw": "movsd"; } break; case 0xa6: s = flip_addr_sz ? "cmps byte ptr [si], byte ptr es:[di]": "cmpsb"; break; case 0xa7: if(flip_addr_sz){ s = flip_imm_sz ? "movs word ptr [si], word ptr es:[di]": "movs dword ptr [si], dword ptr es:[di]"; } else{ s = flip_imm_sz ? "cmpsw": "cmpsd"; } break; case 0xa8: s = "test"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0xa9: s = "test"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); b += 3; } break; case 0xaa: s = flip_addr_sz ? "stos byte ptr es:[di]": "stosb"; break; case 0xab: if(flip_addr_sz){ s = flip_imm_sz ? "stos word ptr es:[di]": "stos dword ptr es:[di]"; } else{ s = flip_imm_sz ? "stosw": "stosd"; } break; case 0xac: s = flip_addr_sz ? "lods byte ptr [si]": "lodsb"; break; case 0xad: if(flip_addr_sz){ s = flip_imm_sz ? "lods word ptr [si]": "lods dword ptr [si]"; } else{ s = flip_imm_sz ? "lodsw": "lodsd"; } break; case 0xae: s = flip_addr_sz ? "scas byte ptr es:[di]": "scasb"; break; case 0xaf: if(flip_addr_sz){ s = flip_imm_sz ? "scas word ptr es:[di]": "scas dword ptr es:[di]"; } else{ s = flip_imm_sz ? "scasw": "scasd"; } break; case 0xb0: s = "mov"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0xb1: s = "mov"; ++b; snprintf(op1, sizeof(op1), "cl, %x", (void *)*b); break; case 0xb2: s = "mov"; ++b; snprintf(op1, sizeof(op1), "dl, %x", (void *)*b); break; case 0xb3: s = "mov"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0xb4: s = "mov"; ++b; snprintf(op1, sizeof(op1), "ah, %x", (void *)*b); break; case 0xb5: s = "mov"; ++b; snprintf(op1, sizeof(op1), "ch, %x", (void *)*b); break; case 0xb6: s = "mov"; ++b; snprintf(op1, sizeof(op1), "dh, %x", (void *)*b); break; case 0xb7: s = "mov"; ++b; snprintf(op1, sizeof(op1), "bh, %x", (void *)*b); break; case 0xb8: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); b += 3; } break; case 0xb9: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "cx, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "ecx, %x", *(u32 *)++b); b += 3; } break; case 0xba: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "dx, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "edx, %x", *(u32 *)++b); b += 3; } break; case 0xbb: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "bx, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "ebx, %x", *(u32 *)++b); b += 3; } break; case 0xbc: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "sp, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "esp, %x", *(u32 *)++b); b += 3; } break; case 0xbd: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "bp, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "ebp, %x", *(u32 *)++b); b += 3; } break; case 0xbe: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "si, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "esi, %x", *(u32 *)++b); b += 3; } break; case 0xbf: s = "mov"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "di, %x", *(u16 *)++b); ++b; } else{ snprintf(op1, sizeof(op1), "edi, %x", *(u32 *)++b); b += 3; } break; case 0xc0: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0xc1: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0xc2: s = "retn"; snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); ++b; break; case 0xc3: s = "retn"; break; case 0xc4: s = "les"; b += decodeModSM_memonly(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0xc5: s = "lds"; b += decodeModSM_memonly(show, ++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); break; case 0xc6: s = "mov"; b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); break; case 0xc7: s = "mov"; b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); len = strlen(op1); if(flip_imm_sz){ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); ++b; } else{ snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); b += 3; } break; case 0xc8: s = "enter"; snprintf(op1, sizeof(op1), "%x, %x", *(u16 *)(b+1), *(u8 *)(b+3)); b += 3; break; case 0xc9: s = "leave"; break; case 0xca: s = "retf"; snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); ++b; break; case 0xcb: s = "retf"; break; case 0xcc: s = "int 3"; break; case 0xcd: s = "int"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)*b); break; case 0xce: s = "into"; break; case 0xcf: s = "iret"; break; case 0xd0: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", 1"); break; case 0xd1: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", 1"); break; case 0xd2: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", cl"); break; case 0xd3: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "rol"; break; case 1: s = "ror"; break; case 2: s = "rcl"; break; case 3: s = "rcr"; break; case 4: s = "shl"; break; case 5: s = "shr"; break; case 6: s = "shl"; break; case 7: s = "sar"; break; default: if (show) print("Invalid Mod R/M byte."); return; } len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, ", cl"); break; case 0xd4: s = "aam"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)*b); break; case 0xd5: s = "aad"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)*b); break; case 0xd6: s = "salc"; break; case 0xd7: s = "xlat"; break; case 0xd8: if(*++b == 0xd1){ s = "fcom st(1)"; } else if(*b == 0xd9){ s = "fcomp st(1)"; } else{ switch((*b&0x38)>>3){ case 0: s = "fadd"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 1: s = "fmul"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 2: s = "fcom"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 3: s = "fcomp"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 4: s = "fsub"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 5: s = "fsubr"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 6: s = "fdiv"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; case 7: s = "fdivr"; b += decodeModSM_float(show, b, op1, 1, 0, flip_addr_sz); break; default: if (show) print("Invalid Mod R/M byte."); return; } } break; case 0xe0: s = "loopnz"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0xe1: s = "loopz"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0xe2: s = "loop"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0xe3: s = "jcxz"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0xe4: s = "in"; ++b; snprintf(op1, sizeof(op1), "al, %x", (void *)*b); break; case 0xe5: s = "in"; ++b; snprintf(op1, sizeof(op1), flip_imm_sz ? "ax, %x": "eax, %x", (void *)*b); break; case 0xe6: s = "out"; ++b; snprintf(op1, sizeof(op1), "%x, al", (void *)*b); break; case 0xe7: s = "in"; ++b; snprintf(op1, sizeof(op1), flip_imm_sz ? "%x, ax": "%x, eax", (void *)*b); break; case 0xe8: s = "call"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "%x", entry+(u32)b-(u32)f_entry+*(u16 *)++b+3); b += 2; } else{ snprintf(op1, sizeof(op1), "%x",(void *)entry+(u32)b-(u32)f_entry+*(u32 *)++b+4); b += 3; } break; case 0xe9: s = "jmp"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "near ptr %x", entry+(u32)b-(u32)f_entry+*(u16 *)++b+3); ++b; } else{ snprintf(op1, sizeof(op1), "near ptr %x", (void *)entry+(u32)b-(u32)f_entry+*(u32 *)++b+4); b += 3; } break; case 0xea: s = "jmp"; if(flip_imm_sz){ snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+2), *(u16 *)++b); b += 3; } else{ snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+4), *(u32 *)++b); b += 5; } break; case 0xeb: s = "jmp"; ++b; snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); break; case 0xec: s = "in al, dx"; break; case 0xed: s = flip_imm_sz ? "in ax, dx": "in eax, dx"; break; case 0xee: s= "out dx, al"; break; case 0xef: s = flip_imm_sz ? "out dx, ax": "out dx, eax"; break; case 0xf1: s = "int 1"; break; case 0xf4: s = "hlt"; break; case 0xf5: s = "cmc"; break; case 0xf6: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "test"; len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, "%x", *(u8 *)++b); break; case 1: s = "test"; len = strlen(op1); snprintf(op1+len, sizeof(op1)-len, "%x", *(u8 *)++b); break; case 2: s = "not"; break; case 3: s = "neg"; break; case 4: s = "mul ax, al, "; break; case 5: s = "imul ax, al, "; break; case 6: s = "div al, ah, ax, "; break; case 7: s = "idiv al, ah, ax, "; break; default: if (show) print("Invalid Mod R/M byte."); return; } break; case 0xf7: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); switch((*b&0x38)/8){ case 0: s = "test"; len = strlen(op1); if(flip_imm_sz){ snprintf(op1+len, sizeof(op1)-len, "%x", *(u16 *)++b); ++b; } else{ snprintf(op1+len, sizeof(op1)-len, "%x", *(u32 *)++b); b += 3; } break; case 1: s = "test"; len = strlen(op1); if(flip_imm_sz){ snprintf(op1+len, sizeof(op1)-len, "%x", *(u16 *)++b); ++b; } else{ snprintf(op1+len, sizeof(op1)-len, "%x", *(u32 *)++b); b += 3; } break; case 2: s = "not"; break; case 3: s = "neg"; break; case 4: s = "mul rdx, rax, "; break; case 5: s = "imul rdx, rax, "; break; case 6: s = "div rdx, rax, "; break; case 7: s = "idiv rdx, rax, "; break; default: if (show) print("Invalid Mod R/M byte."); return; } break; case 0xf8: s = "clc"; break; case 0xf9: s = "stc"; break; case 0xfa: s = "cli"; break; case 0xfb: s = "sti"; break; case 0xfc: s = "cld"; break; case 0xfd: s = "std"; break; case 0xfe: b += decodeModSM(show, ++b, op1, 1, 0, flip_addr_sz); if(!((*b&0x38)/8)){ s = "inc"; } else if((*b&0x38)/8 == 1){ s = "dec"; } else{ if (show) print("Invalid Mod R/M byte."); return; } break; case 0xff: switch((*++b&0x38)>>3){ case 0: s = "inc"; b += decodeModSM(show, b, op1, 1, 0, flip_addr_sz); break; case 1: s = "dec"; b += decodeModSM(show, b, op1, 1, 0, flip_addr_sz); break; case 2: s = "call"; b += decodeModSM(show, b, op1, 1, 0, flip_addr_sz); break; case 3: s = "callf"; b += decodeModSM_memonly(show, b, op1, 1, 0, flip_addr_sz); break; case 4: s = "jmp"; b += decodeModSM(show, b, op1, 1, 0, flip_addr_sz); break; case 5: s = "jmpf"; b += decodeModSM_memonly(show, b, op1, 1, 0, flip_addr_sz); break; case 6: s = "push"; b += decodeModSM(show, b, op1, 1, 0, flip_addr_sz); break; default: if (show) print("Invalid Mod R/M byte."); return; } break; default: if (show) print("invalid opcode\r\n"); return; } strcompressdelimiter(s,' '); if (show) printf(" %X: %s %s\r\n", (u32)a, s, op1); else if (string!=NULL) sprintf(string, " %X: %s %s\r\n", (u32)a, s, op1); ++b; } return b-a; }