diff --git a/CMakeLists.txt b/CMakeLists.txt index 04cb3ea766..31392efff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,8 +350,8 @@ set(COMMON src/common/logging/backend.cpp src/common/config.cpp src/common/config.h src/common/debug.h - src/common/disassembler.cpp - src/common/disassembler.h + src/common/decoder.cpp + src/common/decoder.h src/common/endian.h src/common/enum.h src/common/io_file.cpp diff --git a/src/common/disassembler.cpp b/src/common/decoder.cpp similarity index 67% rename from src/common/disassembler.cpp rename to src/common/decoder.cpp index 2d1264a4eb..d8eddbcc64 100644 --- a/src/common/disassembler.cpp +++ b/src/common/decoder.cpp @@ -2,18 +2,18 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "common/disassembler.h" +#include "common/decoder.h" namespace Common { -Disassembler::Disassembler() { +Decoder::Decoder() { ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL); } -Disassembler::~Disassembler() = default; +Decoder::~Decoder() = default; -void Disassembler::printInstruction(void* code, u64 address) { +void Decoder::printInstruction(void* code, u64 address) { ZydisDecodedInstruction instruction; ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE]; ZyanStatus status = @@ -25,8 +25,7 @@ void Disassembler::printInstruction(void* code, u64 address) { } } -void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, - u64 address) { +void Decoder::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address) { const int bufLen = 256; char szBuffer[bufLen]; ZydisFormatterFormatInstruction(&m_formatter, &inst, operands, inst.operand_count_visible, @@ -34,4 +33,9 @@ void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* fmt::print("instruction: {}\n", szBuffer); } +ZyanStatus Decoder::decodeInstruction(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, + void* data, u64 size) { + return ZydisDecoderDecodeFull(&m_decoder, data, size, &inst, operands); +} + } // namespace Common diff --git a/src/common/disassembler.h b/src/common/decoder.h similarity index 59% rename from src/common/disassembler.h rename to src/common/decoder.h index b81f9e31bc..5d2175ba92 100644 --- a/src/common/disassembler.h +++ b/src/common/decoder.h @@ -8,13 +8,20 @@ namespace Common { -class Disassembler { +class Decoder { public: - Disassembler(); - ~Disassembler(); + Decoder(); + ~Decoder(); void printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address); void printInstruction(void* code, u64 address); + ZyanStatus decodeInstruction(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, + void* data, u64 size = 15); + + static Decoder& Instance() { + static Decoder instance; + return instance; + } private: ZydisDecoder m_decoder; diff --git a/src/core/cpu_patches.cpp b/src/core/cpu_patches.cpp index 1b159d32b3..819855ae34 100644 --- a/src/core/cpu_patches.cpp +++ b/src/core/cpu_patches.cpp @@ -9,6 +9,7 @@ #include #include "common/alignment.h" #include "common/assert.h" +#include "common/decoder.h" #include "common/types.h" #include "core/signals.h" #include "core/tls.h" @@ -622,7 +623,6 @@ static const std::unordered_map Patches = { }; static std::once_flag init_flag; -static ZydisDecoder instr_decoder; struct PatchModule { /// Mutex controlling access to module code regions. @@ -663,8 +663,8 @@ static PatchModule* GetModule(const void* ptr) { static std::pair TryPatch(u8* code, PatchModule* module) { ZydisDecodedInstruction instruction; ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; - const auto status = - ZydisDecoderDecodeFull(&instr_decoder, code, module->end - code, &instruction, operands); + const auto status = Common::Decoder::Instance().decodeInstruction(instruction, operands, code, + module->end - code); if (!ZYAN_SUCCESS(status)) { return std::make_pair(false, 1); } @@ -755,8 +755,6 @@ static bool PatchesIllegalInstructionHandler(void* code_address) { } static void PatchesInit() { - ZydisDecoderInit(&instr_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); - if (!Patches.empty()) { auto* signals = Signals::Instance(); // Should be called last. diff --git a/src/core/signals.cpp b/src/core/signals.cpp index a16c150e97..ab18e1c1c1 100644 --- a/src/core/signals.cpp +++ b/src/core/signals.cpp @@ -3,6 +3,7 @@ #include "common/arch.h" #include "common/assert.h" +#include "common/decoder.h" #include "core/signals.h" #ifdef _WIN32 @@ -10,7 +11,6 @@ #else #include #ifdef ARCH_X86_64 -#include #include #endif #endif @@ -66,14 +66,10 @@ static std::string DisassembleInstruction(void* code_address) { char buffer[256] = ""; #ifdef ARCH_X86_64 - ZydisDecoder decoder; - ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); - ZydisDecodedInstruction instruction; ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; - static constexpr u64 max_length = 0x20; const auto status = - ZydisDecoderDecodeFull(&decoder, code_address, max_length, &instruction, operands); + Common::Decoder::Instance().decodeInstruction(instruction, operands, code_address); if (ZYAN_SUCCESS(status)) { ZydisFormatter formatter; ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);