3471 lines
62 KiB
C
3471 lines
62 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 |= 0x3 << 8;
|
|
if (type != DBG_CLEAR)
|
|
dr7 |= 0x3 << (number << 1);
|
|
else
|
|
dr7 &= ~(0x3 << (number << 1));
|
|
dr7 &= ~(0x3 << (16 + (number << 2)));
|
|
dr7 |= type << (16 + (number << 2));
|
|
dr7 &= ~(0x3 << (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;
|
|
}
|