/***************************************************************************************************12Zyan Disassembler Library (Zydis)34Original Author : Joel Hoener56* Permission is hereby granted, free of charge, to any person obtaining a copy7* of this software and associated documentation files (the "Software"), to deal8* in the Software without restriction, including without limitation the rights9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell10* copies of the Software, and to permit persons to whom the Software is11* furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included in all14* copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE22* SOFTWARE.2324***************************************************************************************************/2526#include <Zydis/Disassembler.h>27#include <Zycore/LibC.h>2829/* ============================================================================================== */30/* Internal helpers */31/* ============================================================================================== */3233static ZyanStatus ZydisDisassemble(ZydisMachineMode machine_mode,34ZyanU64 runtime_address, const void* buffer, ZyanUSize length,35ZydisDisassembledInstruction *instruction, ZydisFormatterStyle style)36{37if (!buffer || !instruction)38{39return ZYAN_STATUS_INVALID_ARGUMENT;40}4142*instruction = (ZydisDisassembledInstruction)43{44.runtime_address = runtime_address45};4647// Derive the stack width from the address width.48ZydisStackWidth stack_width;49switch (machine_mode)50{51case ZYDIS_MACHINE_MODE_LONG_64:52stack_width = ZYDIS_STACK_WIDTH_64;53break;54case ZYDIS_MACHINE_MODE_LONG_COMPAT_32:55case ZYDIS_MACHINE_MODE_LEGACY_32:56stack_width = ZYDIS_STACK_WIDTH_32;57break;58case ZYDIS_MACHINE_MODE_LONG_COMPAT_16:59case ZYDIS_MACHINE_MODE_LEGACY_16:60case ZYDIS_MACHINE_MODE_REAL_16:61stack_width = ZYDIS_STACK_WIDTH_16;62break;63default:64return ZYAN_STATUS_INVALID_ARGUMENT;65}6667ZydisDecoder decoder;68ZYAN_CHECK(ZydisDecoderInit(&decoder, machine_mode, stack_width));6970ZydisDecoderContext ctx;71ZYAN_CHECK(ZydisDecoderDecodeInstruction(&decoder, &ctx, buffer, length, &instruction->info));72ZYAN_CHECK(ZydisDecoderDecodeOperands(&decoder, &ctx, &instruction->info,73instruction->operands, instruction->info.operand_count));7475ZydisFormatter formatter;76ZYAN_CHECK(ZydisFormatterInit(&formatter, style));77ZYAN_CHECK(ZydisFormatterFormatInstruction(&formatter, &instruction->info,78instruction->operands, instruction->info.operand_count_visible, instruction->text,79sizeof(instruction->text), runtime_address, ZYAN_NULL));8081return ZYAN_STATUS_SUCCESS;82}8384/* ============================================================================================== */85/* Public functions */86/* ============================================================================================== */8788ZyanStatus ZydisDisassembleIntel(ZydisMachineMode machine_mode,89ZyanU64 runtime_address, const void* buffer, ZyanUSize length,90ZydisDisassembledInstruction *instruction)91{92return ZydisDisassemble(machine_mode, runtime_address, buffer, length, instruction,93ZYDIS_FORMATTER_STYLE_INTEL);94}9596ZyanStatus ZydisDisassembleATT(ZydisMachineMode machine_mode,97ZyanU64 runtime_address, const void* buffer, ZyanUSize length,98ZydisDisassembledInstruction *instruction)99{100return ZydisDisassemble(machine_mode, runtime_address, buffer, length, instruction,101ZYDIS_FORMATTER_STYLE_ATT);102}103104/* ============================================================================================== */105106107