summaryrefslogtreecommitdiff
path: root/thirdparty/mhook/disasm-lib/disasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mhook/disasm-lib/disasm.c')
-rw-r--r--thirdparty/mhook/disasm-lib/disasm.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/thirdparty/mhook/disasm-lib/disasm.c b/thirdparty/mhook/disasm-lib/disasm.c
new file mode 100644
index 00000000..7e72baaa
--- /dev/null
+++ b/thirdparty/mhook/disasm-lib/disasm.c
@@ -0,0 +1,122 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+#undef NDEBUG
+#include <assert.h>
+#include <windows.h>
+#include "disasm.h"
+
+#ifdef NO_SANITY_CHECKS
+#define NDEBUG
+#undef assert
+#define assert(x)
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Global variables
+//////////////////////////////////////////////////////////////////////
+
+ARCHITECTURE_FORMAT SupportedArchitectures[] =
+{
+ { ARCH_X86, &X86 },
+ { ARCH_X86_16, &X86 },
+ { ARCH_X64, &X86 },
+ { ARCH_UNKNOWN, NULL }
+};
+
+typedef struct _DISASM_ARG_INFO
+{
+ INSTRUCTION *MatchedInstruction;
+ BOOL MatchPrefix;
+ U8 *Opcode;
+ U32 OpcodeLength;
+ INSTRUCTION_TYPE InstructionType;
+ U32 Count;
+} DISASM_ARG_INFO;
+
+//////////////////////////////////////////////////////////////////////
+// Function prototypes
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitInstruction(INSTRUCTION *Instruction, DISASSEMBLER *Disassembler);
+struct _ARCHITECTURE_FORMAT *GetArchitectureFormat(ARCHITECTURE_TYPE Type);
+
+//////////////////////////////////////////////////////////////////////
+// Disassembler setup
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitDisassembler(DISASSEMBLER *Disassembler, ARCHITECTURE_TYPE Architecture)
+{
+ ARCHITECTURE_FORMAT *ArchFormat;
+
+ memset(Disassembler, 0, sizeof(DISASSEMBLER));
+ Disassembler->Initialized = DISASSEMBLER_INITIALIZED;
+
+ ArchFormat = GetArchitectureFormat(Architecture);
+ if (!ArchFormat) { assert(0); return FALSE; }
+ Disassembler->ArchType = ArchFormat->Type;
+ Disassembler->Functions = ArchFormat->Functions;
+ return TRUE;
+}
+
+void CloseDisassembler(DISASSEMBLER *Disassembler)
+{
+ memset(Disassembler, 0, sizeof(DISASSEMBLER));
+}
+
+//////////////////////////////////////////////////////////////////////
+// Instruction setup
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitInstruction(INSTRUCTION *Instruction, DISASSEMBLER *Disassembler)
+{
+ memset(Instruction, 0, sizeof(INSTRUCTION));
+ Instruction->Initialized = INSTRUCTION_INITIALIZED;
+ Instruction->Disassembler = Disassembler;
+ memset(Instruction->String, ' ', MAX_OPCODE_DESCRIPTION-1);
+ Instruction->String[MAX_OPCODE_DESCRIPTION-1] = '\0';
+ return TRUE;
+}
+
+// If Decode = FALSE, only the following fields are valid:
+// Instruction->Length, Instruction->Address, Instruction->Prefixes, Instruction->PrefixCount,
+// Instruction->OpcodeBytes, Instruction->Instruction->OpcodeLength, Instruction->Groups,
+// Instruction->Type, Instruction->OperandCount
+//
+// If Disassemble = TRUE, then Instruction->String is valid (also requires Decode = TRUE)
+//
+// WARNING: This will overwrite the previously obtained instruction
+INSTRUCTION *GetInstruction(DISASSEMBLER *Disassembler, U64 VirtualAddress, U8 *Address, U32 Flags)
+{
+ if (Disassembler->Initialized != DISASSEMBLER_INITIALIZED) { assert(0); return NULL; }
+ assert(Address);
+ InitInstruction(&Disassembler->Instruction, Disassembler);
+ Disassembler->Instruction.Address = Address;
+ Disassembler->Instruction.VirtualAddressDelta = VirtualAddress - (U64)Address;
+ if (!Disassembler->Functions->GetInstruction(&Disassembler->Instruction, Address, Flags))
+ {
+ assert(Disassembler->Instruction.Address == Address);
+ assert(Disassembler->Instruction.Length < MAX_INSTRUCTION_LENGTH);
+
+ // Save the address that failed, in case the lower-level disassembler didn't
+ Disassembler->Instruction.Address = Address;
+ Disassembler->Instruction.ErrorOccurred = TRUE;
+ return NULL;
+ }
+ return &Disassembler->Instruction;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Miscellaneous
+///////////////////////////////////////////////////////////////////////////
+
+static ARCHITECTURE_FORMAT *GetArchitectureFormat(ARCHITECTURE_TYPE Type)
+{
+ ARCHITECTURE_FORMAT *Format;
+ for (Format = SupportedArchitectures; Format->Type != ARCH_UNKNOWN; Format++)
+ {
+ if (Format->Type == Type) return Format;
+ }
+
+ assert(0);
+ return NULL;
+}
+