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); | ||||||
|  |      | ||||||
|  |     if (instruction->operandCount > 0) | ||||||
|  |     { | ||||||
|  |         puts(""); | ||||||
|         printOperands(instruction); |         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