📄 disassemble.c
字号:
Instruction->Opcode = *currentCode;
sprintf(mnemonic, "int1");
currentCode++;
break;
}
case 0xF4:
{
Instruction->Opcode = *currentCode;
sprintf(mnemonic, "hlt");
currentCode++;
break;
}
case 0xF5:
{
Instruction->Opcode = *currentCode;
sprintf(mnemonic, "cmc");
currentCode++;
break;
}
case 0xF6: case 0xF7:
{
Instruction->Opcode = *currentCode;
Instruction->wFlag = *currentCode & 1;
Instruction->sFlag = (~(*currentCode & 1)) & 1;
currentCode++;
sprintf(mnemonic, "%s", LogicalArithmeticMnemonic[(*currentCode >> 3) & 7]);
currentCode = ParseModRM(currentCode, Instruction, operand1);
if(strcmp(mnemonic, "test") == 0)
{
currentCode = ParseImmediate(currentCode, Instruction, operand2);
}
break;
}
/* flag set */
case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD:
{
Instruction->Opcode = *currentCode;
sprintf(mnemonic, "%s", FlagMnemonic[*currentCode & 7]);
currentCode++;
break;
}
case 0xFE:
{
Instruction->Opcode = *currentCode;
Instruction->wFlag = *currentCode & 1;
currentCode++;
sprintf(mnemonic, "%s", (*currentCode >> 3) & 7 ? "dec" : "inc");
currentCode = ParseModRM(currentCode, Instruction, operand1);
break;
}
case 0xFF:
{
Instruction->Opcode = *currentCode;
Instruction->wFlag = *currentCode & 1;
currentCode++;
switch((*currentCode >> 3) & 7)
{
case 0 : case 1: case 2 : case 4: case 6:
{
sprintf(mnemonic, FFOpcodeMnemonic[(*currentCode >> 3) & 7]);
currentCode = ParseModRM(currentCode, Instruction, operand1);
break;
}
case 3 : case 5:
{
sprintf(mnemonic, FFOpcodeMnemonic[(*currentCode >> 3) & 7]);
currentCode = ParseModRM(currentCode, Instruction, operand1);
sprintf(operand2, "far %s%s", Instruction->OperandPrefix >= 0 ? "dword " : "fword ",
strstr(operand1, "ptr"));
sprintf(operand1, "%s", operand2);
*operand2 = '\0';
break;
}
default:
{
sprintf(mnemonic, "???");
currentCode++;
}
}
break;
}
/* 2-bytes instructions */
case 0x0F:
{
Instruction->Opcode = *((int *)currentCode) & 0xFFFF;
currentCode ++;
switch(*currentCode)
{
/* jxxx */
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F:
{
sprintf(mnemonic, "%s", *currentCode & 1 ? JnxxMnemonic[(*currentCode >> 1) & 7] : JxxxMnemonic[(*currentCode >> 1) & 7]);
currentCode++;
sprintf(operand1, "%X", Instruction->OperandPrefix >= 0 ? (Instruction->LinearAddress & 0xFFFF) + (*((int*)currentCode) & 0xFFFF) + currentCode - Code + 2 :
Instruction->LinearAddress + *((int *)currentCode) + currentCode - Code + 4);
Instruction->OperandPrefix >= 0 ? (currentCode += 2) : (currentCode += 4);
break;
}
/* setxxx */
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F:
{
Instruction->wFlag = 0;
sprintf(mnemonic, "%s", *currentCode & 1 ? SetnxxMnemonic[(*currentCode >> 1) & 7] : SetxxxMnemonic[(*currentCode >> 1) & 7]);
currentCode++;
currentCode = ParseModRM(currentCode, Instruction, operand1);
break;
}
/* push pop fs gs*/
case 0xA0: case 0xA1: case 0xA8: case 0xA9:
{
sprintf(mnemonic, "%s", *currentCode & 1 ? "pop" : "push");
sprintf(operand1, "%s", (*currentCode >> 3 & 1) ? "gs" : "fs");
currentCode++;
break;
}
/* bt bts btr btc bsf bsr */
case 0xA3: case 0xAB: case 0xB3: case 0xBB:
{
Instruction->dFlag = (*currentCode >> 1) & 1;
Instruction->wFlag = *currentCode & 1;
sprintf(mnemonic, "%s", BTMnemonic[(*currentCode >> 3) & 3]);
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand2, operand1);
break;
}
case 0xBA:
{
Instruction->wFlag = 1;
Instruction->sFlag = 1;
sprintf(mnemonic, "%s", BTMnemonic[(*(currentCode + 1) >> 3) & 3]);
currentCode++;
currentCode = ParseModRM(currentCode, Instruction, operand1);
currentCode = ParseImmediate(currentCode, Instruction, operand2);
break;
}
case 0xBC: case 0xBD:
{
Instruction->wFlag = 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "%s", *currentCode & 1 ? "bsr" : "bsf");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);
break;
}
/* cpuid */
case 0xA2:
{
sprintf(mnemonic, "cpuid");
currentCode++;
break;
}
/* shld, shrd */
case 0xA4: case 0xAC:
{
Instruction->wFlag = 1;
Instruction->dFlag = 1;
Instruction->sFlag = 1;
sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "shrd" : "shld");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand2, operand1);
currentCode = ParseImmediate(currentCode, Instruction, operand3);
break;
}
case 0xA5: case 0xAD:
{
Instruction->wFlag = 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "shrd" : "shld");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand2, operand1);
sprintf(operand3, "cl");
break;
}
/* imul */
case 0xAF:
{
Instruction->wFlag = 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "%s", "imul");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);
break;
}
/* cmpxchg */
case 0xB0: case 0xB1:
{
Instruction->wFlag = *currentCode & 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "cmpxchg");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand2, operand1);
break;
}
/* lss lfs lgs */
case 0xB2: case 0xB4: case 0xB5:
{
Instruction->wFlag = 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "l%s", SegmentRegisters[*currentCode & 7]);
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);
sprintf(operand3, "%s%s", Instruction->OperandPrefix >= 0 ? "dword " : "fword ",
strstr(operand2, "ptr"));
sprintf(operand2, "%s", operand3);
*operand3 = '\0';
break;
}
/* movzx movsx */
case 0xB6: case 0xB7: case 0xBE: case 0xBF:
{
Instruction->wFlag = *currentCode & 1;
sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "movsx" : "movzx");
currentCode++;
sprintf(operand1, "%s", Instruction->OperandPrefix >= 0 ? Register16[(*currentCode >> 3) & 7] : Register32[(*currentCode >> 3) & 7]);
currentCode = ParseModRM(currentCode, Instruction, operand2);
break;
}
case 0xC0: case 0xC1:
{
Instruction->wFlag = *currentCode & 1;
Instruction->dFlag = 1;
sprintf(mnemonic, "xadd");
currentCode++;
currentCode = ParseRegModRM(currentCode, Instruction, operand2, operand1);
break;
}
case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF:
{
sprintf(mnemonic, "bswap");
sprintf(operand1, "%s", Instruction->OperandPrefix >= 0 ? Register16[*currentCode & 7] : Register32[*currentCode & 7]);
currentCode++;
break;
}
default:
{
sprintf(mnemonic, "%s", "???");
currentCode++;
}
}
break;
}
default :
{
currentCode++;
sprintf(mnemonic, "%s", "???");
}
}
/* instruction str = [prefix] mnemonic [operand1,] [operand2,] [operand3] */
sprintf(InstructionStr, "%s%s%s%s%s%s%s%s%s",
prefix, strlen(prefix) > 0 ? "\t" : "",
mnemonic, "\t",
operand1,
strlen(operand2) > 0 ? ", " : "", operand2,
strlen(operand3) > 0 ? ", " : "", operand3);
return currentCode;
}
unsigned char *ParseModRM(unsigned char *Code, PINSTRUCTION Instruction, char *OperandRM)
{
unsigned char *currentCode;
char Mod, RM;
char DisplacementStr[MAX_OPERAND_LEN] = "";
char RMStr[MAX_OPERAND_LEN] = "";
char SizeStr[MAX_OPERAND_LEN] = "";
char AddressStr[MAX_OPERAND_LEN] = "";
char SegmentPrefixStr[MAX_OPERAND_LEN] ="";
currentCode = Code;
Instruction->ModRM = *currentCode;
/* get mod, reg/code, rm */
Mod = (*currentCode >> 6) & 3;
RM = (*currentCode) & 7;
sprintf(SegmentPrefixStr, "%s%s", Instruction->SegmentPrefix >= 0 ? SegmentRegisters[Instruction->SegmentPrefix] : "",
Instruction->SegmentPrefix >= 0 ? ":" : "");
sprintf(SizeStr, "%s", Instruction->wFlag ? (Instruction->OperandPrefix >= 0 ? "word ptr" : "dword ptr") : "byte ptr");
sprintf(AddressStr, "%s", Instruction->AddressPrefix >=0 ? Address16[RM] : Register32[RM]);
switch(Mod)
{
case 0 : /* 00 */
{
if(RM != 4 && RM != 5 && RM != 6) /* 100, 101,110 */
{
sprintf(RMStr, "%s", AddressStr);
currentCode++;
}
else if(RM == 4) /* 100 */
{
if(Instruction->AddressPrefix >= 0) /* 16 bits mode */
{
sprintf(RMStr, "%s", Address16[RM]);
currentCode++;
}
else /*32 bits mode */
{
/* SIB */
currentCode++;
currentCode = ParseSIB(currentCode, Instruction, RMStr);
currentCode++;
}
}
else if(RM == 5) /* 101 */
{
if(Instruction->AddressPrefix >= 0) /* 16 bits mode */
{
sprintf(RMStr, "%s", Address16[RM]);
currentCode++;
}
else /*32 bits mode */
{
/* displacement 32 */
currentCode++;
Instruction->Displacement = *((unsigned int *)currentCode);
sprintf(RMStr, "%X", *((unsigned int *)currentCode));
currentCode += 4;
}
}
else if(RM == 6) /* 110 */
{
if(Instruction->AddressPrefix >= 0) /* 16 bits mode */
{
/* displacement 16 */
currentCode++;
strcpy(&(Instruction->Displacement), currentCode, 2);
sprintf(RMStr, "%X%X%X%X", (*(currentCode + 1) >> 4) & 0xF,
(*(currentCode + 1) & 0xF), (*currentCode >> 4) & 0xF, (*currentCode) & 0xF);
currentCode += 2;
}
else /* 32 bits mode */
{
sprintf(RMStr, "%s", Register32[RM]);
currentCode++;
}
}
sprintf(OperandRM, "%s %s[%s]", SizeStr, SegmentPrefixStr, RMStr);
break;
}
case 1 : /* 01 */
{
if(RM != 4)
{
sprintf(RMStr, "%s", Register32[RM]);
}
else
{
/* SIB */
if(Instruction->AddressPrefix >= 0)
{
sprintf(RMStr, "%s", Address16[RM]);
}
else
{
currentCode++;
currentCode = ParseSIB(currentCode, Instruction, RMStr);
}
}
/* displacement 8 */
currentCode++;
Instruction->Displacement = *currentCode;
sprintf(DisplacementStr, "%s%X%X", (*currentCode >>7) & 1 ? " - " : " + ", (*currentCode >> 7) & 1 ? (~(*currentCode) + 1) >> 4 & 0xF : (*currentCode >> 4) & 0xF,
(*currentCode >> 7) & 1 ? (~(*currentCode) + 1) & 0xF : (*currentCode) & 0xF);
currentCode++;
sprintf(OperandRM, "%s %s[%s%s]", SizeStr, SegmentPrefixStr, RMStr, DisplacementStr);
break;
}
case 2 : /* 10 */
{
if(RM != 4)
{
sprintf(RMStr, "%s", Register32[RM]);
}
else
{
/* SIB */
if(Instruction->AddressPrefix >= 0)
{
sprintf(RMStr, "%s", Address16[RM]);
}
else
{
currentCode++;
currentCode = ParseSIB(currentCode, Instruction, RMStr);
}
}
/* displacement 32 */
currentCode++;
Instruction->Displacement = *((int *)currentCode);
sprintf(DisplacementStr, " %c %X", ((*((int *)currentCode)) >> 31) & 1 ? '-' : '+', ((*((int *)currentCode)) >> 31) & 1? ~(*((int *)currentCode)) + 1 : *((int *)currentCode));
currentCode += 4;
sprintf(OperandRM, "%s %s[%s%s]", SizeStr, SegmentPrefixStr, RMStr, DisplacementStr);
break;
}
case 3 : /* 11 */
{
sprintf(OperandRM, "%s", Instruction->wFlag ? (Instruction->OperandPrefix >= 0 ? Register16[RM] : Register32[RM])
: Register8[RM]);
currentCode++;
break;
}
}
return currentCode;
}
unsigned char *ParseRegModRM(unsigned char *Code, PINSTRUCTION Instruction, char *Operand1, char *Operand2)
{
unsigned char *currentCode;
char RegOpcode;
currentCode = Code;
RegOpcode = (*currentCode >> 3) & 7;
currentCode = ParseModRM(currentCode, Instruction, Instruction->dFlag ? Operand2 : Operand1);
sprintf(Instruction->dFlag ? Operand1 : Operand2, "%s", Instruction->wFlag ? (Instruction->OperandPrefix >= 0 ? Register16[RegOpcode] : Register32[RegOpcode])
: Register8[RegOpcode]);
return currentCode;
}
unsigned char *ParseImmediate(unsigned char *Code, PINSTRUCTION Instruction, char *OperandImmediate)
{
unsigned char *currentCode;
currentCode = Code;
if(!Instruction->sFlag)
{
if(Instruction->OperandPrefix >= 0)
{
/* 16 bits immediate value */
memcpy(&(Instruction->Immediate), currentCode, 2);
sprintf(OperandImmediate, "%X%X%X%X", (*(currentCode + 1) >> 4) & 0xF,
(*(currentCode + 1) & 0xF), (*currentCode >> 4) & 0xF, (*currentCode) & 0xF);
currentCode += 2;
}
else
{
/* 32 bits immediate value */
Instruction->Immediate = *((unsigned int *)currentCode);
sprintf(OperandImmediate, "%X", *((unsigned int *)currentCode));
currentCode += 4;
}
}
else
{
/* 8 bits immediate value */
Instruction->Immediate = *currentCode;
sprintf(OperandImmediate, "%X%X", (*currentCode >> 4) & 0xF, (*currentCode) & 0xF);
currentCode++;
}
return currentCode;
}
unsigned char *ParseSIB(unsigned char *Code, PINSTRUCTION Instruction, char *SIBStr)
{
char *currentCode;
char Mod;
char Scale, Index, Base;
char BaseStr[MAX_OPERAND_LEN] = "";
char ScaledIndexStr[MAX_OPERAND_LEN] = "";
char DisplacementStr[MAX_OPERAND_LEN] = "";
currentCode = Code;
Instruction->SIB = *currentCode;
Mod = ((Instruction->ModRM) >> 6) & 3;
Scale = (*currentCode >> 6) & 3;
Index = (*currentCode >> 3) & 7;
Base = (*currentCode) & 7;
/* base */
sprintf(BaseStr, "%s", (Base ==5 && Mod == 0) ? "" : Register32[Base]);
/* when Mod == 00b and Base = 101b, there is a special displacement 32 */
if(Base == 5 && Mod == 0)
{
currentCode ++;
Instruction->Displacement = *((long *)currentCode);
sprintf(DisplacementStr, "%X", *((int *)currentCode));
currentCode += 3;
}
/* scaled index */
Index == 4 ? sprintf(ScaledIndexStr, "") :
(Scale ? sprintf(ScaledIndexStr, "%s * %d", Register32[Index], 1 << Scale) :
sprintf(ScaledIndexStr, "%s", Register32[Index]));
/* merge them into SIB */
sprintf(SIBStr, "%s%s%s%s%s", BaseStr,
(strlen(BaseStr) > 0 && strlen(ScaledIndexStr) > 0) ? " + " : "",
ScaledIndexStr,
(strlen(BaseStr) > 0 && strlen(ScaledIndexStr) > 0 && strlen(DisplacementStr) > 0) ? " + " : "",
DisplacementStr);
return currentCode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -