2620 lines
87 KiB
C
2620 lines
87 KiB
C
/*******************************************************************************/
|
|
/* 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 %%dr0,%%eax; mov %%eax,%[address]":[address] "=m" (address)::);
|
|
else if (number==1) asm("mov %%dr1,%%eax; movl %%eax,%[address]":[address] "=m" (address)::);
|
|
else if (number==2) asm("mov %%dr2,%%eax; movl %%eax,%[address]":[address] "=m" (address)::);
|
|
else if (number==3) asm("mov %%dr0,%%eax; 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 1000;
|
|
}
|
|
} 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 1000;
|
|
}
|
|
}
|
|
|
|
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 1000;
|
|
}
|
|
} 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 1000;
|
|
}
|
|
}
|
|
|
|
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 1000;
|
|
}
|
|
} 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 1000;
|
|
}
|
|
}
|
|
|
|
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 1000;
|
|
|
|
} 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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
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 1000;
|
|
}
|
|
break;
|
|
default:
|
|
if (show) print("invalid opcode\r\n");
|
|
return 1000;
|
|
}
|
|
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;
|
|
}
|
|
|