Merge branch 'develop'

This commit is contained in:
athre0z 2015-05-22 17:45:06 +02:00
commit 5bab2410fc
17 changed files with 460 additions and 184 deletions

View File

@ -16,7 +16,7 @@ if (NOT CONFIGURED_ONCE)
set(compiler_specific "-Werror")
set(compiler_specific_cxx "-std=c++14")
elseif (MSVC)
set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS")
set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS /GR-")
endif ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${compiler_specific_cxx}"
@ -27,7 +27,7 @@ endif ()
# CMake always orders MSVC to build with a shared CRT. Hack CMake variables in order
# to generate with a statically linked CRT when we build as a static library.
if (MSVC AND NOT BUILD_SHARED_LIBS AND NOT FORCE_SHARED_CRT)
if (MSVC AND NOT FORCE_SHARED_CRT)
set(manipulated_vars
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
@ -58,6 +58,11 @@ set(sources
"Zydis/ZydisSymbolResolver.cpp"
"Zydis/ZydisUtils.cpp")
if (BUILD_SHARED_LIBS AND WIN32)
set(sources ${sources}
"Zydis/VersionInfo.rc")
endif ()
if (BUILD_C_BINDINGS)
set(headers ${headers}
"Zydis/ZydisAPI.h")
@ -66,6 +71,7 @@ if (BUILD_C_BINDINGS)
endif ()
add_library("Zydis" ${headers} ${sources})
set_target_properties("Zydis" PROPERTIES COMPILE_DEFINITIONS "Zydis_EXPORTS")
generate_export_header(
"Zydis"
BASE_NAME "ZYDIS"
@ -78,6 +84,8 @@ if (BUILD_EXAMPLES)
add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp")
target_link_libraries("SimpleDemo_CPP" "Zydis")
add_executable("CustomDataSource_CPP" "Examples/CPP/CustomDataSource/CustomDataSource.cpp")
target_link_libraries("CustomDataSource_CPP" "Zydis")
if (BUILD_C_BINDINGS)
add_executable("SimpleDemo_C" "Examples/C/SimpleDemo/SimpleDemo.c")

View File

@ -154,7 +154,7 @@ int main()
puts("64 bit test ...\n\n");
while (ZydisDecodeInstruction(decoder, &info))
{
printf("%016"PRIu64"X ", info.instrAddress);
printf("%016"PRIX64" ", info.instrAddress);
if (info.flags & ZYDIS_IF_ERROR_MASK)
{
printf("db %02X", info.data[0]);

View File

@ -0,0 +1,169 @@
/***************************************************************************************************
Zyan Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications : Joel Höner
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <stdint.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <sstream>
#include <Zydis.hpp>
class ZydisStdinInput : public Zydis::BaseInput
{
private:
std::vector<uint8_t> m_buffer;
uint32_t m_position = 0;
uint64_t m_globalPosition = 0;
private:
void gatherInput();
protected:
uint8_t internalInputPeek() override;
uint8_t internalInputNext() override;
public:
bool isEndOfInput() const override;
uint64_t getPosition() const override;
bool setPosition(uint64_t position) override;
};
void ZydisStdinInput::gatherInput()
{
if (m_position != m_buffer.size())
{
return;
}
std::vector<uint8_t> buffer;
bool valid;
do
{
valid = true;
buffer.clear();
std::string input;
std::getline(std::cin, input);
if (input.empty())
{
valid = false;
continue;
}
std::istringstream ss(input);
uint32_t x;
do
{
ss >> std::hex >> x;
if (ss.fail())
{
std::cout << std::endl << "# Error: Invalid hex input." << std::endl << std::endl;
ss.ignore();
valid = false;
break;
}
if (buffer.size() == buffer.capacity())
{
buffer.reserve(buffer.capacity() + 512);
}
if (x > 255)
{
std::cout << std::endl << "# Warning: 0x"
<< std::hex << std::setw(8) << std::setfill('0') << std::uppercase << x
<< " converted to uint8_t. Possible data loss." << std::endl << std::endl;
}
buffer.resize(buffer.size() + 1);
buffer[buffer.size() - 1] = static_cast<uint8_t>(x);
} while (!ss.eof());
} while (!valid);
m_buffer = buffer;
m_position = 0;
}
uint8_t ZydisStdinInput::internalInputPeek()
{
gatherInput();
return m_buffer[m_position];
}
uint8_t ZydisStdinInput::internalInputNext()
{
gatherInput();
m_globalPosition++;
return m_buffer[m_position++];
}
bool ZydisStdinInput::isEndOfInput() const
{
return false;
}
uint64_t ZydisStdinInput::getPosition() const
{
return m_globalPosition;
}
bool ZydisStdinInput::setPosition(uint64_t position)
{
if (position > m_globalPosition)
{
return false;
}
int64_t delta = m_globalPosition - position;
if (delta > m_position)
{
return false;
}
m_position = m_position - static_cast<int32_t>(delta);
m_globalPosition = position;
return true;
}
int main()
{
Zydis::InstructionInfo info;
Zydis::InstructionDecoder decoder;
Zydis::IntelInstructionFormatter formatter;
ZydisStdinInput input;
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
decoder.setDataSource(&input);
decoder.setInstructionPointer(0x00000000);
while (decoder.decodeInstruction(info))
{
std::cout << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
return 0;
}

View File

@ -78,7 +78,7 @@ int main()
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.data[0];
std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
@ -97,7 +97,7 @@ int main()
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.data[0];
std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;

View File

@ -1,5 +1,5 @@
Zyan Disassembler Engine (Zydis)
==================================
Zyan Disassembler Engine (Zydis) [![Build Status](https://travis-ci.org/zyantific/zyan-disassembler-engine.svg?branch=master)](https://travis-ci.org/zyantific/zyan-disassembler-engine)
================================
Fast and lightweight x86/x86-64 disassembler library.
@ -20,7 +20,7 @@ Fast and lightweight x86/x86-64 disassembler library.
The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console.
```C++
```c++
#include <tchar.h>
#include <iostream>
#include <stdint.h>
@ -35,7 +35,7 @@ int _tmain(int argc, _TCHAR* argv[])
Zydis::MemoryInput input(&data[0], sizeof(data));
Zydis::InstructionInfo info;
Zydis::InstructionDecoder decoder;
decoder.setDisassemblerMode(Zydis::ZydisMode::M32BIT);
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
decoder.setDataSource(&input);
decoder.setInstructionPointer(0);
Zydis::IntelInstructionFormatter formatter;
@ -47,8 +47,13 @@ int _tmain(int argc, _TCHAR* argv[])
```
## Compilation ##
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler.
## Documentation ##
[The HTML Doxygen documentation](https://www.zyantific.com/doc/zydis/index.html) is automatically built from master every 12 hours.
## License ##
Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.

BIN
Zydis/VersionInfo.rc Normal file

Binary file not shown.

View File

@ -28,12 +28,73 @@
***************************************************************************************************/
#ifndef _ZYDIS_DISASSEMBLER_HPP_
#define _ZYDIS_DISASSEMBLER_HPP_
/**
* @file
* @brief C++ API include file.
*/
/**
* @mainpage Zyan Disassembler Engine (Zydis)
*
* Zydis is a fast and lightweight x86/x86-64 disassembler library.
*
* @section Features
* - Supports all x86 and x86-64 (AMD64) General purpose and System instructions.
* - Supported ISA extensions:
* - MMX, FPU (x87), AMD 3DNow
* - SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES,
* - AMD-V, INTEL-VMX, SMX
* - Optimized for high performance
* - Very small overhead compared to other common disassembler libraries (about 60KiB)
* - Abstract formatter and symbol-resolver classes for custom syntax implementations.
* - Intel syntax is implemented by default
* - Complete doxygen documentation
*
* @section Quick Example
* The following example program uses Zydis to disassemble a given memory buffer and prints the
* output to the console.
*
* @code
* #include <tchar.h>
* #include <iostream>
* #include <stdint.h>
* #include "Zydis.hpp"
*
* int _tmain(int argc, _TCHAR* argv[])
* {
* uint8_t data[] =
* {
* 0x90, 0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3
* };
* Zydis::MemoryInput input(&data[0], sizeof(data));
* Zydis::InstructionInfo info;
* Zydis::InstructionDecoder decoder;
* decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
* decoder.setDataSource(&input);
* decoder.setInstructionPointer(0);
* Zydis::IntelInstructionFormatter formatter;
* while (decoder.decodeInstruction(info))
* {
* std::cout << formatter.formatInstruction(info) << std::endl;
* }
* }
* @endcode
*
* @section Compilation
* Zydis builds cleanly on most platforms without any external dependencies. You can use CMake
* to generate project files for your favorite C++14 compiler.
*
* @section License
* Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their
* respective licenses.
*/
#ifndef _ZYDIS_HPP_
#define _ZYDIS_HPP_
#include "ZydisInstructionDecoder.hpp"
#include "ZydisInstructionFormatter.hpp"
#include "ZydisSymbolResolver.hpp"
#include "ZydisUtils.hpp"
#endif /*_ZYDIS_DISASSEMBLER_HPP_ */
#endif /*_ZYDIS_HPP_ */

View File

@ -85,6 +85,7 @@ private:
using FullClassT = ZydisClassEx<ZydisClassT>;
public:
uint32_t type;
uint32_t align;
std::conditional_t<std::is_abstract<ZydisClassT>::value, char, ZydisClassT> instance;
public:
/**
@ -99,6 +100,7 @@ public:
typename... InstanceCtorArgsT>
ZydisClassEx(uint32_t classType, InstanceCtorArgsT... args)
: type(classType)
, align(0)
, instance(args...) { };
public:
/**
@ -126,7 +128,9 @@ public:
static FullClassT* fromInstance(ZydisClassT* instance)
{
return reinterpret_cast<FullClassT*>(
reinterpret_cast<uintptr_t>(instance) - sizeof(std::declval<FullClassT>().type));
reinterpret_cast<uintptr_t>(instance)
- sizeof(std::declval<FullClassT>().type)
- sizeof(std::declval<FullClassT>().align));
}
};
#pragma pack(pop)

View File

@ -28,11 +28,14 @@
***************************************************************************************************/
/**
* @file
* @brief C API for Zydis.
*/
#ifndef _ZYDIS_API_H_
#define _ZYDIS_API_H_
#define Zydis_EXPORTS
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>

View File

@ -61,7 +61,7 @@ bool InstructionDecoder::decodeRegisterOperand(InstructionInfo& info,
break;
case 8:
// TODO: Only REX? Or VEX too?
if (m_disassemblerMode == DisassemblerMode::M64BIT&& (info.flags& IF_PREFIX_REX))
if (m_disassemblerMode == DisassemblerMode::M64BIT && (info.flags & IF_PREFIX_REX))
{
if (registerId >= 4)
{
@ -88,7 +88,7 @@ bool InstructionDecoder::decodeRegisterOperand(InstructionInfo& info,
break;
case RegisterClass::MMX:
reg = static_cast<Register>(
static_cast<uint16_t>(Register::MM0) + (registerId& 0x07));
static_cast<uint16_t>(Register::MM0) + (registerId & 0x07));
break;
case RegisterClass::CONTROL:
reg = static_cast<Register>(static_cast<uint16_t>(Register::CR0) + registerId);
@ -97,13 +97,13 @@ bool InstructionDecoder::decodeRegisterOperand(InstructionInfo& info,
reg = static_cast<Register>(static_cast<uint16_t>(Register::DR0) + registerId);
break;
case RegisterClass::SEGMENT:
if ((registerId& 7) > 5)
if ((registerId & 7) > 5)
{
info.flags |= IF_ERROR_OPERAND;
return false;
}
reg = static_cast<Register>(
static_cast<uint16_t>(Register::ES) + (registerId& 0x07));
static_cast<uint16_t>(Register::ES) + (registerId & 0x07));
break;
case RegisterClass::XMM:
reg = static_cast<Register>(registerId + static_cast<uint16_t>(
@ -125,7 +125,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
{
return false;
}
assert(info.flags& IF_MODRM);
assert(info.flags & IF_MODRM);
// Decode register operand
if (info.modrm_mod == 3)
{
@ -147,10 +147,10 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
Register::SI, Register::DI, Register::SI, Register::DI,
Register::NONE, Register::NONE, Register::NONE,
Register::NONE };
operand.base = static_cast<Register>(bases[info.modrm_rm_ext& 0x07]);
operand.index = static_cast<Register>(indices[info.modrm_rm_ext& 0x07]);
operand.base = static_cast<Register>(bases[info.modrm_rm_ext & 0x07]);
operand.index = static_cast<Register>(indices[info.modrm_rm_ext & 0x07]);
operand.scale = 0;
if (info.modrm_mod == 0&& info.modrm_rm_ext == 6) {
if (info.modrm_mod == 0 && info.modrm_rm_ext == 6) {
offset = 16;
operand.base = Register::NONE;
} else if (info.modrm_mod == 1) {
@ -181,7 +181,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
default:
assert(0);
}
if ((info.modrm_rm_ext& 0x07) == 4)
if ((info.modrm_rm_ext & 0x07) == 4)
{
if (!decodeSIB(info))
{
@ -193,7 +193,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
operand.index =
static_cast<Register>(static_cast<uint16_t>(Register::EAX) +
info.sib_index_ext);
operand.scale = (1 << info.sib_scale)& ~1;
operand.scale = (1 << info.sib_scale) & ~1;
if (operand.index == Register::ESP)
{
operand.index = Register::NONE;
@ -225,7 +225,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
switch (info.modrm_mod)
{
case 0:
if ((info.modrm_rm_ext& 0x07) == 5)
if ((info.modrm_rm_ext & 0x07) == 5)
{
info.flags |= IF_RELATIVE;
operand.base = Register::RIP;
@ -241,7 +241,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
default:
assert(0);
}
if ((info.modrm_rm_ext& 0x07) == 4)
if ((info.modrm_rm_ext & 0x07) == 4)
{
if (!decodeSIB(info))
{
@ -259,7 +259,7 @@ bool InstructionDecoder::decodeRegisterMemoryOperand(InstructionInfo& info,
operand.scale = 0;
} else
{
operand.scale = (1 << info.sib_scale)& ~1;
operand.scale = (1 << info.sib_scale) & ~1;
}
if ((operand.base == Register::RBP) || (operand.base == Register::R13))
{
@ -318,7 +318,7 @@ bool InstructionDecoder::decodeImmediate(InstructionInfo& info, OperandInfo& ope
// TODO: Maybe return false instead of assert
assert(0);
}
if (!operand.lval.uqword&& (info.flags& IF_ERROR_MASK))
if (!operand.lval.uqword && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -350,7 +350,7 @@ bool InstructionDecoder::decodeDisplacement(InstructionInfo& info,
// TODO: Maybe return false instead of assert
assert(0);
}
if (!operand.lval.uqword&& (info.flags& IF_ERROR_MASK))
if (!operand.lval.uqword && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -359,17 +359,17 @@ bool InstructionDecoder::decodeDisplacement(InstructionInfo& info,
bool InstructionDecoder::decodeModrm(InstructionInfo& info)
{
if (!(info.flags& IF_MODRM))
if (!(info.flags & IF_MODRM))
{
info.modrm = inputNext(info);
if (!info.modrm&& (info.flags& IF_ERROR_MASK))
if (!info.modrm && (info.flags & IF_ERROR_MASK))
{
return false;
}
info.flags |= IF_MODRM;
info.modrm_mod = (info.modrm >> 6)& 0x03;
info.modrm_reg = (info.modrm >> 3)& 0x07;
info.modrm_rm = (info.modrm >> 0)& 0x07;
info.modrm_mod = (info.modrm >> 6) & 0x03;
info.modrm_reg = (info.modrm >> 3) & 0x07;
info.modrm_rm = (info.modrm >> 0) & 0x07;
}
// The @c decodeModrm method might get called multiple times during the opcode- and the
// operand decoding, but the effective REX/VEX fields are not initialized before the end of
@ -382,19 +382,19 @@ bool InstructionDecoder::decodeModrm(InstructionInfo& info)
bool InstructionDecoder::decodeSIB(InstructionInfo& info)
{
assert(info.flags& IF_MODRM);
assert((info.modrm_rm& 0x7) == 4);
if (!(info.flags& IF_SIB))
assert(info.flags & IF_MODRM);
assert((info.modrm_rm & 0x7) == 4);
if (!(info.flags & IF_SIB))
{
info.sib = inputNext(info);
if (!info.sib&& (info.flags& IF_ERROR_MASK))
if (!info.sib && (info.flags & IF_ERROR_MASK))
{
return false;
}
info.flags |= IF_SIB;
info.sib_scale = (info.sib >> 6)& 0x03;
info.sib_index = (info.sib >> 3)& 0x07;
info.sib_base = (info.sib >> 0)& 0x07;
info.sib_scale = (info.sib >> 6) & 0x03;
info.sib_index = (info.sib >> 3) & 0x07;
info.sib_base = (info.sib >> 0) & 0x07;
// The @c decodeSib method is only called during the operand decoding, so updating the
// extended values at this point should be safe.
info.sib_index_ext = (info.eff_rexvex_x << 3) | info.sib_index;
@ -405,45 +405,45 @@ bool InstructionDecoder::decodeSIB(InstructionInfo& info)
bool InstructionDecoder::decodeVex(InstructionInfo& info)
{
if (!(info.flags& IF_PREFIX_VEX))
if (!(info.flags & IF_PREFIX_VEX))
{
info.vex_op = inputCurrent();
switch (info.vex_op)
{
case 0xC4:
info.vex_b1 = inputNext(info);
if (!info.vex_b1 || (info.flags& IF_ERROR_MASK))
if (!info.vex_b1 || (info.flags & IF_ERROR_MASK))
{
return false;
}
info.vex_b2 = inputNext(info);
if (!info.vex_b2 || (info.flags& IF_ERROR_MASK))
if (!info.vex_b2 || (info.flags & IF_ERROR_MASK))
{
return false;
}
info.vex_r = (info.vex_b1 >> 7)& 0x01;
info.vex_x = (info.vex_b1 >> 6)& 0x01;
info.vex_b = (info.vex_b1 >> 5)& 0x01;
info.vex_m_mmmm = (info.vex_b1 >> 0)& 0x1F;
info.vex_w = (info.vex_b2 >> 7)& 0x01;
info.vex_vvvv = (info.vex_b2 >> 3)& 0x0F;
info.vex_l = (info.vex_b2 >> 2)& 0x01;
info.vex_pp = (info.vex_b2 >> 0)& 0x03;
info.vex_r = (info.vex_b1 >> 7) & 0x01;
info.vex_x = (info.vex_b1 >> 6) & 0x01;
info.vex_b = (info.vex_b1 >> 5) & 0x01;
info.vex_m_mmmm = (info.vex_b1 >> 0) & 0x1F;
info.vex_w = (info.vex_b2 >> 7) & 0x01;
info.vex_vvvv = (info.vex_b2 >> 3) & 0x0F;
info.vex_l = (info.vex_b2 >> 2) & 0x01;
info.vex_pp = (info.vex_b2 >> 0) & 0x03;
break;
case 0xC5:
info.vex_b1 = inputNext(info);
if (!info.vex_b1 || (info.flags& IF_ERROR_MASK))
if (!info.vex_b1 || (info.flags & IF_ERROR_MASK))
{
return false;
}
info.vex_r = (info.vex_b1 >> 7)& 0x01;
info.vex_r = (info.vex_b1 >> 7) & 0x01;
info.vex_x = 1;
info.vex_b = 1;
info.vex_m_mmmm = 1;
info.vex_w = 0;
info.vex_vvvv = (info.vex_b1 >> 3)& 0x0F;
info.vex_l = (info.vex_b1 >> 2)& 0x01;
info.vex_pp = (info.vex_b1 >> 0)& 0x03;
info.vex_vvvv = (info.vex_b1 >> 3) & 0x0F;
info.vex_l = (info.vex_b1 >> 2) & 0x01;
info.vex_pp = (info.vex_b1 >> 0) & 0x03;
break;
default:
assert(0);
@ -513,19 +513,19 @@ bool InstructionDecoder::decodeOperands(InstructionInfo& info)
info.operand[i].access_mode = OperandAccessMode::READ;
if (i == 0)
{
if (info.instrDefinition->flags& IDF_OPERAND1_WRITE)
if (info.instrDefinition->flags & IDF_OPERAND1_WRITE)
{
info.operand[0].access_mode = OperandAccessMode::WRITE;
} else if (info.instrDefinition->flags& IDF_OPERAND1_READWRITE)
} else if (info.instrDefinition->flags & IDF_OPERAND1_READWRITE)
{
info.operand[0].access_mode = OperandAccessMode::READWRITE;
}
} else if (i == 1)
{
if (info.instrDefinition->flags& IDF_OPERAND2_WRITE)
if (info.instrDefinition->flags & IDF_OPERAND2_WRITE)
{
info.operand[1].access_mode = OperandAccessMode::WRITE;
} else if (info.instrDefinition->flags& IDF_OPERAND2_READWRITE)
} else if (info.instrDefinition->flags & IDF_OPERAND2_READWRITE)
{
info.operand[1].access_mode = OperandAccessMode::READWRITE;
}
@ -556,7 +556,7 @@ bool InstructionDecoder::decodeOperand(InstructionInfo& info, OperandInfo& opera
operand.lval.ptr.off = inputNext<uint32_t>(info);
operand.lval.ptr.seg = inputNext<uint16_t>(info);
}
if ((!operand.lval.ptr.off || !operand.lval.ptr.seg)&& (info.flags& IF_ERROR_MASK))
if ((!operand.lval.ptr.off || !operand.lval.ptr.seg) && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -596,7 +596,7 @@ bool InstructionDecoder::decodeOperand(InstructionInfo& info, OperandInfo& opera
info.modrm_reg_ext, operandSize);
case DefinedOperandType::H:
assert(info.vex_op != 0);
return decodeRegisterOperand(info, operand, RegisterClass::XMM, (0xF& ~info.vex_vvvv),
return decodeRegisterOperand(info, operand, RegisterClass::XMM, (0xF & ~info.vex_vvvv),
operandSize);
case DefinedOperandType::sI:
operand.signed_lval = true;
@ -619,12 +619,12 @@ bool InstructionDecoder::decodeOperand(InstructionInfo& info, OperandInfo& opera
{
assert(info.vex_op != 0);
uint8_t imm = inputNext(info);
if (!imm&& (info.flags& IF_ERROR_MASK))
if (!imm && (info.flags & IF_ERROR_MASK))
{
return false;
}
uint8_t mask = (m_disassemblerMode == DisassemblerMode::M64BIT) ? 0xF : 0x7;
return decodeRegisterOperand(info, operand, RegisterClass::XMM, mask& (imm >> 4),
return decodeRegisterOperand(info, operand, RegisterClass::XMM, mask & (imm >> 4),
operandSize);
}
case DefinedOperandType::MR:
@ -729,7 +729,7 @@ bool InstructionDecoder::decodeOperand(InstructionInfo& info, OperandInfo& opera
case DefinedOperandType::GS:
if (m_disassemblerMode == DisassemblerMode::M64BIT)
{
if ((operandType != DefinedOperandType::FS)&&
if ((operandType != DefinedOperandType::FS) &&
(operandType != DefinedOperandType::GS))
{
info.flags |= IF_ERROR_OPERAND;
@ -768,25 +768,25 @@ void InstructionDecoder::resolveOperandAndAddressMode(InstructionInfo& info) con
switch (m_disassemblerMode)
{
case DisassemblerMode::M16BIT:
info.operand_mode = (info.flags& IF_PREFIX_OPERAND_SIZE) ? 32 : 16;
info.address_mode = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 32 : 16;
info.operand_mode = (info.flags & IF_PREFIX_OPERAND_SIZE) ? 32 : 16;
info.address_mode = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 32 : 16;
break;
case DisassemblerMode::M32BIT:
info.operand_mode = (info.flags& IF_PREFIX_OPERAND_SIZE) ? 16 : 32;
info.address_mode = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 16 : 32;
info.operand_mode = (info.flags & IF_PREFIX_OPERAND_SIZE) ? 16 : 32;
info.address_mode = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 16 : 32;
break;
case DisassemblerMode::M64BIT:
if (info.eff_rexvex_w)
{
info.operand_mode = 64;
} else if ((info.flags& IF_PREFIX_OPERAND_SIZE))
} else if ((info.flags & IF_PREFIX_OPERAND_SIZE))
{
info.operand_mode = 16;
} else
{
info.operand_mode = (info.instrDefinition->flags& IDF_DEFAULT_64) ? 64 : 32;
info.operand_mode = (info.instrDefinition->flags & IDF_DEFAULT_64) ? 64 : 32;
}
info.address_mode = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 32 : 64;
info.address_mode = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 32 : 64;
break;
default:
assert(0);
@ -797,26 +797,26 @@ void InstructionDecoder::calculateEffectiveRexVexValues(InstructionInfo& info) c
{
assert(info.instrDefinition);
uint8_t rex = info.rex;
if (info.flags& IF_PREFIX_VEX)
if (info.flags & IF_PREFIX_VEX)
{
switch (info.vex_op)
{
case 0xC4:
rex = ((~(info.vex_b1 >> 5)& 0x07) | ((info.vex_b2 >> 4)& 0x08));
rex = ((~(info.vex_b1 >> 5) & 0x07) | ((info.vex_b2 >> 4) & 0x08));
break;
case 0xC5:
rex = (~(info.vex_b1 >> 5))& 4;
rex = (~(info.vex_b1 >> 5)) & 4;
break;
default:
assert(0);
}
}
rex &= (info.instrDefinition->flags& 0x000F);
info.eff_rexvex_w = (rex >> 3)& 0x01;
info.eff_rexvex_r = (rex >> 2)& 0x01;
info.eff_rexvex_x = (rex >> 1)& 0x01;
info.eff_rexvex_b = (rex >> 0)& 0x01;
info.eff_vex_l = info.vex_l&& (info.instrDefinition->flags& IDF_ACCEPTS_VEXL);
rex &= (info.instrDefinition->flags & 0x000F);
info.eff_rexvex_w = (rex >> 3) & 0x01;
info.eff_rexvex_r = (rex >> 2) & 0x01;
info.eff_rexvex_x = (rex >> 1) & 0x01;
info.eff_rexvex_b = (rex >> 0) & 0x01;
info.eff_vex_l = info.vex_l && (info.instrDefinition->flags & IDF_ACCEPTS_VEXL);
}
bool InstructionDecoder::decodePrefixes(InstructionInfo& info)
@ -870,8 +870,8 @@ bool InstructionDecoder::decodePrefixes(InstructionInfo& info)
info.flags |= IF_PREFIX_ADDRESS_SIZE;
break;
default:
if ((m_disassemblerMode == DisassemblerMode::M64BIT)&&
(inputCurrent()& 0xF0) == 0x40)
if ((m_disassemblerMode == DisassemblerMode::M64BIT) &&
(inputCurrent() & 0xF0) == 0x40)
{
info.flags |= IF_PREFIX_REX;
info.rex = inputCurrent();
@ -884,7 +884,7 @@ bool InstructionDecoder::decodePrefixes(InstructionInfo& info)
// Increase the input offset, if a prefix was found
if (!done)
{
if (!inputNext(info)&& (info.flags& IF_ERROR_MASK))
if (!inputNext(info) && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -892,12 +892,12 @@ bool InstructionDecoder::decodePrefixes(InstructionInfo& info)
} while (!done);
// TODO: Check for multiple prefixes of the same group
// Parse REX Prefix
if (info.flags& IF_PREFIX_REX)
if (info.flags & IF_PREFIX_REX)
{
info.rex_w = (info.rex >> 3)& 0x01;
info.rex_r = (info.rex >> 2)& 0x01;
info.rex_x = (info.rex >> 1)& 0x01;
info.rex_b = (info.rex >> 0)& 0x01;
info.rex_w = (info.rex >> 3) & 0x01;
info.rex_r = (info.rex >> 2) & 0x01;
info.rex_x = (info.rex >> 1) & 0x01;
info.rex_b = (info.rex >> 0) & 0x01;
}
return true;
}
@ -906,7 +906,7 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
{
using namespace Internal;
// Read first opcode byte
if (!inputNext(info)&& (info.flags& IF_ERROR_MASK))
if (!inputNext(info) && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -934,8 +934,8 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
const InstructionDefinition *instrDefinition =
GetInstructionDefinition(node);
// Check for invalid 64 bit instruction
if ((m_disassemblerMode == DisassemblerMode::M64BIT)&&
(instrDefinition->flags& IDF_INVALID_64))
if ((m_disassemblerMode == DisassemblerMode::M64BIT) &&
(instrDefinition->flags & IDF_INVALID_64))
{
info.flags |= IF_ERROR_INVALID_64;
return false;
@ -956,12 +956,12 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
return true;
case OpcodeTreeNodeType::TABLE:
// Read next opcode byte
if (!inputNext(info)&& (info.flags& IF_ERROR_MASK))
if (!inputNext(info) && (info.flags & IF_ERROR_MASK))
{
return false;
}
// Update instruction info
assert((info.opcode_length > 0)&& (info.opcode_length < 3));
assert((info.opcode_length > 0) && (info.opcode_length < 3));
info.opcode[info.opcode_length] = inputCurrent();
info.opcode_length++;
// Set child node index for next iteration
@ -993,13 +993,13 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
break;
case OpcodeTreeNodeType::MANDATORY:
// Check if there are any prefixes present
if (info.flags& IF_PREFIX_REP)
if (info.flags & IF_PREFIX_REP)
{
index = 1; // F2
} else if (info.flags& IF_PREFIX_REPNE)
} else if (info.flags & IF_PREFIX_REPNE)
{
index = 2; // F3
} else if (info.flags& IF_PREFIX_OPERAND_SIZE)
} else if (info.flags & IF_PREFIX_OPERAND_SIZE)
{
index = 3; // 66
}
@ -1007,7 +1007,7 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
{
index = 0;
}
if (index&& (GetOpcodeTreeChild(node, index) != 0))
if (index && (GetOpcodeTreeChild(node, index) != 0))
{
// Remove REP and REPNE prefix
info.flags &= ~IF_PREFIX_REP;
@ -1032,13 +1032,13 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
switch (m_disassemblerMode)
{
case DisassemblerMode::M16BIT:
index = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 1 : 0;
index = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 1 : 0;
break;
case DisassemblerMode::M32BIT:
index = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 0 : 1;
index = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 0 : 1;
break;
case DisassemblerMode::M64BIT:
index = (info.flags& IF_PREFIX_ADDRESS_SIZE) ? 1 : 2;
index = (info.flags & IF_PREFIX_ADDRESS_SIZE) ? 1 : 2;
break;
default:
assert(0);
@ -1048,13 +1048,13 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
switch (m_disassemblerMode)
{
case DisassemblerMode::M16BIT:
index = (info.flags& IF_PREFIX_OPERAND_SIZE) ? 1 : 0;
index = (info.flags & IF_PREFIX_OPERAND_SIZE) ? 1 : 0;
break;
case DisassemblerMode::M32BIT:
index = (info.flags& IF_PREFIX_OPERAND_SIZE) ? 0 : 1;
index = (info.flags & IF_PREFIX_OPERAND_SIZE) ? 0 : 1;
break;
case DisassemblerMode::M64BIT:
index = (info.rex_w) ? 2 : ((info.flags& IF_PREFIX_OPERAND_SIZE) ? 0 : 1);
index = (info.rex_w) ? 2 : ((info.flags & IF_PREFIX_OPERAND_SIZE) ? 0 : 1);
break;
default:
assert(0);
@ -1100,7 +1100,7 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
}
// Read the actual 3dnow opcode
info.opcode[2] = inputNext(info);
if (!info.opcode[2]&& (info.flags& IF_ERROR_MASK))
if (!info.opcode[2] && (info.flags & IF_ERROR_MASK))
{
return false;
}
@ -1125,20 +1125,20 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
}
if (info.operand[0].type != OperandType::NONE)
{
if (info.instrDefinition->flags& IDF_OPERAND1_WRITE)
if (info.instrDefinition->flags & IDF_OPERAND1_WRITE)
{
info.operand[0].access_mode = OperandAccessMode::WRITE;
} else if (info.instrDefinition->flags& IDF_OPERAND1_READWRITE)
} else if (info.instrDefinition->flags & IDF_OPERAND1_READWRITE)
{
info.operand[0].access_mode = OperandAccessMode::READWRITE;
}
}
if (info.operand[1].type != OperandType::NONE)
{
if (info.instrDefinition->flags& IDF_OPERAND2_WRITE)
if (info.instrDefinition->flags & IDF_OPERAND2_WRITE)
{
info.operand[1].access_mode = OperandAccessMode::WRITE;
} else if (info.instrDefinition->flags& IDF_OPERAND2_READWRITE)
} else if (info.instrDefinition->flags & IDF_OPERAND2_READWRITE)
{
info.operand[1].access_mode = OperandAccessMode::READWRITE;
}
@ -1148,7 +1148,7 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
}
case OpcodeTreeNodeType::VEX:
if ((m_disassemblerMode == DisassemblerMode::M64BIT) ||
(((inputCurrent() >> 6)& 0x03) == 0x03))
(((inputCurrent() >> 6) & 0x03) == 0x03))
{
// Decode vex prefix
if (!decodeVex(info))
@ -1181,11 +1181,11 @@ bool InstructionDecoder::decodeOpcode(InstructionInfo& info)
}
break;
case OpcodeTreeNodeType::VEXW:
assert(info.flags& IF_PREFIX_VEX);
assert(info.flags & IF_PREFIX_VEX);
index = info.vex_w;
break;
case OpcodeTreeNodeType::VEXL:
assert(info.flags& IF_PREFIX_VEX);
assert(info.flags & IF_PREFIX_VEX);
index = info.vex_l;
break;
default:
@ -1243,7 +1243,7 @@ bool InstructionDecoder::decodeInstruction(InstructionInfo& info)
goto DecodeError;
}
// SWAPGS is only valid in 64 bit mode
if ((info.mnemonic == InstructionMnemonic::SWAPGS)&&
if ((info.mnemonic == InstructionMnemonic::SWAPGS) &&
(m_disassemblerMode != DisassemblerMode::M64BIT))
{
info.flags &= IF_ERROR_INVALID;
@ -1252,13 +1252,13 @@ bool InstructionDecoder::decodeInstruction(InstructionInfo& info)
// Handle aliases
if (info.mnemonic == InstructionMnemonic::XCHG)
{
if ((info.operand[0].type == OperandType::REGISTER&&
info.operand[0].base == Register::AX&&
info.operand[1].type == OperandType::REGISTER&&
if ((info.operand[0].type == OperandType::REGISTER &&
info.operand[0].base == Register::AX &&
info.operand[1].type == OperandType::REGISTER &&
info.operand[1].base == Register::AX) ||
(info.operand[0].type == OperandType::REGISTER&&
info.operand[0].base == Register::EAX&&
info.operand[1].type == OperandType::REGISTER&&
(info.operand[0].type == OperandType::REGISTER &&
info.operand[0].base == Register::EAX &&
info.operand[1].type == OperandType::REGISTER &&
info.operand[1].base == Register::EAX))
{
info.mnemonic = InstructionMnemonic::NOP;
@ -1268,7 +1268,7 @@ bool InstructionDecoder::decodeInstruction(InstructionInfo& info)
info.operand[1].access_mode = OperandAccessMode::NA;
}
}
if ((info.mnemonic == InstructionMnemonic::NOP)&& (info.flags& IF_PREFIX_REP))
if ((info.mnemonic == InstructionMnemonic::NOP) && (info.flags & IF_PREFIX_REP))
{
info.mnemonic = InstructionMnemonic::PAUSE;
info.flags &= ~IF_PREFIX_REP;
@ -1282,7 +1282,7 @@ DecodeError:
// Increment instruction pointer.
m_instructionPointer += 1;
// Backup all error flags, the instruction length and the instruction address
uint32_t flags = info.flags& (IF_ERROR_MASK | 0x00000007);
uint32_t flags = info.flags & (IF_ERROR_MASK | 0x00000007);
uint8_t length = info.length;
uint8_t firstByte = info.data[0];
uint64_t instrAddress = info.instrAddress;
@ -1303,7 +1303,7 @@ DecodeError:
}
// Return with error, if the end of the input source was reached while decoding the
// invalid instruction
if (info.flags& IF_ERROR_END_OF_INPUT)
if (info.flags & IF_ERROR_END_OF_INPUT)
{
info.length = 0;
return false;

View File

@ -28,6 +28,11 @@
***************************************************************************************************/
/**
* @file
* @brief Instruction decoder classes.
*/
#ifndef _ZYDIS_INSTRUCTIONDECODER_HPP_
#define _ZYDIS_INSTRUCTIONDECODER_HPP_
@ -45,34 +50,10 @@ namespace Zydis
*/
class BaseInput
{
friend class InstructionDecoder;
private:
uint8_t m_currentInput;
protected:
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method increases the current
* input position by one.
* @return The current input byte.
*/
virtual uint8_t internalInputPeek() = 0;
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method does NOT increase the
* current input position.
* @return The current input byte.
*/
virtual uint8_t internalInputNext() = 0;
protected:
/**
* @brief Default constructor.
*/
BaseInput() { };
public:
/**
* @brief Destructor.
*/
virtual ~BaseInput() { };
public:
private:
/**
* @brief Reads the next byte from the data source. This method does NOT increase the
* current input position or the @c length field of the @c info parameter.
@ -111,6 +92,31 @@ public:
* @return The current input byte.
*/
uint8_t inputCurrent() const;
protected:
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method increases the current
* input position by one.
* @return The current input byte.
*/
virtual uint8_t internalInputPeek() = 0;
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method does NOT increase the
* current input position.
* @return The current input byte.
*/
virtual uint8_t internalInputNext() = 0;
protected:
/**
* @brief Default constructor.
*/
BaseInput() { };
public:
/**
* @brief Destructor.
*/
virtual ~BaseInput() { };
public:
/**
* @brief Override this method in your custom data source implementations.
@ -175,7 +181,7 @@ inline T BaseInput::inputNext(InstructionInfo& info)
for (unsigned i = 0; i < (sizeof(T) / sizeof(uint8_t)); ++i)
{
T b = inputNext(info);
if (!b&& (info.flags& IF_ERROR_MASK))
if (!b && (info.flags & IF_ERROR_MASK))
{
return 0;
}

View File

@ -40,7 +40,7 @@ namespace Zydis
/* BaseInstructionFormatter ================================================================ */
const char *BaseInstructionFormatter::m_registerStrings[] =
const char* BaseInstructionFormatter::m_registerStrings[] =
{
/* 8 bit general purpose registers */
"al", "cl", "dl", "bl",
@ -238,13 +238,13 @@ void BaseInstructionFormatter::outputAppendAddress(const InstructionInfo& info,
}
} else
{
if (info.flags& IF_DISASSEMBLER_MODE_16)
if (info.flags & IF_DISASSEMBLER_MODE_16)
{
outputAppendFormatted("%.4X", address);
} else if (info.flags& IF_DISASSEMBLER_MODE_32)
} else if (info.flags & IF_DISASSEMBLER_MODE_32)
{
outputAppendFormatted("%.8lX", address);
} else if (info.flags& IF_DISASSEMBLER_MODE_64)
} else if (info.flags & IF_DISASSEMBLER_MODE_64)
{
outputAppendFormatted("%.16llX", address);
} else
@ -294,7 +294,7 @@ void BaseInstructionFormatter::outputAppendImmediate(const InstructionInfo& info
}
}
uint64_t offset = 0;
const char *name = nullptr;
const char* name = nullptr;
if (resolveSymbols)
{
name = resolveSymbol(info, value, offset);
@ -317,7 +317,7 @@ void BaseInstructionFormatter::outputAppendImmediate(const InstructionInfo& info
void BaseInstructionFormatter::outputAppendDisplacement(const OperandInfo& operand)
{
assert(operand.offset > 0);
if ((operand.base == Register::NONE)&& (operand.index == Register::NONE))
if ((operand.base == Register::NONE) && (operand.index == Register::NONE))
{
// Assume the displacement value is unsigned
assert(operand.scale == 0);
@ -409,7 +409,7 @@ void IntelInstructionFormatter::formatOperand(const InstructionInfo& info,
outputAppend(registerToString(operand.base));
break;
case OperandType::MEMORY:
if (info.flags& IF_PREFIX_SEGMENT)
if (info.flags & IF_PREFIX_SEGMENT)
{
outputAppendFormatted("%s:", registerToString(info.segment));
}
@ -481,14 +481,14 @@ void IntelInstructionFormatter::formatOperand(const InstructionInfo& info,
void IntelInstructionFormatter::internalFormatInstruction(const InstructionInfo& info)
{
// Append string prefixes
if (info.flags& IF_PREFIX_LOCK)
if (info.flags & IF_PREFIX_LOCK)
{
outputAppend("lock ");
}
if (info.flags& IF_PREFIX_REP)
if (info.flags & IF_PREFIX_REP)
{
outputAppend("rep ");
} else if (info.flags& IF_PREFIX_REPNE)
} else if (info.flags & IF_PREFIX_REPNE)
{
outputAppend("repne ");
}
@ -507,7 +507,7 @@ void IntelInstructionFormatter::internalFormatInstruction(const InstructionInfo&
(info.operand[0].size != info.operand[1].size))
{
cast = true;
} else if (info.operand[1].type == OperandType::REGISTER&&
} else if (info.operand[1].type == OperandType::REGISTER &&
info.operand[1].base == Register::CL)
{
switch (info.mnemonic)
@ -537,14 +537,14 @@ void IntelInstructionFormatter::internalFormatInstruction(const InstructionInfo&
{
outputAppend(", ");
bool cast = false;
if (info.operand[1].type == OperandType::MEMORY&&
info.operand[0].size != info.operand[1].size&&
if (info.operand[1].type == OperandType::MEMORY &&
info.operand[0].size != info.operand[1].size &&
((info.operand[0].type != OperandType::REGISTER) ||
((info.operand[0].base != Register::ES)&&
(info.operand[0].base != Register::CS)&&
(info.operand[0].base != Register::SS)&&
(info.operand[0].base != Register::DS)&&
(info.operand[0].base != Register::FS)&&
((info.operand[0].base != Register::ES) &&
(info.operand[0].base != Register::CS) &&
(info.operand[0].base != Register::SS) &&
(info.operand[0].base != Register::DS) &&
(info.operand[0].base != Register::FS) &&
(info.operand[0].base != Register::GS))))
{
cast = true;
@ -560,7 +560,7 @@ void IntelInstructionFormatter::internalFormatInstruction(const InstructionInfo&
{
outputAppend(", ");
bool cast = false;
if (info.operand[2].type == OperandType::MEMORY&&
if (info.operand[2].type == OperandType::MEMORY &&
(info.operand[2].size != info.operand[1].size))
{
cast = true;

View File

@ -28,6 +28,11 @@
***************************************************************************************************/
/**
* @file
* @brief Instruction formatting classes.
*/
#ifndef _ZYDIS_INSTRUCTIONFORMATTER_HPP_
#define _ZYDIS_INSTRUCTIONFORMATTER_HPP_

View File

@ -28,6 +28,11 @@
***************************************************************************************************/
/**
* @file
* @brief The opcode table definition, mostly internal stuff.
*/
#ifndef _ZYDIS_OPCODETABLE_HPP_
#define _ZYDIS_OPCODETABLE_HPP_
@ -1607,7 +1612,7 @@ extern const char* instrMnemonicStrings[];
*/
inline OpcodeTreeNodeType GetOpcodeNodeType(OpcodeTreeNode node)
{
return static_cast<OpcodeTreeNodeType>((node >> 12)& 0x0F);
return static_cast<OpcodeTreeNodeType>((node >> 12) & 0x0F);
}
/**
@ -1617,7 +1622,7 @@ inline OpcodeTreeNodeType GetOpcodeNodeType(OpcodeTreeNode node)
*/
inline uint16_t GetOpcodeNodeValue(OpcodeTreeNode node)
{
return (node& 0x0FFF);
return (node & 0x0FFF);
}
/**
@ -1698,7 +1703,7 @@ inline OpcodeTreeNode GetOpcodeTreeChild(OpcodeTreeNode parent, uint16_t index)
inline const InstructionDefinition* GetInstructionDefinition(OpcodeTreeNode node)
{
assert(GetOpcodeNodeType(node) == OpcodeTreeNodeType::INSTRUCTION_DEFINITION);
return& instrDefinitions[node& 0x0FFF];
return& instrDefinitions[node & 0x0FFF];
}
/**
@ -1735,7 +1740,7 @@ inline uint16_t GetSimpleOperandSize(DefinedOperandSize operandSize)
*/
inline DefinedOperandSize GetComplexOperandMemSize(DefinedOperandSize operandSize)
{
return static_cast<DefinedOperandSize>(static_cast<uint8_t>(operandSize)& 0x0F);
return static_cast<DefinedOperandSize>(static_cast<uint8_t>(operandSize) & 0x0F);
}
/**
@ -1745,7 +1750,7 @@ inline DefinedOperandSize GetComplexOperandMemSize(DefinedOperandSize operandSiz
*/
inline DefinedOperandSize GetComplexOperandRegSize(DefinedOperandSize operandSize)
{
return static_cast<DefinedOperandSize>((static_cast<uint8_t>(operandSize) >> 4)& 0x0F);
return static_cast<DefinedOperandSize>((static_cast<uint8_t>(operandSize) >> 4) & 0x0F);
}
}

View File

@ -28,6 +28,11 @@
***************************************************************************************************/
/**
* @file
* @brief Classes for symbol resolving in the disassembly.
*/
#ifndef _ZYDIS_SYMBOLRESOLVER_HPP_
#define _ZYDIS_SYMBOLRESOLVER_HPP_

View File

@ -37,33 +37,33 @@ namespace Zydis
uint64_t CalcAbsoluteTarget(const InstructionInfo& info, const OperandInfo& operand)
{
assert((operand.type == OperandType::REL_IMMEDIATE) ||
((operand.type == OperandType::MEMORY)&& (operand.base == Register::RIP)));
((operand.type == OperandType::MEMORY) && (operand.base == Register::RIP)));
uint64_t truncMask = 0xFFFFFFFFFFFFFFFFull;
if (!(info.flags& IF_DISASSEMBLER_MODE_64))
if (!(info.flags & IF_DISASSEMBLER_MODE_64))
{
truncMask >>= (64 - info.operand_mode);
}
uint16_t size = operand.size;
if ((operand.type == OperandType::MEMORY)&& (operand.base == Register::RIP))
if ((operand.type == OperandType::MEMORY) && (operand.base == Register::RIP))
{
size = operand.offset;
}
switch (size)
{
case 8:
return (info.instrPointer + operand.lval.sbyte)& truncMask;
return (info.instrPointer + operand.lval.sbyte) & truncMask;
case 16:
{
uint32_t delta = operand.lval.sword& truncMask;
uint32_t delta = operand.lval.sword & truncMask;
if ((info.instrPointer + delta) > 0xFFFF)
{
return (info.instrPointer& 0xF0000) + ((info.instrPointer + delta)& 0xFFFF);
return (info.instrPointer& 0xF0000) + ((info.instrPointer + delta) & 0xFFFF);
}
return info.instrPointer + delta;
}
case 32:
return (info.instrPointer + operand.lval.sdword)& truncMask;
return (info.instrPointer + operand.lval.sdword) & truncMask;
default:
assert(0);
}

View File

@ -28,6 +28,11 @@
***************************************************************************************************/
/**
* @file
* @brief Utility functions.
*/
#ifndef _ZYDIS_UTILS_HPP_
#define _ZYDIS_UTILS_HPP_