From 11cb62c1ed07e0c07c236739f816107f3f78bdf3 Mon Sep 17 00:00:00 2001 From: flobernd Date: Sat, 1 Nov 2014 03:42:37 +0100 Subject: [PATCH 1/2] Improved formatter performance Added symbol resolver example --- Examples/PerformanceTest/Main.cpp | 42 +++-- Examples/SymbolResolver/Main.cpp | 153 +++++++++++++++++- .../VXInstructionFormatter.cpp | 83 +++++----- .../VXInstructionFormatter.h | 1 + .../VXSymbolResolver.cpp | 9 +- 5 files changed, 231 insertions(+), 57 deletions(-) diff --git a/Examples/PerformanceTest/Main.cpp b/Examples/PerformanceTest/Main.cpp index 648b182..36f1383 100644 --- a/Examples/PerformanceTest/Main.cpp +++ b/Examples/PerformanceTest/Main.cpp @@ -40,30 +40,38 @@ using namespace Disassembler; void testDecodingAndFormatting(uintptr_t baseAddress, PIMAGE_NT_HEADERS ntHeaders) { + uint32_t sizeTotal = 0; VXInstructionInfo info; VXInstructionDecoder decoder; VXIntelInstructionFormatter formatter; +#ifdef _M_X64 + decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT); +#else decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT); - PIMAGE_SECTION_HEADER sectionHeader = - reinterpret_cast( - reinterpret_cast(ntHeaders) + sizeof(IMAGE_NT_HEADERS) - + ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER)); - // Decode and format all code sections - for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) +#endif + while (sizeTotal < 1024 * 1024 * 50) { - if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) + PIMAGE_SECTION_HEADER sectionHeader = + reinterpret_cast( + reinterpret_cast(ntHeaders) + sizeof(IMAGE_NT_HEADERS) + + ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER)); + // Decode and format all code sections + for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) { - std::cout << sectionHeader->SizeOfRawData / 1024 << " KiB" << std::endl; - VXMemoryDataSource input(reinterpret_cast( - baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData); - decoder.setDataSource(&input); - decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); - while (decoder.decodeInstruction(info)) + if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) { - formatter.formatInstruction(info); + VXMemoryDataSource input(reinterpret_cast( + baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData); + decoder.setDataSource(&input); + decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); + while (decoder.decodeInstruction(info)) + { + formatter.formatInstruction(info); + } + sizeTotal += sectionHeader->SizeOfRawData; } + sectionHeader++; } - sectionHeader++; } } @@ -87,8 +95,8 @@ int _tmain(int argc, _TCHAR* argv[]) return 1; } - double pcFrequency = 0.0; - uint64_t pcStart = 0; + double pcFrequency; + uint64_t pcStart; LARGE_INTEGER li; // Start the performance counter diff --git a/Examples/SymbolResolver/Main.cpp b/Examples/SymbolResolver/Main.cpp index afe5a5f..ec71f95 100644 --- a/Examples/SymbolResolver/Main.cpp +++ b/Examples/SymbolResolver/Main.cpp @@ -30,9 +30,160 @@ **************************************************************************************************/ #include +#include +#include +#include +#include "VXDisassembler.h" +#include + +using namespace Verteron; +using namespace Disassembler; int _tmain(int argc, _TCHAR* argv[]) { - // TODO: + // Find module base in memory + void *moduleBase = GetModuleHandle(L"kernel32.dll"); + uintptr_t baseAddress = reinterpret_cast(moduleBase); + // Parse PE headers + PIMAGE_DOS_HEADER dosHeader = static_cast(moduleBase); + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + { + return 1; + } + PIMAGE_NT_HEADERS ntHeaders = + reinterpret_cast(baseAddress + dosHeader->e_lfanew); + if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) + { + return 1; + } + // Initialize disassembler + VXInstructionInfo info; + VXInstructionDecoder decoder; + VXExactSymbolResolver resolver; + VXIntelInstructionFormatter formatter; + decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT); + formatter.setSymbolResolver(&resolver); + // Initialize output stream + std::ofstream out; + out.open(".\\output.txt"); + // Find all call and jump targets + uint64_t subCount = 0; + uint64_t locCount = 0; + PIMAGE_SECTION_HEADER sectionHeader = + reinterpret_cast( + reinterpret_cast(ntHeaders) + sizeof(IMAGE_NT_HEADERS) + + ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER)); + for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) + { + if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) + { + VXMemoryDataSource input(reinterpret_cast( + baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData); + decoder.setDataSource(&input); + decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); + while (decoder.decodeInstruction(info)) + { + // Skip invalid instructions and non-relative instructions + if ((info.flags & IF_ERROR_MASK) || !(info.flags & IF_RELATIVE)) + { + continue; + } + switch (info.mnemonic) + { + case VXInstructionMnemonic::CALL: + resolver.setSymbol(VDECalcAbsoluteTarget(info, info.operand[0]), + std::string("sub_" + std::to_string(subCount)).c_str()); + subCount++; + break; + case VXInstructionMnemonic::JMP: + case VXInstructionMnemonic::JO: + case VXInstructionMnemonic::JNO: + case VXInstructionMnemonic::JB: + case VXInstructionMnemonic::JNB: + case VXInstructionMnemonic::JE: + case VXInstructionMnemonic::JNE: + case VXInstructionMnemonic::JBE: + case VXInstructionMnemonic::JA: + case VXInstructionMnemonic::JS: + case VXInstructionMnemonic::JNS: + case VXInstructionMnemonic::JP: + case VXInstructionMnemonic::JNP: + case VXInstructionMnemonic::JL: + case VXInstructionMnemonic::JGE: + case VXInstructionMnemonic::JLE: + case VXInstructionMnemonic::JG: + case VXInstructionMnemonic::JCXZ: + case VXInstructionMnemonic::JECXZ: + case VXInstructionMnemonic::JRCXZ: + resolver.setSymbol(VDECalcAbsoluteTarget(info, info.operand[0]), + std::string("loc_" + std::to_string(locCount)).c_str()); + locCount++; + break; + default: + break; + } + } + } + sectionHeader++; + } + // Add entry point symbol + resolver.setSymbol(baseAddress + ntHeaders->OptionalHeader.AddressOfEntryPoint, "EntryPoint"); + // Add exported symbols + if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > 0) + { + PIMAGE_EXPORT_DIRECTORY exports = + reinterpret_cast(reinterpret_cast(baseAddress) + + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + PDWORD address = + reinterpret_cast(reinterpret_cast(baseAddress) + + exports->AddressOfFunctions); + PDWORD name = + reinterpret_cast(reinterpret_cast(baseAddress) + + exports->AddressOfNames); + PWORD ordinal = + reinterpret_cast(reinterpret_cast(baseAddress) + + exports->AddressOfNameOrdinals); + for(unsigned int i = 0; i < exports->NumberOfNames; ++i) + { + resolver.setSymbol(baseAddress + address[ordinal[i]], + reinterpret_cast(baseAddress) + name[i]); + } + } + // Disassemble + sectionHeader = + reinterpret_cast( + reinterpret_cast(ntHeaders) + sizeof(IMAGE_NT_HEADERS) + + ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER)); + for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) + { + if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) + { + VXMemoryDataSource input(reinterpret_cast( + baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData); + decoder.setDataSource(&input); + decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); + while (decoder.decodeInstruction(info)) + { + uint64_t offset; + const char *symbol = resolver.resolveSymbol(info, info.instrAddress, offset); + if (symbol) + { + out << symbol << ": " << std::endl; + } + out << " " << std::hex << std::setw(16) << std::setfill('0') + << info.instrAddress << " "; + if (info.flags & IF_ERROR_MASK) + { + out << "db " << std::hex << std::setw(2) << std::setfill('0') + << static_cast(info.data[0]) << std::endl; + } else + { + out << formatter.formatInstruction(info) << std::endl; + } + } + } + sectionHeader++; + } + out.close(); return 0; } diff --git a/VerteronDisassemblerEngine/VXInstructionFormatter.cpp b/VerteronDisassemblerEngine/VXInstructionFormatter.cpp index 1fdf80c..2225bc9 100644 --- a/VerteronDisassemblerEngine/VXInstructionFormatter.cpp +++ b/VerteronDisassemblerEngine/VXInstructionFormatter.cpp @@ -96,13 +96,14 @@ const char* VXBaseInstructionFormatter::m_registerStrings[] = "rip" }; -void VXBaseInstructionFormatter::internalFormatInstruction(VXInstructionInfo const& info) +void VXBaseInstructionFormatter::internalFormatInstruction(const VXInstructionInfo &info) { // Nothing to do here } VXBaseInstructionFormatter::VXBaseInstructionFormatter() : m_symbolResolver(nullptr) + , m_outputStringLen(0) , m_uppercase(false) { @@ -110,6 +111,7 @@ VXBaseInstructionFormatter::VXBaseInstructionFormatter() VXBaseInstructionFormatter::VXBaseInstructionFormatter(VXBaseSymbolResolver *symbolResolver) : m_symbolResolver(symbolResolver) + , m_outputStringLen(0) , m_uppercase(false) { @@ -137,7 +139,7 @@ VXBaseInstructionFormatter::~VXBaseInstructionFormatter() void VXBaseInstructionFormatter::outputClear() { - m_outputBuffer.clear(); + m_outputStringLen = 0; } char const* VXBaseInstructionFormatter::outputString() @@ -145,65 +147,72 @@ char const* VXBaseInstructionFormatter::outputString() return &m_outputBuffer[0]; } -void VXBaseInstructionFormatter::outputAppend(char const *text) -{ + void VXBaseInstructionFormatter::outputAppend(char const *text) + { // Get the string length including the null-terminator char size_t strLen = strlen(text) + 1; - // Get the buffer capacity and size - size_t bufCap = m_outputBuffer.capacity(); + // Get the buffer size size_t bufLen = m_outputBuffer.size(); - // Decrease the offset by one, to exclude already existing null-terminator chars in the + // Decrease the offset by one, to exclude already existing null-terminator chars in the // output buffer - size_t offset = (bufLen) ? bufLen - 1 : 0; + size_t offset = (m_outputStringLen) ? m_outputStringLen - 1 : 0; // Resize capacity of the output buffer on demand and add some extra space to improve the - // performance - if (bufCap <= (bufLen + strLen)) + // performance + if (bufLen <= (m_outputStringLen + strLen)) { - m_outputBuffer.reserve(bufCap + strLen + 256); + m_outputBuffer.resize(bufLen + strLen + 512); } - // Append the text - m_outputBuffer.resize(offset + strLen); + // Write the text to the output buffer memcpy(&m_outputBuffer[offset], text, strLen); + // Increase the string length + m_outputStringLen = offset + strLen; // Convert to uppercase if (m_uppercase) { - for (size_t i = offset; i < m_outputBuffer.size() - 1; ++i) + for (size_t i = offset; i < m_outputStringLen - 1; ++i) { m_outputBuffer[i] = toupper(m_outputBuffer[i]); } } -} + } -void VXBaseInstructionFormatter::outputAppendFormatted(char const *format, ...) -{ + void VXBaseInstructionFormatter::outputAppendFormatted(char const *format, ...) + { va_list arguments; va_start(arguments, format); - // Get the string length including the null-terminator char - size_t strLen = _vscprintf(format, arguments) + 1; - // Get the buffer capacity and size - size_t bufCap = m_outputBuffer.capacity(); + // Get the buffer size size_t bufLen = m_outputBuffer.size(); - // Decrease the offset by one, to exclude already existing null-terminator chars in the + // Decrease the offset by one, to exclude already existing null-terminator chars in the // output buffer - size_t offset = (bufLen) ? bufLen - 1 : 0; - if (strLen > 1) + size_t offset = (m_outputStringLen) ? m_outputStringLen - 1 : 0; + // Resize the output buffer on demand and add some extra space to improve the performance + if ((bufLen - m_outputStringLen) < 256) { - // Resize capacity of the output buffer on demand and add some extra space to improve the - // performance - if (bufCap < (bufLen + strLen)) + bufLen = bufLen + 512; + m_outputBuffer.resize(bufLen); + } + int strLen = 0; + do + { + // If the formatted text did not fit in the output buffer, resize it, and try again + if (strLen < 0) { - m_outputBuffer.reserve(bufCap + strLen + 256); + m_outputBuffer.resize(bufLen + 512); + return outputAppendFormatted(format, arguments); } - // Append the formatted text - m_outputBuffer.resize(offset + strLen); - vsnprintf_s(&m_outputBuffer[offset], strLen, strLen, format, arguments); - // Convert to uppercase - if (m_uppercase) + // Write the formatted text to the output buffer + assert((bufLen - offset) > 0); + strLen = + vsnprintf_s(&m_outputBuffer[offset], bufLen - offset, _TRUNCATE, format, arguments); + } while (strLen < 0); + // Increase the string length + m_outputStringLen = offset + strLen + 1; + // Convert to uppercase + if (m_uppercase) + { + for (size_t i = offset; i < m_outputStringLen - 1; ++i) { - for (size_t i = offset; i < m_outputBuffer.size() - 1; ++i) - { - m_outputBuffer[i] = toupper(m_outputBuffer[i]); - } + m_outputBuffer[i] = toupper(m_outputBuffer[i]); } } va_end(arguments); diff --git a/VerteronDisassemblerEngine/VXInstructionFormatter.h b/VerteronDisassemblerEngine/VXInstructionFormatter.h index 149d419..50cd69e 100644 --- a/VerteronDisassemblerEngine/VXInstructionFormatter.h +++ b/VerteronDisassemblerEngine/VXInstructionFormatter.h @@ -50,6 +50,7 @@ private: static const char *m_registerStrings[]; VXBaseSymbolResolver *m_symbolResolver; std::vector m_outputBuffer; + size_t m_outputStringLen; bool m_uppercase; protected: /** diff --git a/VerteronDisassemblerEngine/VXSymbolResolver.cpp b/VerteronDisassemblerEngine/VXSymbolResolver.cpp index d729a5c..51fac85 100644 --- a/VerteronDisassemblerEngine/VXSymbolResolver.cpp +++ b/VerteronDisassemblerEngine/VXSymbolResolver.cpp @@ -59,13 +59,18 @@ const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t &offset) { std::unordered_map::const_iterator iterator = m_symbolMap.find(address); - return (iterator == m_symbolMap.end()) ? nullptr : iterator->second.c_str(); + if (iterator != m_symbolMap.end()) + { + offset = 0; + return iterator->second.c_str(); + } + return nullptr; } bool VXExactSymbolResolver::containsSymbol(uint64_t address) const { std::unordered_map::const_iterator iterator = m_symbolMap.find(address); - return (iterator == m_symbolMap.end()) ? false : true; + return (iterator != m_symbolMap.end()); } void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name) From 319fe310e6b0e42cffbf8505e8f4fa03952f1af9 Mon Sep 17 00:00:00 2001 From: flobernd Date: Mon, 3 Nov 2014 15:15:48 +0100 Subject: [PATCH 2/2] Removed the "Disassembler" namespace Added experimental Clang compiler support --- Examples/PerformanceTest/Main.cpp | 92 +------------- Examples/SimpleDemo/Main.cpp | 1 - Examples/SymbolResolver/Main.cpp | 7 +- README.md | 36 +++++- VerteronDisassemblerEngine/VXDisassembler.h | 1 - .../VXDisassemblerTypes.h | 5 - .../VXDisassemblerUtils.cpp | 6 +- .../VXDisassemblerUtils.h | 5 - .../VXInstructionDecoder.cpp | 5 - .../VXInstructionDecoder.h | 9 +- .../VXInstructionFormatter.cpp | 66 ++++++++-- .../VXInstructionFormatter.h | 84 ++++++++++++- VerteronDisassemblerEngine/VXOpcodeTable.cpp | 35 +++--- VerteronDisassemblerEngine/VXOpcodeTable.h | 5 - .../VXSymbolResolver.cpp | 93 -------------- VerteronDisassemblerEngine/VXSymbolResolver.h | 119 ------------------ .../VerteronDisassemblerEngine.vcxproj | 2 - ...VerteronDisassemblerEngine.vcxproj.filters | 6 +- 18 files changed, 197 insertions(+), 380 deletions(-) delete mode 100644 VerteronDisassemblerEngine/VXSymbolResolver.cpp delete mode 100644 VerteronDisassemblerEngine/VXSymbolResolver.h diff --git a/Examples/PerformanceTest/Main.cpp b/Examples/PerformanceTest/Main.cpp index 36f1383..afe5a5f 100644 --- a/Examples/PerformanceTest/Main.cpp +++ b/Examples/PerformanceTest/Main.cpp @@ -30,99 +30,9 @@ **************************************************************************************************/ #include -#include -#include -#include "VXDisassembler.h" -#include - -using namespace Verteron; -using namespace Disassembler; - -void testDecodingAndFormatting(uintptr_t baseAddress, PIMAGE_NT_HEADERS ntHeaders) -{ - uint32_t sizeTotal = 0; - VXInstructionInfo info; - VXInstructionDecoder decoder; - VXIntelInstructionFormatter formatter; -#ifdef _M_X64 - decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT); -#else - decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT); -#endif - while (sizeTotal < 1024 * 1024 * 50) - { - PIMAGE_SECTION_HEADER sectionHeader = - reinterpret_cast( - reinterpret_cast(ntHeaders) + sizeof(IMAGE_NT_HEADERS) - + ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER)); - // Decode and format all code sections - for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) - { - if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) - { - VXMemoryDataSource input(reinterpret_cast( - baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData); - decoder.setDataSource(&input); - decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); - while (decoder.decodeInstruction(info)) - { - formatter.formatInstruction(info); - } - sizeTotal += sectionHeader->SizeOfRawData; - } - sectionHeader++; - } - } -} int _tmain(int argc, _TCHAR* argv[]) { - - // Find kernel32.dll in memory - void *ntdllBase = GetModuleHandle(L"kernel32.dll"); - PIMAGE_DOS_HEADER dosHeader = static_cast(ntdllBase); - if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) - { - std::cout << "Error: kernel32.dll is corrupted."; - return 1; - } - PIMAGE_NT_HEADERS ntHeaders = - reinterpret_cast( - reinterpret_cast(dosHeader) + dosHeader->e_lfanew); - if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) - { - std::cout << "Error: kernel32.dll is corrupted."; - return 1; - } - - double pcFrequency; - uint64_t pcStart; - LARGE_INTEGER li; - - // Start the performance counter - if (!QueryPerformanceFrequency(&li)) - { - std::cout << "Error: QueryPerformanceFrequency failed."; - return 1; - } - pcFrequency = static_cast(li.QuadPart) / 1000.0; - if (!QueryPerformanceCounter(&li)) - { - std::cout << "Error: QueryPerformanceCounter failed."; - return 1; - } - pcStart = li.QuadPart; - // Perform decoding test - testDecodingAndFormatting(reinterpret_cast(ntdllBase), ntHeaders); - // Stop the performance counter - if (!QueryPerformanceCounter(&li)) - { - std::cout << "Error: QueryPerformanceCounter failed."; - return 1; - } - std::cout << "Time: " << static_cast(li.QuadPart - pcStart) / pcFrequency - << std::endl; - - std::cin.get(); + // TODO: return 0; } diff --git a/Examples/SimpleDemo/Main.cpp b/Examples/SimpleDemo/Main.cpp index d14a84b..3a60d40 100644 --- a/Examples/SimpleDemo/Main.cpp +++ b/Examples/SimpleDemo/Main.cpp @@ -36,7 +36,6 @@ #include "VXDisassembler.h" using namespace Verteron; -using namespace Disassembler; int _tmain(int argc, _TCHAR* argv[]) { diff --git a/Examples/SymbolResolver/Main.cpp b/Examples/SymbolResolver/Main.cpp index ec71f95..ee8e299 100644 --- a/Examples/SymbolResolver/Main.cpp +++ b/Examples/SymbolResolver/Main.cpp @@ -37,7 +37,6 @@ #include using namespace Verteron; -using namespace Disassembler; int _tmain(int argc, _TCHAR* argv[]) { @@ -61,7 +60,11 @@ int _tmain(int argc, _TCHAR* argv[]) VXInstructionDecoder decoder; VXExactSymbolResolver resolver; VXIntelInstructionFormatter formatter; +#ifdef _M_X64 decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT); +#else + decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT); +#endif formatter.setSymbolResolver(&resolver); // Initialize output stream std::ofstream out; @@ -83,7 +86,7 @@ int _tmain(int argc, _TCHAR* argv[]) decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress); while (decoder.decodeInstruction(info)) { - // Skip invalid instructions and non-relative instructions + // Skip invalid and non-relative instructions if ((info.flags & IF_ERROR_MASK) || !(info.flags & IF_RELATIVE)) { continue; diff --git a/README.md b/README.md index 8fc597f..1d0c629 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,43 @@ Fast and lightweight x86/x86-64 disassembler library. - SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES, - AMD-V, INTEL-VMX, SMX - Optimized for high performance - - Decoding and formatting of 50MiB takes about 1 second on a Intel Core i7 3930k @ 3.2GHz CPU -- Very small overhead compared to other common disassembler libraries - - Only 44.00 KiB (64 bit: 47.00 KiB) for the decoder and 62.00 KiB (64 bit: 69.50 KiB) with the optional formatting functionality +- 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 +## Quick Example ## + +The following example program uses VDE to disassemble a given memory buffer and prints the output to the console. + +```C++ +#include +#include +#include +#include "VXDisassembler.h" + +using namespace Verteron; + +int _tmain(int argc, _TCHAR* argv[]) +{ + uint8_t data[] = + { + 0x90, 0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3 + }; + VXMemoryDataSource input(&data[0], sizeof(data)); + VXInstructionInfo info; + VXInstructionDecoder decoder; + decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT); + decoder.setDataSource(&input); + decoder.setInstructionPointer(0); + VXIntelInstructionFormatter formatter; + while (decoder.decodeInstruction(info)) + { + std::cout << formatter.formatInstruction(info) << std::endl; + } +} +``` + ## Compilation ## - While VDE supports other compilers in theory, compilation has not been tested with any compiler other than MSVC12 (Visual Studio 2013) diff --git a/VerteronDisassemblerEngine/VXDisassembler.h b/VerteronDisassemblerEngine/VXDisassembler.h index 7720a6c..271d8d9 100644 --- a/VerteronDisassemblerEngine/VXDisassembler.h +++ b/VerteronDisassemblerEngine/VXDisassembler.h @@ -34,5 +34,4 @@ #include "VXDisassemblerTypes.h" #include "VXInstructionDecoder.h" #include "VXInstructionFormatter.h" -#include "VXSymbolResolver.h" #include "VXDisassemblerUtils.h" diff --git a/VerteronDisassemblerEngine/VXDisassemblerTypes.h b/VerteronDisassemblerEngine/VXDisassemblerTypes.h index 71af477..cf0b902 100644 --- a/VerteronDisassemblerEngine/VXDisassemblerTypes.h +++ b/VerteronDisassemblerEngine/VXDisassemblerTypes.h @@ -37,9 +37,6 @@ namespace Verteron { -namespace Disassembler -{ - /** * @brief Values that represent additional flags of a decoded instruction. */ @@ -530,5 +527,3 @@ struct VXInstructionInfo }; } - -} diff --git a/VerteronDisassemblerEngine/VXDisassemblerUtils.cpp b/VerteronDisassemblerEngine/VXDisassemblerUtils.cpp index 31ee21b..8e7fa65 100644 --- a/VerteronDisassemblerEngine/VXDisassemblerUtils.cpp +++ b/VerteronDisassemblerEngine/VXDisassemblerUtils.cpp @@ -30,12 +30,10 @@ **************************************************************************************************/ #include "VXDisassemblerUtils.h" +#include namespace Verteron { - -namespace Disassembler -{ uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInfo &operand) { @@ -74,5 +72,3 @@ uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInf } } - -} diff --git a/VerteronDisassemblerEngine/VXDisassemblerUtils.h b/VerteronDisassemblerEngine/VXDisassemblerUtils.h index b2c788d..e62d9b1 100644 --- a/VerteronDisassemblerEngine/VXDisassemblerUtils.h +++ b/VerteronDisassemblerEngine/VXDisassemblerUtils.h @@ -37,9 +37,6 @@ namespace Verteron { -namespace Disassembler -{ - /** * @brief Calculates the absolute target address of a relative instruction operand. * @param info The instruction info. @@ -49,5 +46,3 @@ namespace Disassembler uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInfo &operand); } - -} diff --git a/VerteronDisassemblerEngine/VXInstructionDecoder.cpp b/VerteronDisassemblerEngine/VXInstructionDecoder.cpp index c950f39..1534af1 100644 --- a/VerteronDisassemblerEngine/VXInstructionDecoder.cpp +++ b/VerteronDisassemblerEngine/VXInstructionDecoder.cpp @@ -35,9 +35,6 @@ namespace Verteron { -namespace Disassembler -{ - bool VXInstructionDecoder::decodeRegisterOperand(VXInstructionInfo &info, VXOperandInfo &operand, RegisterClass registerClass, uint8_t registerId, VXDefinedOperandSize operandSize) const { @@ -1304,5 +1301,3 @@ DecodeError: } } - -} diff --git a/VerteronDisassemblerEngine/VXInstructionDecoder.h b/VerteronDisassemblerEngine/VXInstructionDecoder.h index dcfe804..ba5cf54 100644 --- a/VerteronDisassemblerEngine/VXInstructionDecoder.h +++ b/VerteronDisassemblerEngine/VXInstructionDecoder.h @@ -38,9 +38,6 @@ namespace Verteron { -namespace Disassembler -{ - /////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -195,7 +192,7 @@ inline uint8_t VXBaseDataSource::inputCurrent() const /////////////////////////////////////////////////////////////////////////////////////////////////// /** - * @brief Implements a memory buffer based data source. + * @brief A memory-buffer based data source for the @c VXInstructionDecoder class. */ class VXMemoryDataSource : public VXBaseDataSource { @@ -275,7 +272,7 @@ inline bool VXMemoryDataSource::setPosition(uint64_t position) /////////////////////////////////////////////////////////////////////////////////////////////////// /** - * @brief Implements a stream based data source. + * @brief A stream based data source for the @c VXInstructionDecoder class. */ class VXStreamDataSource : public VXBaseDataSource { @@ -719,5 +716,3 @@ inline void VXInstructionDecoder::setInstructionPointer(uint64_t instructionPoin /////////////////////////////////////////////////////////////////////////////////////////////////// } - -} diff --git a/VerteronDisassemblerEngine/VXInstructionFormatter.cpp b/VerteronDisassemblerEngine/VXInstructionFormatter.cpp index 2225bc9..94df4ec 100644 --- a/VerteronDisassemblerEngine/VXInstructionFormatter.cpp +++ b/VerteronDisassemblerEngine/VXInstructionFormatter.cpp @@ -37,9 +37,21 @@ namespace Verteron { -namespace Disassembler +/////////////////////////////////////////////////////////////////////////////////////////////////// + +VXBaseSymbolResolver::~VXBaseSymbolResolver() { +} + +const char* VXBaseSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address, + uint64_t &offset) +{ + return nullptr; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + const char* VXBaseInstructionFormatter::m_registerStrings[] = { /* 8 bit general purpose registers */ @@ -104,7 +116,7 @@ void VXBaseInstructionFormatter::internalFormatInstruction(const VXInstructionIn VXBaseInstructionFormatter::VXBaseInstructionFormatter() : m_symbolResolver(nullptr) , m_outputStringLen(0) - , m_uppercase(false) + , m_outputUppercase(false) { } @@ -112,7 +124,7 @@ VXBaseInstructionFormatter::VXBaseInstructionFormatter() VXBaseInstructionFormatter::VXBaseInstructionFormatter(VXBaseSymbolResolver *symbolResolver) : m_symbolResolver(symbolResolver) , m_outputStringLen(0) - , m_uppercase(false) + , m_outputUppercase(false) { } @@ -167,7 +179,7 @@ char const* VXBaseInstructionFormatter::outputString() // Increase the string length m_outputStringLen = offset + strLen; // Convert to uppercase - if (m_uppercase) + if (m_outputUppercase) { for (size_t i = offset; i < m_outputStringLen - 1; ++i) { @@ -208,7 +220,7 @@ char const* VXBaseInstructionFormatter::outputString() // Increase the string length m_outputStringLen = offset + strLen + 1; // Convert to uppercase - if (m_uppercase) + if (m_outputUppercase) { for (size_t i = offset; i < m_outputStringLen - 1; ++i) { @@ -318,7 +330,7 @@ void VXBaseInstructionFormatter::outputAppendDisplacement(const VXInstructionInf const VXOperandInfo &operand) { assert(operand.offset > 0); - if (operand.base == VXRegister::NONE && operand.index == VXRegister::NONE) + if ((operand.base == VXRegister::NONE) && (operand.index == VXRegister::NONE)) { // Assume the displacement value is unsigned assert(operand.scale == 0); @@ -598,6 +610,46 @@ VXIntelInstructionFormatter::~VXIntelInstructionFormatter() } -} +/////////////////////////////////////////////////////////////////////////////////////////////////// + +VXExactSymbolResolver::~VXExactSymbolResolver() +{ + +} + +const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address, + uint64_t &offset) +{ + std::unordered_map::const_iterator iterator = m_symbolMap.find(address); + if (iterator != m_symbolMap.end()) + { + offset = 0; + return iterator->second.c_str(); + } + return nullptr; +} + +bool VXExactSymbolResolver::containsSymbol(uint64_t address) const +{ + std::unordered_map::const_iterator iterator = m_symbolMap.find(address); + return (iterator != m_symbolMap.end()); +} + +void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name) +{ + m_symbolMap[address].assign(name); +} + +void VXExactSymbolResolver::removeSymbol(uint64_t address) +{ + m_symbolMap.erase(address); +} + +void VXExactSymbolResolver::clear() +{ + m_symbolMap.clear(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// } diff --git a/VerteronDisassemblerEngine/VXInstructionFormatter.h b/VerteronDisassemblerEngine/VXInstructionFormatter.h index 50cd69e..f24b0a3 100644 --- a/VerteronDisassemblerEngine/VXInstructionFormatter.h +++ b/VerteronDisassemblerEngine/VXInstructionFormatter.h @@ -32,14 +32,38 @@ #pragma once #include +#include #include "VXDisassemblerTypes.h" -#include "VXSymbolResolver.h" namespace Verteron { -namespace Disassembler +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * @brief Base class for all symbol resolver implementations. + */ +class VXBaseSymbolResolver { +public: + /** + * @brief Destructor. + */ + virtual ~VXBaseSymbolResolver(); +public: + /** + * @brief Resolves a symbol. + * @param info The instruction info. + * @param address The address. + * @param offset Reference to an unsigned 64 bit integer that receives an offset + * relative to the base address of the symbol. + * @return The name of the symbol, if the symbol was found, @c NULL if not. + */ + virtual const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address, + uint64_t &offset); +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// /** * @brief Base class for all instruction formatter implementations. @@ -51,7 +75,7 @@ private: VXBaseSymbolResolver *m_symbolResolver; std::vector m_outputBuffer; size_t m_outputStringLen; - bool m_uppercase; + bool m_outputUppercase; protected: /** * @brief Clears the output string buffer. @@ -164,7 +188,7 @@ public: inline void VXBaseInstructionFormatter::outputSetUppercase(bool uppercase) { - m_uppercase = uppercase; + m_outputUppercase = uppercase; } inline char const* VXBaseInstructionFormatter::registerToString(VXRegister reg) const @@ -240,6 +264,56 @@ public: ~VXIntelInstructionFormatter() override; }; -} +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * @brief Simple symbol resolver that only matches exact addresses. + */ +class VXExactSymbolResolver : public VXBaseSymbolResolver +{ +private: + std::unordered_map m_symbolMap; +public: + /** + * @brief Destructor. + */ + ~VXExactSymbolResolver() override; +public: + /** + * @brief Resolves a symbol. + * @param info The instruction info. + * @param address The address. + * @param offset Reference to an unsigned 64 bit integer that receives an offset + * relative to the base address of the symbol. + * @return The name of the symbol, if the symbol was found, @c NULL if not. + */ + const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address, + uint64_t &offset) override; +public: + /** + * @brief Query if the given address is a known symbol. + * @param address The address. + * @return True if the address is known, false if not. + */ + bool containsSymbol(uint64_t address) const; + /** + * @brief Adds or changes a symbol. + * @param address The address. + * @param name The symbol name. + */ + void setSymbol(uint64_t address, const char* name); + /** + * @brief Removes the symbol described by address. This will invalidate all char pointers + * to the specific symbol name. + * @param address The address. + */ + void removeSymbol(uint64_t address); + /** + * @brief Clears the symbol tree. + */ + void clear(); +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// } diff --git a/VerteronDisassemblerEngine/VXOpcodeTable.cpp b/VerteronDisassemblerEngine/VXOpcodeTable.cpp index 9ad8ebc..c6d5778 100644 --- a/VerteronDisassemblerEngine/VXOpcodeTable.cpp +++ b/VerteronDisassemblerEngine/VXOpcodeTable.cpp @@ -34,16 +34,13 @@ namespace Verteron { -namespace Disassembler -{ - namespace Internal { #define INVALID 0 #define NODE(type, n) (static_cast(type) << 12 | (n)) -static const VXOpcodeTreeNode optreeTable[][256] = +const VXOpcodeTreeNode optreeTable[][256] = { { /* 00 */ 0x0015, @@ -2627,7 +2624,7 @@ static const VXOpcodeTreeNode optreeTable[][256] = }, }; -static const VXOpcodeTreeNode optreeModrmMod[][2] = +const VXOpcodeTreeNode optreeModrmMod[][2] = { { /* 00 */ NODE(VXOpcodeTreeNodeType::MANDATORY, 0x0001), @@ -2747,7 +2744,7 @@ static const VXOpcodeTreeNode optreeModrmMod[][2] = }, }; -static const VXOpcodeTreeNode optreeModrmReg[][8] = +const VXOpcodeTreeNode optreeModrmReg[][8] = { { /* 00 */ 0x0531, @@ -3231,7 +3228,7 @@ static const VXOpcodeTreeNode optreeModrmReg[][8] = }, }; -static const VXOpcodeTreeNode optreeModrmRm[][8] = +const VXOpcodeTreeNode optreeModrmRm[][8] = { { /* 00 */ INVALID, @@ -3375,7 +3372,7 @@ static const VXOpcodeTreeNode optreeModrmRm[][8] = }, }; -static const VXOpcodeTreeNode optreeMandatory[][4] = +const VXOpcodeTreeNode optreeMandatory[][4] = { { /* 00 */ NODE(VXOpcodeTreeNodeType::MODRM_REG, 0x0000), @@ -5293,7 +5290,7 @@ static const VXOpcodeTreeNode optreeMandatory[][4] = }, }; -static const VXOpcodeTreeNode optreeX87[][64] = +const VXOpcodeTreeNode optreeX87[][64] = { { /* 00 */ 0x00BC, @@ -5825,7 +5822,7 @@ static const VXOpcodeTreeNode optreeX87[][64] = }, }; -static const VXOpcodeTreeNode optreeAddressSize[][3] = +const VXOpcodeTreeNode optreeAddressSize[][3] = { { /* 00 */ 0x02CD, @@ -5834,7 +5831,7 @@ static const VXOpcodeTreeNode optreeAddressSize[][3] = }, }; -static const VXOpcodeTreeNode optreeOperandSize[][3] = +const VXOpcodeTreeNode optreeOperandSize[][3] = { { /* 00 */ 0x03E0, @@ -5958,7 +5955,7 @@ static const VXOpcodeTreeNode optreeOperandSize[][3] = }, }; -static const VXOpcodeTreeNode optreeMode[][2] = +const VXOpcodeTreeNode optreeMode[][2] = { { /* 00 */ 0x04AA, @@ -6142,7 +6139,7 @@ static const VXOpcodeTreeNode optreeMode[][2] = }, }; -static const VXOpcodeTreeNode optreeVendor[][2] = +const VXOpcodeTreeNode optreeVendor[][2] = { { /* 00 */ INVALID, @@ -6246,7 +6243,7 @@ static const VXOpcodeTreeNode optreeVendor[][2] = }, }; -static const VXOpcodeTreeNode optree3dnow[][256] = +const VXOpcodeTreeNode optree3dnow[][256] = { { /* 00 */ INVALID, @@ -6508,7 +6505,7 @@ static const VXOpcodeTreeNode optree3dnow[][256] = }, }; -static const VXOpcodeTreeNode optreeVex[][16] = +const VXOpcodeTreeNode optreeVex[][16] = { { /* 00 */ NODE(VXOpcodeTreeNodeType::MODE, 0x0024), @@ -6548,7 +6545,7 @@ static const VXOpcodeTreeNode optreeVex[][16] = }, }; -static const VXOpcodeTreeNode optreeVexW[][2] = +const VXOpcodeTreeNode optreeVexW[][2] = { { /* 00 */ 0x061D, @@ -6652,7 +6649,7 @@ static const VXOpcodeTreeNode optreeVexW[][2] = }, }; -static const VXOpcodeTreeNode optreeVexL[][2] = +const VXOpcodeTreeNode optreeVexL[][2] = { { /* 00 */ 0x069C, @@ -6865,7 +6862,7 @@ static const VXOpcodeTreeNode optreeVexL[][2] = #define OPI_sIb { VXDefinedOperandType::sI, VXDefinedOperandSize::B } #define OPI_sIz { VXDefinedOperandType::sI, VXDefinedOperandSize::Z } -static const VXInstructionDefinition instrDefinitions[] = +const VXInstructionDefinition instrDefinitions[] = { /* 000 */ { VXInstructionMnemonic::INVALID, { OPI_NONE, OPI_NONE, OPI_NONE, OPI_NONE }, 0 }, /* 001 */ { VXInstructionMnemonic::AAA, { OPI_NONE, OPI_NONE, OPI_NONE, OPI_NONE }, 0 }, @@ -9656,5 +9653,3 @@ const char* instrMnemonicStrings[] = } } - -} diff --git a/VerteronDisassemblerEngine/VXOpcodeTable.h b/VerteronDisassemblerEngine/VXOpcodeTable.h index ea95715..9824d37 100644 --- a/VerteronDisassemblerEngine/VXOpcodeTable.h +++ b/VerteronDisassemblerEngine/VXOpcodeTable.h @@ -37,9 +37,6 @@ namespace Verteron { -namespace Disassembler -{ - /** * @brief Values that represent an instruction mnemonic. */ @@ -1754,5 +1751,3 @@ inline VXDefinedOperandSize VDEGetComplexOperandRegSize(VXDefinedOperandSize ope } } - -} diff --git a/VerteronDisassemblerEngine/VXSymbolResolver.cpp b/VerteronDisassemblerEngine/VXSymbolResolver.cpp deleted file mode 100644 index 51fac85..0000000 --- a/VerteronDisassemblerEngine/VXSymbolResolver.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************************************** - - Verteron Disassembler Engine - Version 1.0 - - Remarks : Freeware, Copyright must be included - - Original Author : Florian Bernd - Modifications : - - Last change : 29. October 2014 - - * 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 "VXSymbolResolver.h" - -namespace Verteron -{ - -namespace Disassembler -{ - -VXBaseSymbolResolver::~VXBaseSymbolResolver() -{ - -} - -const char* VXBaseSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address, - uint64_t &offset) -{ - return nullptr; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -VXExactSymbolResolver::~VXExactSymbolResolver() -{ - -} - -const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address, - uint64_t &offset) -{ - std::unordered_map::const_iterator iterator = m_symbolMap.find(address); - if (iterator != m_symbolMap.end()) - { - offset = 0; - return iterator->second.c_str(); - } - return nullptr; -} - -bool VXExactSymbolResolver::containsSymbol(uint64_t address) const -{ - std::unordered_map::const_iterator iterator = m_symbolMap.find(address); - return (iterator != m_symbolMap.end()); -} - -void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name) -{ - m_symbolMap[address].assign(name); -} - -void VXExactSymbolResolver::removeSymbol(uint64_t address) -{ - m_symbolMap.erase(address); -} - -void VXExactSymbolResolver::clear() -{ - m_symbolMap.clear(); -} - -} - -} diff --git a/VerteronDisassemblerEngine/VXSymbolResolver.h b/VerteronDisassemblerEngine/VXSymbolResolver.h deleted file mode 100644 index 8336984..0000000 --- a/VerteronDisassemblerEngine/VXSymbolResolver.h +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************************************************************** - - Verteron Disassembler Engine - Version 1.0 - - Remarks : Freeware, Copyright must be included - - Original Author : Florian Bernd - Modifications : - - Last change : 29. October 2014 - - * 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. - -**************************************************************************************************/ -#pragma once - -#include -#include -#include "VXDisassemblerTypes.h" - -namespace Verteron -{ - -namespace Disassembler -{ - -/** - * @brief Base class for all symbol resolver implementations. - */ -class VXBaseSymbolResolver -{ -public: - /** - * @brief Destructor. - */ - virtual ~VXBaseSymbolResolver(); -public: - /** - * @brief Resolves a symbol. - * @param info The instruction info. - * @param address The address. - * @param offset Reference to an unsigned 64 bit integer that receives an offset - * relative to the base address of the symbol. - * @return The name of the symbol, if the symbol was found, @c NULL if not. - */ - virtual const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address, - uint64_t &offset); -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * @brief Simple symbol resolver that only matches exact addresses. - */ -class VXExactSymbolResolver : public VXBaseSymbolResolver -{ -private: - std::unordered_map m_symbolMap; -public: - /** - * @brief Destructor. - */ - ~VXExactSymbolResolver() override; -public: - /** - * @brief Resolves a symbol. - * @param info The instruction info. - * @param address The address. - * @param offset Reference to an unsigned 64 bit integer that receives an offset - * relative to the base address of the symbol. - * @return The name of the symbol, if the symbol was found, @c NULL if not. - */ - const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address, - uint64_t &offset) override; -public: - /** - * @brief Query if the given address is a known symbol. - * @param address The address. - * @return True if the address is known, false if not. - */ - bool containsSymbol(uint64_t address) const; - /** - * @brief Adds or changes a symbol. - * @param address The address. - * @param name The symbol name. - */ - void setSymbol(uint64_t address, const char* name); - /** - * @brief Removes the symbol described by address. This will invalidate all char pointers - * to the specific symbol name. - * @param address The address. - */ - void removeSymbol(uint64_t address); - /** - * @brief Clears the symbol tree. - */ - void clear(); -}; - -} - -} diff --git a/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj b/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj index 6af81a9..0628199 100644 --- a/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj +++ b/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj @@ -25,14 +25,12 @@ - - {F5C6F0A7-F75D-42BD-A8AB-A2D1D5F67099} diff --git a/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj.filters b/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj.filters index 57ea373..e106092 100644 --- a/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj.filters +++ b/VerteronDisassemblerEngine/VerteronDisassemblerEngine.vcxproj.filters @@ -3,17 +3,15 @@ + - - + - - \ No newline at end of file