mirror of https://github.com/x64dbg/zydis
Improved `ZydisInfo` tool
This commit is contained in:
parent
53e89b0800
commit
18eaba7cdd
|
@ -67,76 +67,10 @@ const char* ZydisFormatStatus(ZydisStatus status)
|
||||||
/* Print functions */
|
/* Print functions */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
void printFlags(ZydisDecodedInstruction* instruction)
|
|
||||||
{
|
|
||||||
static const char* flagNames[] =
|
|
||||||
{
|
|
||||||
"CF",
|
|
||||||
"PF",
|
|
||||||
"AF",
|
|
||||||
"ZF",
|
|
||||||
"SF",
|
|
||||||
"TF",
|
|
||||||
"IF",
|
|
||||||
"DF",
|
|
||||||
"OF",
|
|
||||||
"IOPL",
|
|
||||||
"NT",
|
|
||||||
"RF",
|
|
||||||
"VM",
|
|
||||||
"AC",
|
|
||||||
"VIF",
|
|
||||||
"VIP",
|
|
||||||
"ID",
|
|
||||||
"C0",
|
|
||||||
"C1",
|
|
||||||
"C2",
|
|
||||||
"C3"
|
|
||||||
};
|
|
||||||
static const char* flagActions[] =
|
|
||||||
{
|
|
||||||
" ",
|
|
||||||
"T",
|
|
||||||
"M",
|
|
||||||
"0",
|
|
||||||
"1",
|
|
||||||
"U"
|
|
||||||
};
|
|
||||||
|
|
||||||
printf("FLAGS:\n ACTIONS: ");
|
|
||||||
uint8_t c = 0;
|
|
||||||
for (ZydisCPUFlag i = 0; i < ZYDIS_ARRAY_SIZE(instruction->flags); ++i)
|
|
||||||
{
|
|
||||||
if (instruction->flags[i].action != ZYDIS_CPUFLAG_ACTION_NONE)
|
|
||||||
{
|
|
||||||
++c;
|
|
||||||
printf("[%-4s: %s] ", flagNames[i], flagActions[instruction->flags[i].action]);
|
|
||||||
}
|
|
||||||
if (c == 8)
|
|
||||||
{
|
|
||||||
printf("\n ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
puts(c ? "" : "none");
|
|
||||||
|
|
||||||
ZydisCPUFlagMask flags, temp;
|
|
||||||
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_TESTED, &flags);
|
|
||||||
printf(" READ: 0x%08"PRIX32"\n", flags);
|
|
||||||
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_MODIFIED, &flags);
|
|
||||||
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_SET_0, &temp);
|
|
||||||
flags |= temp;
|
|
||||||
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_SET_1, &temp);
|
|
||||||
flags |= temp;
|
|
||||||
printf(" WRITTEN: 0x%08"PRIX32"\n", flags);
|
|
||||||
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_UNDEFINED, &flags);
|
|
||||||
printf(" UNDEFINED: 0x%08"PRIX32"\n", flags);
|
|
||||||
|
|
||||||
puts("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void printOperands(ZydisDecodedInstruction* instruction)
|
void printOperands(ZydisDecodedInstruction* instruction)
|
||||||
{
|
{
|
||||||
puts("Operands:");
|
fputs("== [ OPERANDS ] =====================================================", stdout);
|
||||||
|
fputs("=======================================\n", stdout);
|
||||||
fputs("## TYPE VISIBILITY ACTION ENCODING SIZE NELEM ELEMSZ", stdout);
|
fputs("## TYPE VISIBILITY ACTION ENCODING SIZE NELEM ELEMSZ", stdout);
|
||||||
fputs(" ELEMTYPE VALUE\n", stdout);
|
fputs(" ELEMTYPE VALUE\n", stdout);
|
||||||
fputs("== ========= ========== ====== ============ ==== ===== ======", stdout);
|
fputs("== ========= ========== ====== ============ ==== ===== ======", stdout);
|
||||||
|
@ -276,18 +210,203 @@ void printOperands(ZydisDecodedInstruction* instruction)
|
||||||
fputs(" ======== ===========================\n", stdout);
|
fputs(" ======== ===========================\n", stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printFlags(ZydisDecodedInstruction* instruction)
|
||||||
|
{
|
||||||
|
static const char* flagNames[] =
|
||||||
|
{
|
||||||
|
"CF",
|
||||||
|
"PF",
|
||||||
|
"AF",
|
||||||
|
"ZF",
|
||||||
|
"SF",
|
||||||
|
"TF",
|
||||||
|
"IF",
|
||||||
|
"DF",
|
||||||
|
"OF",
|
||||||
|
"IOPL",
|
||||||
|
"NT",
|
||||||
|
"RF",
|
||||||
|
"VM",
|
||||||
|
"AC",
|
||||||
|
"VIF",
|
||||||
|
"VIP",
|
||||||
|
"ID",
|
||||||
|
"C0",
|
||||||
|
"C1",
|
||||||
|
"C2",
|
||||||
|
"C3"
|
||||||
|
};
|
||||||
|
static const char* flagActions[] =
|
||||||
|
{
|
||||||
|
" ",
|
||||||
|
"T",
|
||||||
|
"M",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"U"
|
||||||
|
};
|
||||||
|
|
||||||
|
fputs("== [ FLAGS ] =====================================================", stdout);
|
||||||
|
fputs("=======================================\n", stdout);
|
||||||
|
printf(" ACTIONS: ");
|
||||||
|
uint8_t c = 0;
|
||||||
|
for (ZydisCPUFlag i = 0; i < ZYDIS_ARRAY_SIZE(instruction->flags); ++i)
|
||||||
|
{
|
||||||
|
if (instruction->flags[i].action != ZYDIS_CPUFLAG_ACTION_NONE)
|
||||||
|
{
|
||||||
|
++c;
|
||||||
|
printf("[%-4s: %s] ", flagNames[i], flagActions[instruction->flags[i].action]);
|
||||||
|
}
|
||||||
|
if (c == 8)
|
||||||
|
{
|
||||||
|
printf("\n ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts(c ? "" : "none");
|
||||||
|
|
||||||
|
ZydisCPUFlagMask flags, temp;
|
||||||
|
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_TESTED, &flags);
|
||||||
|
printf(" READ: 0x%08"PRIX32"\n", flags);
|
||||||
|
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_MODIFIED, &flags);
|
||||||
|
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_SET_0, &temp);
|
||||||
|
flags |= temp;
|
||||||
|
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_SET_1, &temp);
|
||||||
|
flags |= temp;
|
||||||
|
printf(" WRITTEN: 0x%08"PRIX32"\n", flags);
|
||||||
|
ZydisGetCPUFlagsByAction(instruction, ZYDIS_CPUFLAG_ACTION_UNDEFINED, &flags);
|
||||||
|
printf(" UNDEFINED: 0x%08"PRIX32"\n", flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printAVXInfo(ZydisDecodedInstruction* instruction)
|
||||||
|
{
|
||||||
|
static const char* broadcastStrings[] =
|
||||||
|
{
|
||||||
|
"NONE",
|
||||||
|
"1_TO_2",
|
||||||
|
"1_TO_4",
|
||||||
|
"1_TO_8",
|
||||||
|
"1_TO_16",
|
||||||
|
"1_TO_32",
|
||||||
|
"1_TO_64",
|
||||||
|
"2_TO_4",
|
||||||
|
"2_TO_8",
|
||||||
|
"2_TO_16",
|
||||||
|
"4_TO_8",
|
||||||
|
"4_TO_16",
|
||||||
|
"8_TO_16"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* maskModeStrings[] =
|
||||||
|
{
|
||||||
|
"NONE",
|
||||||
|
"MERGE",
|
||||||
|
"ZERO"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* roundingModeStrings[] =
|
||||||
|
{
|
||||||
|
"DEFAULT",
|
||||||
|
"RN",
|
||||||
|
"RD",
|
||||||
|
"RU",
|
||||||
|
"RZ"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* swizzleModeStrings[] =
|
||||||
|
{
|
||||||
|
"NONE",
|
||||||
|
"DCBA",
|
||||||
|
"CDAB",
|
||||||
|
"BADC",
|
||||||
|
"DACB",
|
||||||
|
"AAAA",
|
||||||
|
"BBBB",
|
||||||
|
"CCCC",
|
||||||
|
"DDDD"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* conversionModeStrings[] =
|
||||||
|
{
|
||||||
|
"NONE",
|
||||||
|
"FLOAT16",
|
||||||
|
"SINT8",
|
||||||
|
"UINT8",
|
||||||
|
"SINT16",
|
||||||
|
"UINT16"
|
||||||
|
};
|
||||||
|
|
||||||
|
fputs("== [ AVX ] =====================================================", stdout);
|
||||||
|
fputs("=======================================\n", stdout);
|
||||||
|
|
||||||
|
printf(" VECTORLEN: %03d\n", instruction->avx.vectorLength);
|
||||||
|
printf(" BROADCAST: %s%s", broadcastStrings[instruction->avx.broadcast.mode],
|
||||||
|
instruction->avx.broadcast.isStatic ? " (static)" : "");
|
||||||
|
|
||||||
|
switch (instruction->encoding)
|
||||||
|
{
|
||||||
|
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
||||||
|
printf("\n ROUNDING: %s", roundingModeStrings[instruction->avx.roundingMode]);
|
||||||
|
printf("\n SAE: %s", instruction->avx.hasSAE ? "Y" : "N");
|
||||||
|
printf("\n MASK: %s [%5s]%s", ZydisRegisterGetString(instruction->avx.mask.reg),
|
||||||
|
maskModeStrings[instruction->avx.mask.mode],
|
||||||
|
instruction->avx.mask.isControlMask ? " (control-mask)" : "");
|
||||||
|
break;
|
||||||
|
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
||||||
|
printf("\n ROUNDING: %s", roundingModeStrings[instruction->avx.roundingMode]);
|
||||||
|
printf("\n SAE: %s", instruction->avx.hasSAE ? "Y" : "N");
|
||||||
|
printf("\n MASK: %s [MERGE]", ZydisRegisterGetString(instruction->avx.mask.reg));
|
||||||
|
printf("\n EH: %s", instruction->avx.hasEvictionHint ? "Y" : "N");
|
||||||
|
printf("\n SWIZZLE: %s", swizzleModeStrings[instruction->avx.swizzleMode]);
|
||||||
|
printf("\n CONVERT: %s", conversionModeStrings[instruction->avx.conversionMode]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
void printInstruction(ZydisDecodedInstruction* instruction)
|
void printInstruction(ZydisDecodedInstruction* instruction)
|
||||||
{
|
{
|
||||||
ZydisFormatter formatter;
|
static const char* opcodeMapStrings[] =
|
||||||
ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL,
|
{
|
||||||
ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE,
|
"DEFAULT",
|
||||||
ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT);
|
"0F",
|
||||||
char buffer[256];
|
"0F38",
|
||||||
ZydisFormatterFormatInstruction(&formatter, instruction, &buffer[0], sizeof(buffer));
|
"0F3A",
|
||||||
printf("Mnemonic : %s\n", ZydisMnemonicGetString(instruction->mnemonic));
|
"0F0F",
|
||||||
printf("Disassembly: %s\n\n", &buffer[0]);
|
"XOP8",
|
||||||
|
"XOP9",
|
||||||
|
"XOPA"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* instructionEncodingStrings[] =
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
"DEFAULT",
|
||||||
|
"3DNOW",
|
||||||
|
"XOP",
|
||||||
|
"VEX",
|
||||||
|
"EVEX",
|
||||||
|
"MVEX"
|
||||||
|
};
|
||||||
|
|
||||||
|
fputs("== [ BASIC ] =====================================================", stdout);
|
||||||
|
fputs("=======================================\n", stdout);
|
||||||
|
printf(" MNEMONIC: %s [ENC: %s, MAP: %s, OPC: %02X]\n",
|
||||||
|
ZydisMnemonicGetString(instruction->mnemonic),
|
||||||
|
instructionEncodingStrings[instruction->encoding],
|
||||||
|
opcodeMapStrings[instruction->opcodeMap],
|
||||||
|
instruction->opcode);
|
||||||
|
printf(" LENGTH: %2d\n", instruction->length);
|
||||||
|
printf(" SSZ: %2d\n", instruction->stackWidth);
|
||||||
|
printf(" EOSZ: %2d\n", instruction->operandSize);
|
||||||
|
printf(" EASZ: %2d\n", instruction->addressWidth);
|
||||||
|
|
||||||
printOperands(instruction);
|
if (instruction->operandCount > 0)
|
||||||
|
{
|
||||||
|
puts("");
|
||||||
|
printOperands(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
if (ZydisRegisterGetClass(
|
if (ZydisRegisterGetClass(
|
||||||
instruction->operands[instruction->operandCount - 1].reg) == ZYDIS_REGCLASS_FLAGS)
|
instruction->operands[instruction->operandCount - 1].reg) == ZYDIS_REGCLASS_FLAGS)
|
||||||
|
@ -295,20 +414,33 @@ void printInstruction(ZydisDecodedInstruction* instruction)
|
||||||
puts("");
|
puts("");
|
||||||
printFlags(instruction);
|
printFlags(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_XOP) ||
|
||||||
|
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_VEX) ||
|
||||||
|
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
|
||||||
|
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
|
||||||
|
{
|
||||||
|
puts("");
|
||||||
|
printAVXInfo(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZydisFormatter formatter;
|
||||||
|
ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL,
|
||||||
|
ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE,
|
||||||
|
ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT);
|
||||||
|
char buffer[256];
|
||||||
|
ZydisFormatterFormatInstruction(&formatter, instruction, &buffer[0], sizeof(buffer));
|
||||||
|
fputs("\n== [ DISASM ] =====================================================", stdout);
|
||||||
|
fputs("=======================================\n", stdout);
|
||||||
|
printf(" %s\n", &buffer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Entry point */
|
/* Entry point */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
#include <../src/SharedData.h>
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf("%"PRId64"\n", (uint64_t)sizeof(ZydisInstructionDefinitionDEFAULT));
|
|
||||||
printf("%"PRId64"\n", (uint64_t)sizeof(ZydisInstructionDefinitionEVEX));
|
|
||||||
printf("%"PRId64"\n", (uint64_t)sizeof(ZydisOperandDefinition));
|
|
||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
fputs("Usage: ZydisInfo -[16|32|64] [hexbytes]\n", stderr);
|
fputs("Usage: ZydisInfo -[16|32|64] [hexbytes]\n", stderr);
|
||||||
|
@ -335,7 +467,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH] =
|
uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH] =
|
||||||
{
|
{
|
||||||
0x48, 0xC1, 0xC0, 0x04//0x0F, 0x01, 0xC3//0x48, 0x00, 0xC0//0x48, 0x8B, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00//0xC4, 0xE3, 0x89, 0x48, 0x8C, 0x98, 0x00, 0x01, 0x00, 0x00, 0x38//0x62, 0xF1, 0x6C, 0x5F, 0xC2, 0x54, 0x98, 0x40, 0x0F
|
0x62, 0x22, 0xF9, 0x85, 0xA2, 0x64, 0x78, 0x5E, 0x24, 0x04, 0xCF, 0x7E, 0x23
|
||||||
};
|
};
|
||||||
|
|
||||||
ZydisDecodedInstruction instruction;
|
ZydisDecodedInstruction instruction;
|
||||||
|
|
Loading…
Reference in New Issue