From 58383a9020249d25ed3c0ea94753253f9ce1610c Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 16 Nov 2018 09:55:46 +0100 Subject: [PATCH 01/33] VB header parsing --- include/retdec/fileformat/fftypes.h | 1 + .../fileformat/file_format/file_format.h | 1 + .../fileformat/file_format/pe/pe_format.h | 1 + .../visual_basic_header/visual_basic_header.h | 150 ++++++++++++++++++ src/fileformat/CMakeLists.txt | 1 + src/fileformat/file_format/file_format.cpp | 2 + src/fileformat/file_format/pe/pe_format.cpp | 91 +++++++++++ .../visual_basic_header.cpp | 40 +++++ 8 files changed, 287 insertions(+) create mode 100644 include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h create mode 100644 src/fileformat/types/visual_basic_header/visual_basic_header.cpp diff --git a/include/retdec/fileformat/fftypes.h b/include/retdec/fileformat/fftypes.h index 3ea50776c..d4455f4ea 100644 --- a/include/retdec/fileformat/fftypes.h +++ b/include/retdec/fileformat/fftypes.h @@ -24,6 +24,7 @@ #include "retdec/fileformat/types/resource_table/resource_icon.h" #include "retdec/fileformat/types/resource_table/resource_icon_group.h" #include "retdec/fileformat/types/rich_header/rich_header.h" +#include "retdec/fileformat/types/visual_basic_header/visual_basic_header.h" #include "retdec/fileformat/types/sec_seg/elf_section.h" #include "retdec/fileformat/types/sec_seg/elf_segment.h" #include "retdec/fileformat/types/sec_seg/macho_section.h" diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index 4b2b7efd6..9417fc960 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -81,6 +81,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils ResourceTable *resourceTable; ///< table of resources ResourceTree *resourceTree; ///< structure of resource tree RichHeader *richHeader; ///< rich header + VisualBasicHeader *visualBasicHeader; ///< visual basic header PdbInfo *pdbInfo; ///< information about related PDB debug file CertificateTable *certificateTable; ///< table of certificates ElfCoreInfo *elfCoreInfo; ///< information about core file structures diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index 013a432e4..17a9ff330 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -61,6 +61,7 @@ class PeFormat : public FileFormat std::size_t getRichHeaderOffset(const std::string &plainFile); bool getResourceNodes(std::vector &nodes, std::vector &levels); void loadRichHeader(); + void loadVisualBasicHeader(); void loadSections(); void loadSymbols(); void loadImports(); diff --git a/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h b/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h new file mode 100644 index 000000000..c244fe39c --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h @@ -0,0 +1,150 @@ +/** + * @file include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h + * @brief Class for rich header. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_HEADER_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_HEADER_H + +#include + +namespace retdec { +namespace fileformat { + +struct VBHeader +{ + std::uint8_t signature[4]; ///< "VB5!" signature + std::uint16_t runtimeBuild; ///< Runtime flag + std::uint8_t languageDLL[14]; ///< Language DLL + std::uint8_t backupLanguageDLL[14]; ///< Backup language DLL + std::uint16_t runtimeDLLVersion; ///< Version of the runtime DLL + std::uint32_t languageID; ///< Application language + std::uint32_t backupLanguageID; ///< Used with backup language DLL + std::uint32_t aSubMain; ///< Procedure to start after the application is launched + std::uint32_t aProjectInfo; ///< Pointer to ProjectInfo + std::uint32_t fMDLIntObjs; + std::uint32_t fMDLIntObjs2; + std::uint32_t threadFlags; ///< Thread flags + std::uint32_t threadCount; ///< Number of threads (themeaning of this field is unclear as VB doesn't let you make multithreaded application) + std::uint16_t formCount; ///< Number of forms in this application + std::uint16_t externalComponentCount; ///< Number of external OCX components + std::uint32_t thunkCount; + std::uint32_t aGUITable; ///< Pointer to GUITable + std::uint32_t aExternalComponentTable; ///< Pointer to ExternalComponentTable + std::uint32_t aComRegisterData; ///< Pointer to ComRegisterData + std::uint32_t oProjectExename; ///< Pointer to the string containing EXE filename + std::uint32_t oProjectTitle; ///< Pointer to the string containing project's title + std::uint32_t oHelpFile; ///< Pointer to the string containing name of the Help file + std::uint32_t oProjectName; ///< Pointer to the string containing project's name + + VBHeader() + { + + } + + std::size_t headerSize() + { + return + sizeof(signature) + sizeof(runtimeBuild) + sizeof(languageDLL) + + sizeof(backupLanguageDLL) + sizeof(runtimeDLLVersion) + sizeof(languageID) + + sizeof(backupLanguageID) + sizeof(aSubMain) + sizeof(aProjectInfo) + + sizeof(fMDLIntObjs) + sizeof(fMDLIntObjs2) + sizeof(threadFlags) + + sizeof(threadCount) + sizeof(formCount) + sizeof(externalComponentCount) + + sizeof(thunkCount) + sizeof(aGUITable) + sizeof(aExternalComponentTable) + + sizeof(aComRegisterData) + sizeof(oProjectExename) + sizeof(oProjectTitle) + + sizeof(oHelpFile) + sizeof(oProjectName); + } + + void dump(std::ostream &out) + { + out << "signature:\t\t"; + for (std::size_t i = 0; i < sizeof(signature); i++) + { + out << signature[i]; + } + out << "\n"; + + out << "runtimeBuild:\t\t" << runtimeBuild << "\n"; + + out << "languageDLL:\t\t"; + for (std::size_t i = 0; i < sizeof(languageDLL); i++) + { + if (!languageDLL[i]) + { + break; + } + out << languageDLL[i]; + } + out << "\n"; + + out << "backupLanguageDLL:\t"; + for (std::size_t i = 0; i < sizeof(backupLanguageDLL); i++) + { + if (!backupLanguageDLL[i]) + { + break; + } + out << backupLanguageDLL[i]; + } + out << "\n"; + + out << "runtimeDLLVersion:\t" << runtimeDLLVersion << "\n"; + out << "languageID:\t\t" << languageID << "\n"; + out << "backupLanguageID:\t" << backupLanguageID << "\n"; + out << "aSubMain:\t\t" << std::hex << aSubMain << "\n"; + out << "aProjectInfo:\t\t" << aProjectInfo << std::dec << "\n"; + out << "fMDLIntObjs:\t\t" << fMDLIntObjs << "\n"; + out << "fMDLIntObjs2:\t\t" << fMDLIntObjs2 << "\n"; + out << "threadFlags:\t\t" << threadFlags << "\n"; + out << "threadCount:\t\t" << threadCount << "\n"; + out << "formCount:\t\t" << formCount << "\n"; + out << "externalComponentCount:\t" << externalComponentCount << "\n"; + out << "thunkCount:\t\t" << thunkCount << "\n"; + out << "aGUITable:\t\t" << std::hex << aGUITable << "\n"; + out << "aExternalComponentTable:" << aExternalComponentTable << "\n"; + out << "aComRegisterData:\t" << aComRegisterData << "\n"; + out << "oProjectExename:\t" << oProjectExename << "\n"; + out << "oProjectTitle:\t\t" << oProjectTitle << "\n"; + out << "oHelpFile:\t\t" << oHelpFile << "\n"; + out << "oProjectName:\t\t" << oProjectName << std::dec << "\n"; + } +}; + +/** + * Visual basic header + */ +class VisualBasicHeader +{ + private: + std::size_t headerAddress; ///< Header address + + public: + VisualBasicHeader(); + ~VisualBasicHeader(); + + /// @name Getters + /// @{ + + /// @} + + /// @name Setters + /// @{ + void setHeaderAddress(std::size_t address); + /// @} + + /// @name Iterators + /// @{ + + /// @} + + /// @name Other methods + /// @{ + + /// @} +}; + +} // namespace fileformat +} // namespace retdec + +#endif diff --git a/src/fileformat/CMakeLists.txt b/src/fileformat/CMakeLists.txt index 4313460b4..47ea1e112 100644 --- a/src/fileformat/CMakeLists.txt +++ b/src/fileformat/CMakeLists.txt @@ -21,6 +21,7 @@ set(FILEFORMAT_SOURCES types/symbol_table/elf_symbol.cpp types/rich_header/rich_header.cpp types/rich_header/linker_info.cpp + types/visual_basic_header/visual_basic_header.cpp types/import_table/import.cpp types/import_table/import_table.cpp types/import_table/pe_import.cpp diff --git a/src/fileformat/file_format/file_format.cpp b/src/fileformat/file_format/file_format.cpp index fe50fbeaf..e3644f230 100644 --- a/src/fileformat/file_format/file_format.cpp +++ b/src/fileformat/file_format/file_format.cpp @@ -185,6 +185,7 @@ void FileFormat::init() resourceTable = nullptr; resourceTree = nullptr; richHeader = nullptr; + visualBasicHeader = nullptr; pdbInfo = nullptr; certificateTable = nullptr; elfCoreInfo = nullptr; @@ -230,6 +231,7 @@ void FileFormat::clear() delete resourceTable; delete resourceTree; delete richHeader; + delete visualBasicHeader; delete pdbInfo; delete certificateTable; delete elfCoreInfo; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 6ac958a3f..1c40b098d 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -425,6 +425,7 @@ void PeFormat::initStructures() loadResources(); loadCertificates(); loadDotnetHeaders(); + loadVisualBasicHeader(); computeSectionTableHashes(); loadStrings(); } @@ -622,6 +623,96 @@ void PeFormat::loadRichHeader() richHeader->setBytes(header.getDecryptedHeaderBytes()); } +/** + * Load visual basic header + */ +void PeFormat::loadVisualBasicHeader() +{ + unsigned long long version = 0; + unsigned long long baseAddress = 0; + std::size_t vbHeaderAddress = 0; + std::size_t vbHeaderOffset = 0; + struct VBHeader vbh; + + if (!isVisualBasic(version)) + { + return; + } + + // first instruction is expected to be PUSH (0x68 b0 b1 b2 b3) + std::vectorbytes; + if (!getEpBytes(bytes, 5) || bytes.size() != 5 || bytes[0] != 0x68) + { + return; + } + + if (!getImageBaseAddress(baseAddress)) + { + return; + } + + vbHeaderAddress = bytes[4] << 24 | bytes[3] << 16 | bytes[2] << 8 | bytes[1]; + vbHeaderOffset = vbHeaderAddress - baseAddress; + + if (!getBytes(bytes, vbHeaderOffset, vbh.headerSize()) || bytes.size() != vbh.headerSize()) + { + return; + } + + std::size_t offset = 0; + + std::memcpy(&vbh.signature, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.signature)); offset += sizeof(vbh.signature); + vbh.runtimeBuild = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeBuild); + std::memcpy(&vbh.languageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); + std::memcpy(&vbh.backupLanguageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); + vbh.runtimeDLLVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeDLLVersion); + vbh.languageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.languageID); + vbh.backupLanguageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.backupLanguageID); + vbh.aSubMain = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aSubMain); + vbh.aProjectInfo = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aProjectInfo); + vbh.threadFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadFlags); + vbh.threadCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadCount); + vbh.formCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.formCount); + vbh.externalComponentCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalComponentCount); + vbh.thunkCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.thunkCount); + vbh.aGUITable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aGUITable); + vbh.aExternalComponentTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aExternalComponentTable); + vbh.aComRegisterData = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aComRegisterData); + vbh.oProjectExename = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectExename); + vbh.oProjectTitle = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectTitle); + vbh.oHelpFile = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oHelpFile); + vbh.oProjectName = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectName); + + if (!isLittleEndian()) + { + vbh.runtimeBuild = byteSwap16(vbh.runtimeBuild); + vbh.runtimeDLLVersion = byteSwap16(vbh.runtimeDLLVersion); + vbh.languageID = byteSwap32(vbh.languageID); + vbh.backupLanguageID = byteSwap32(vbh.backupLanguageID); + vbh.aSubMain = byteSwap32(vbh.aSubMain); + vbh.aProjectInfo = byteSwap32(vbh.aProjectInfo); + vbh.threadFlags = byteSwap32(vbh.threadFlags); + vbh.threadCount = byteSwap32(vbh.threadCount); + vbh.formCount = byteSwap16(vbh.formCount); + vbh.externalComponentCount = byteSwap16(vbh.externalComponentCount); + vbh.thunkCount = byteSwap32(vbh.thunkCount); + vbh.aGUITable = byteSwap32(vbh.aGUITable); + vbh.aExternalComponentTable = byteSwap32(vbh.aExternalComponentTable); + vbh.aComRegisterData = byteSwap32(vbh.aComRegisterData); + vbh.oProjectExename = byteSwap32(vbh.oProjectExename); + vbh.oProjectTitle = byteSwap32(vbh.oProjectTitle); + vbh.oHelpFile = byteSwap32(vbh.oHelpFile); + vbh.oProjectName = byteSwap32(vbh.oProjectName); + } + + std::cout << "KUBO " << std::to_string(vbh.headerSize()) << "\n"; + vbh.dump(std::cout); + + + visualBasicHeader = new VisualBasicHeader(); + visualBasicHeader->setHeaderAddress(vbHeaderAddress); +} + /** * Load information about sections */ diff --git a/src/fileformat/types/visual_basic_header/visual_basic_header.cpp b/src/fileformat/types/visual_basic_header/visual_basic_header.cpp new file mode 100644 index 000000000..1ab496b8a --- /dev/null +++ b/src/fileformat/types/visual_basic_header/visual_basic_header.cpp @@ -0,0 +1,40 @@ +/** + * @file src/fileformat/types/visual_basic_header/visual_basic_header.cpp + * @brief Class for rich header. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include + +#include "retdec/fileformat/types/visual_basic_header/visual_basic_header.h" + +namespace retdec { +namespace fileformat { + +/** + * Constructor + */ +VisualBasicHeader::VisualBasicHeader() +{ + +} + +/** + * Destructor + */ +VisualBasicHeader::~VisualBasicHeader() +{ + +} + +/** + * Set header address + * @param address Header address to be set + */ +void VisualBasicHeader::setHeaderAddress(std::size_t address) +{ + headerAddress = address; +} + +} // namespace fileformat +} // namespace retdec From 023b90bba1b93f0eb000ec0afd165a918c9b5763 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 16 Nov 2018 20:41:43 +0100 Subject: [PATCH 02/33] project info header parsing I. --- .../fileformat/file_format/pe/pe_format.h | 3 +- .../visual_basic_header/visual_basic_header.h | 9 +- .../visual_basic_project_info.h | 97 ++++++++++++++ src/fileformat/CMakeLists.txt | 1 + src/fileformat/file_format/pe/pe_format.cpp | 121 ++++++++++++++---- .../visual_basic_header.cpp | 2 +- .../visual_basic_project_info.cpp | 31 +++++ 7 files changed, 230 insertions(+), 34 deletions(-) create mode 100644 include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h create mode 100644 src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index 17a9ff330..ef22f53e8 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -61,7 +61,8 @@ class PeFormat : public FileFormat std::size_t getRichHeaderOffset(const std::string &plainFile); bool getResourceNodes(std::vector &nodes, std::vector &levels); void loadRichHeader(); - void loadVisualBasicHeader(); + bool loadVisualBasicHeader(); + bool loadVisualBasicProjectInfo(std::size_t structureOffset); void loadSections(); void loadSymbols(); void loadImports(); diff --git a/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h b/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h index c244fe39c..1e26aee2c 100644 --- a/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h +++ b/include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h @@ -1,6 +1,6 @@ /** * @file include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h - * @brief Class for rich header. + * @brief Class for visual basic header. * @copyright (c) 2017 Avast Software, licensed under the MIT license */ @@ -23,13 +23,13 @@ struct VBHeader std::uint32_t backupLanguageID; ///< Used with backup language DLL std::uint32_t aSubMain; ///< Procedure to start after the application is launched std::uint32_t aProjectInfo; ///< Pointer to ProjectInfo - std::uint32_t fMDLIntObjs; - std::uint32_t fMDLIntObjs2; + std::uint32_t fMDLIntObjs; ///< VB controll flags for IDs < 32 + std::uint32_t fMDLIntObjs2; ///< VB controll flags for IDs > 32 std::uint32_t threadFlags; ///< Thread flags std::uint32_t threadCount; ///< Number of threads (themeaning of this field is unclear as VB doesn't let you make multithreaded application) std::uint16_t formCount; ///< Number of forms in this application std::uint16_t externalComponentCount; ///< Number of external OCX components - std::uint32_t thunkCount; + std::uint32_t thunkCount; ///< Number of thunks to create std::uint32_t aGUITable; ///< Pointer to GUITable std::uint32_t aExternalComponentTable; ///< Pointer to ExternalComponentTable std::uint32_t aComRegisterData; ///< Pointer to ComRegisterData @@ -108,6 +108,7 @@ struct VBHeader out << "oProjectTitle:\t\t" << oProjectTitle << "\n"; out << "oHelpFile:\t\t" << oHelpFile << "\n"; out << "oProjectName:\t\t" << oProjectName << std::dec << "\n"; + out << "\n"; } }; diff --git a/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h b/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h new file mode 100644 index 000000000..468d0c448 --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h @@ -0,0 +1,97 @@ +/** + * @file include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h + * @brief Class for visual basic project info. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_PROJECT_INFO_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_PROJECT_INFO_H + +#include + +namespace retdec { +namespace fileformat { + +struct VBProjInfo +{ + std::uint32_t dwVersion; ///< 5.00 in Hex (0x1F4), version + std::uint32_t lpObjectTable; ///< pointer to object table + std::uint32_t dwNull; ///< unused value after compilation + std::uint32_t lpCodeStart; ///< pointer to start of code + std::uint32_t lpCodeEnd; ///< pointer to end of code + std::uint32_t dwDataSize; ///< size of VB object structures + std::uint32_t lpThreadSpace; ///< pointer to pointer to thread object + std::uint32_t lpVbaSeh; ///< pointer to VBA exception handler + std::uint32_t lpNativeCode; ///< pointer to .DATA section + uint8_t szPathInformation[528]; ///< path and id string, bytes; unsigned long long version = 0; unsigned long long baseAddress = 0; std::size_t vbHeaderAddress = 0; std::size_t vbHeaderOffset = 0; + std::size_t vbProjectInfoOffset = 0; + std::size_t offset = 0; struct VBHeader vbh; if (!isVisualBasic(version)) { - return; + return false; } - // first instruction is expected to be PUSH (0x68 b0 b1 b2 b3) - std::vectorbytes; + // first instruction is expected to be PUSH (0x68 ) if (!getEpBytes(bytes, 5) || bytes.size() != 5 || bytes[0] != 0x68) { - return; + return false; } if (!getImageBaseAddress(baseAddress)) { - return; + return false; } vbHeaderAddress = bytes[4] << 24 | bytes[3] << 16 | bytes[2] << 8 | bytes[1]; @@ -656,32 +662,30 @@ void PeFormat::loadVisualBasicHeader() if (!getBytes(bytes, vbHeaderOffset, vbh.headerSize()) || bytes.size() != vbh.headerSize()) { - return; + return false; } - std::size_t offset = 0; - std::memcpy(&vbh.signature, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.signature)); offset += sizeof(vbh.signature); - vbh.runtimeBuild = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeBuild); + vbh.runtimeBuild = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeBuild); std::memcpy(&vbh.languageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); std::memcpy(&vbh.backupLanguageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); - vbh.runtimeDLLVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeDLLVersion); - vbh.languageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.languageID); - vbh.backupLanguageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.backupLanguageID); - vbh.aSubMain = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aSubMain); - vbh.aProjectInfo = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aProjectInfo); - vbh.threadFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadFlags); - vbh.threadCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadCount); - vbh.formCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.formCount); - vbh.externalComponentCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalComponentCount); - vbh.thunkCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.thunkCount); - vbh.aGUITable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aGUITable); - vbh.aExternalComponentTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aExternalComponentTable); - vbh.aComRegisterData = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aComRegisterData); - vbh.oProjectExename = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectExename); - vbh.oProjectTitle = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectTitle); - vbh.oHelpFile = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oHelpFile); - vbh.oProjectName = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectName); + vbh.runtimeDLLVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeDLLVersion); + vbh.languageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.languageID); + vbh.backupLanguageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.backupLanguageID); + vbh.aSubMain = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aSubMain); + vbh.aProjectInfo = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aProjectInfo); + vbh.threadFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadFlags); + vbh.threadCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadCount); + vbh.formCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.formCount); + vbh.externalComponentCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalComponentCount); + vbh.thunkCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.thunkCount); + vbh.aGUITable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aGUITable); + vbh.aExternalComponentTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aExternalComponentTable); + vbh.aComRegisterData = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aComRegisterData); + vbh.oProjectExename = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectExename); + vbh.oProjectTitle = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectTitle); + vbh.oHelpFile = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oHelpFile); + vbh.oProjectName = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectName); if (!isLittleEndian()) { @@ -705,12 +709,73 @@ void PeFormat::loadVisualBasicHeader() vbh.oProjectName = byteSwap32(vbh.oProjectName); } - std::cout << "KUBO " << std::to_string(vbh.headerSize()) << "\n"; + // TODO check VB header magic + + std::cout << "[KUBO] VB header <<<<<<<<<<< " << std::to_string(vbh.headerSize()) << "\n"; vbh.dump(std::cout); + vbProjectInfoOffset = vbh.aProjectInfo - baseAddress; + + loadVisualBasicProjectInfo(vbProjectInfoOffset); + visualBasicHeader = new VisualBasicHeader(); visualBasicHeader->setHeaderAddress(vbHeaderAddress); + + + // TODO iclude VB headrov to /fftypes and delete here + + return true; +} + +/** + * Load visual basic project info + * @param structureOffset Offset in file where the structure starts + * @return @c true if project info was successfuly loaded, @c false otherwise + */ +bool PeFormat::loadVisualBasicProjectInfo(std::size_t structureOffset) +{ + std::vector bytes; + std::size_t offset = 0; + struct VBProjInfo vbpi; + + if (!getBytes(bytes, structureOffset, vbpi.headerSize()) || bytes.size() != vbpi.headerSize()) + { + return false; + } + + vbpi.dwVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwVersion); + vbpi.lpObjectTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpObjectTable); + vbpi.dwNull = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwNull); + vbpi.lpCodeStart = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpCodeStart); + vbpi.lpCodeEnd = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpCodeEnd); + vbpi.dwDataSize = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwDataSize); + vbpi.lpThreadSpace = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpThreadSpace); + vbpi.lpVbaSeh = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpVbaSeh); + vbpi.lpNativeCode = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpNativeCode); + std::memcpy(&vbpi.szPathInformation, reinterpret_cast(&bytes.data()[offset]), sizeof(vbpi.szPathInformation)); offset += sizeof(vbpi.szPathInformation); + vbpi.lpExternalTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpExternalTable); + vbpi.dwExternalCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwExternalCount); + + if (!isLittleEndian()) + { + vbpi.dwVersion = byteSwap32(vbpi.dwVersion); + vbpi.lpObjectTable = byteSwap32(vbpi.lpObjectTable); + vbpi.dwNull = byteSwap32(vbpi.dwNull); + vbpi.lpCodeStart = byteSwap32(vbpi.lpCodeStart); + vbpi.lpCodeEnd = byteSwap32(vbpi.lpCodeEnd); + vbpi.dwDataSize = byteSwap32(vbpi.dwDataSize); + vbpi.lpThreadSpace = byteSwap32(vbpi.lpThreadSpace); + vbpi.lpVbaSeh = byteSwap32(vbpi.lpVbaSeh); + vbpi.lpNativeCode = byteSwap32(vbpi.lpNativeCode); + vbpi.lpExternalTable = byteSwap32(vbpi.lpExternalTable); + vbpi.dwExternalCount = byteSwap32(vbpi.dwExternalCount); + } + + std::cout << "[KUBO] VB project info <<<<<<<<<<< " << std::to_string(vbpi.headerSize()) << "\n"; + vbpi.dump(std::cout); + + return true; } /** diff --git a/src/fileformat/types/visual_basic_header/visual_basic_header.cpp b/src/fileformat/types/visual_basic_header/visual_basic_header.cpp index 1ab496b8a..f7d99bc2d 100644 --- a/src/fileformat/types/visual_basic_header/visual_basic_header.cpp +++ b/src/fileformat/types/visual_basic_header/visual_basic_header.cpp @@ -1,6 +1,6 @@ /** * @file src/fileformat/types/visual_basic_header/visual_basic_header.cpp - * @brief Class for rich header. + * @brief Class for visual basic header. * @copyright (c) 2017 Avast Software, licensed under the MIT license */ diff --git a/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp b/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp new file mode 100644 index 000000000..55fe97fa0 --- /dev/null +++ b/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp @@ -0,0 +1,31 @@ +/** + * @file src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp + * @brief Class for visual basic project info. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include + +#include "retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h" + +namespace retdec { +namespace fileformat { + +/** + * Constructor + */ +VisualBasicProjectInfo::VisualBasicProjectInfo() +{ + +} + +/** + * Destructor + */ +VisualBasicProjectInfo::~VisualBasicProjectInfo() +{ + +} + +} // namespace fileformat +} // namespace retdec From 0b37a1a476e7b04a0a25912eed9ca1828db79489 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 13 Dec 2018 00:13:01 +0100 Subject: [PATCH 03/33] fileinfo wrapper --- src/fileinfo/CMakeLists.txt | 1 + .../file_information/file_information.h | 1 + .../file_information_types.h | 1 + .../visual_basic_info.cpp | 224 ++++++++++++++++++ .../visual_basic_info.h | 60 +++++ 5 files changed, 287 insertions(+) create mode 100644 src/fileinfo/file_information/file_information_types/visual_basic_info.cpp create mode 100644 src/fileinfo/file_information/file_information_types/visual_basic_info.h diff --git a/src/fileinfo/CMakeLists.txt b/src/fileinfo/CMakeLists.txt index a66f232df..ae4c4acf9 100644 --- a/src/fileinfo/CMakeLists.txt +++ b/src/fileinfo/CMakeLists.txt @@ -30,6 +30,7 @@ set(FILEINFO_SOURCES file_information/file_information_types/resource_table/resource.cpp file_information/file_information_types/resource_table/resource_table.cpp file_information/file_information_types/rich_header.cpp + file_information/file_information_types/visual_basic_info.cpp file_information/file_information_types/special_information.cpp file_information/file_information_types/strings.cpp file_information/file_information_types/symbol_table/symbol.cpp diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 8fbda47ad..9a610f648 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -39,6 +39,7 @@ class FileInformation std::string compactManifest; ///< compact version of XML manifest FileHeader header; ///< file header RichHeader richHeader; ///< rich header + VisualBasicInfo visualBasicInfo; ///< visual basic information PdbInfo pdbInfo; ///< information about related PDB file ImportTable importTable; ///< information about imports ExportTable exportTable; ///< information about exports diff --git a/src/fileinfo/file_information/file_information_types/file_information_types.h b/src/fileinfo/file_information/file_information_types/file_information_types.h index 084fec203..d826e3d97 100644 --- a/src/fileinfo/file_information/file_information_types/file_information_types.h +++ b/src/fileinfo/file_information/file_information_types/file_information_types.h @@ -24,6 +24,7 @@ #include "fileinfo/file_information/file_information_types/relocation_table/relocation_table.h" #include "fileinfo/file_information/file_information_types/resource_table/resource_table.h" #include "fileinfo/file_information/file_information_types/rich_header.h" +#include "fileinfo/file_information/file_information_types/visual_basic_info.h" #include "fileinfo/file_information/file_information_types/strings.h" #include "fileinfo/file_information/file_information_types/symbol_table/symbol_table.h" diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp new file mode 100644 index 000000000..f5e40b8c5 --- /dev/null +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -0,0 +1,224 @@ +/** + * @file src/fileinfo/file_information/file_information_types/visual_basic_info.cpp + * @brief Rich header. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "fileinfo/file_information/file_information_types/visual_basic_info.h" +#include "fileinfo/file_information/file_information_types/type_conversions.h" + +using namespace retdec::fileformat; + +namespace fileinfo { + +/** + * Constructor + */ +VisualBasicInfo::VisualBasicInfo() : visualBasicInfo(nullptr) +{ + +} + +/** + * Destructor + */ +VisualBasicInfo::~VisualBasicInfo() +{ + +} + +/** + * Get language DLL + * @return Visual basic language DLL + */ +std::string VisualBasicInfo::getLanguageDLL() const +{ + return visualBasicInfo ? visualBasicInfo->getLanguageDLL() : ""; +} + +/** + * Get backup language DLL + * @return Visual basic backup language DLL + */ +std::string VisualBasicInfo::getBackupLanguageDLL() const +{ + return visualBasicInfo ? visualBasicInfo->getBackupLanguageDLL() : ""; +} + +/** + * Get project exe name + * @return Visual basic project exe name + */ +std::string VisualBasicInfo::getProjectExeName() const +{ + return visualBasicInfo ? visualBasicInfo->getProjectExeName() : ""; +} + +/** + * Get project description + * @return Visual basic project description + */ +std::string VisualBasicInfo::getProjectDescription() const +{ + return visualBasicInfo ? visualBasicInfo->getProjectDescription() : ""; +} + +/** + * Get project help file + * @return Visual basic project help file + */ +std::string VisualBasicInfo::getProjectHelpFile() const +{ + return visualBasicInfo ? visualBasicInfo->getProjectHelpFile() : ""; +} + +/** + * Get project name + * @return Visual basic project name + */ +std::string VisualBasicInfo::getProjectName() const +{ + return visualBasicInfo ? visualBasicInfo->getProjectName() : ""; +} + +/** + * Get language DLL primary LCID + * @return Visual basic language DLL primary LCID as string + */ +std::string VisualBasicInfo::getLanguageDLLPrimaryLCIDStr() const +{ + std::uint32_t lcid; + if (!visualBasicInfo || !visualBasicInfo->getLanguageDLLPrimaryLCID(lcid)) + { + return ""; + } + return getNumberAsString(lcid); +} + +/** + * Get language DLL secondary LCID + * @return Visual basic language DLL secondary LCID as string + */ +std::string VisualBasicInfo::getLanguageDLLSecondaryLCIDStr() const +{ + std::uint32_t lcid; + if (!visualBasicInfo || !visualBasicInfo->getLanguageDLLSecondaryLCID(lcid)) + { + return ""; + } + return getNumberAsString(lcid); +} + +/** + * Get project path + * @return Visual basic project path + */ +std::string VisualBasicInfo::getProjectPath() const +{ + return visualBasicInfo ? visualBasicInfo->getProjectPath() : ""; +} + +/** + * Get project primary LCID + * @return Visual basic project primary LCID as string + */ +std::string VisualBasicInfo::getProjectPrimaryLCIDStr() const +{ + std::uint32_t lcid; + if (!visualBasicInfo || !visualBasicInfo->getProjectPrimaryLCID(lcid)) + { + return ""; + } + return getNumberAsString(lcid); +} + +/** + * Get project secondary LCID + * @return Visual basic project secondary LCID as string + */ +std::string VisualBasicInfo::getProjectSecondaryLCIDStr() const +{ + std::uint32_t lcid; + if (!visualBasicInfo || !visualBasicInfo->getProjectSecondaryLCID(lcid)) + { + return ""; + } + return getNumberAsString(lcid); +} + +/** + * Get object + * @param position Index of selected visual basic object (indexed from 0) + * @return Visual basic object + */ +const retdec::fileformat::VisualBasicObject *VisualBasicInfo::getObject(std::size_t position) const +{ + return visualBasicInfo ? visualBasicInfo->getObject(position) : nullptr; +} + +/** + * Get extern + * @param position Index of selected visual basic extern (indexed from 0) + * @return Visual basic extern + */ +const retdec::fileformat::VisualBasicExtern *VisualBasicInfo::getExtern(std::size_t position) const +{ + return visualBasicInfo ? visualBasicInfo->getExtern(position) : nullptr; +} + +/** + * Get number of objects + * @return Visual basic number of objects + */ +std::size_t VisualBasicInfo::getNumberOfObjects() const +{ + return visualBasicInfo ? visualBasicInfo->getNumberOfObjects() : 0; +} + +/** + * Get number of externs + * @return Visual basic number of externs + */ +std::size_t VisualBasicInfo::getNumberOfExterns() const +{ + return visualBasicInfo ? visualBasicInfo->getNumberOfExterns() : 0; +} + +// /** +// * Get typeLib CLSID +// * @return Visual basic typeLib CLSID as string +// */ +// std::string VisualBasicInfo::getTypeLibCLSIDStr() const +// { +// std::uint32_t clsid; +// if (!visualBasicInfo || !visualBasicInfo->getTypeLibCLSID(clsid)) +// { +// return ""; +// } +// return getNumberAsString(clsid); +// } + +/** + * Get typeLib LCID + * @return Visual basic typeLib LCID as string + */ +std::string VisualBasicInfo::getTypeLibLCIDStr() const +{ + std::uint32_t lcid; + if (!visualBasicInfo || !visualBasicInfo->getTypeLibLCID(lcid)) + { + return ""; + } + return getNumberAsString(lcid); +} + +/** + * Set visual basic information + * @param vbInfo Instance of class with original information about visual basic + */ +void VisualBasicInfo::setInfo(const retdec::fileformat::VisualBasicInfo *vbInfo) +{ + visualBasicInfo = vbInfo; +} + +} // namespace fileinfo diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h new file mode 100644 index 000000000..72c8ba7f6 --- /dev/null +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -0,0 +1,60 @@ +/** + * @file src/fileinfo/file_information/file_information_types/visual_basic_info.h + * @brief Visual basic information. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef FILEINFO_FILE_INFORMATION_FILE_INFORMATION_TYPES_VISUAL_BASIC_INFO_H +#define FILEINFO_FILE_INFORMATION_FILE_INFORMATION_TYPES_VISUAL_BASIC_INFO_H + +#include "retdec/fileformat/types/visual_basic/visual_basic_info.h" +#include "retdec/fileformat/types/visual_basic/visual_basic_object.h" +#include "retdec/fileformat/types/visual_basic/visual_basic_extern.h" + +namespace fileinfo { + +/** + * Class for rich header + */ +class VisualBasicInfo +{ + private: + const retdec::fileformat::VisualBasicInfo *visualBasicInfo; + public: + VisualBasicInfo(); + ~VisualBasicInfo(); + + /// @name Getters + /// @{ + std::string getLanguageDLL() const; + std::string getBackupLanguageDLL() const; + std::string getProjectExeName() const; + std::string getProjectDescription() const; + std::string getProjectHelpFile() const; + std::string getProjectName() const; + std::string getLanguageDLLPrimaryLCIDStr() const; + std::string getLanguageDLLSecondaryLCIDStr() const; + std::string getProjectPath() const; + std::string getProjectPrimaryLCIDStr() const; + std::string getProjectSecondaryLCIDStr() const; + const retdec::fileformat::VisualBasicObject *getObject(std::size_t position) const; + const retdec::fileformat::VisualBasicExtern *getExtern(std::size_t position) const; + std::size_t getNumberOfObjects() const; + std::size_t getNumberOfExterns() const; + // std::string getTypeLibCLSIDStr() const; + std::string getTypeLibLCIDStr() const; + /// @} + + /// @name Setters + /// @{ + void setInfo(const retdec::fileformat::VisualBasicInfo *vbInfo); + /// @} + + /// @name Other methods + /// @{ + /// @} +}; + +} // namespace fileinfo + +#endif From 9ab607abb024c03df918ecd14d4825f2a9a58181 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 13 Dec 2018 00:18:03 +0100 Subject: [PATCH 04/33] fileinfo wrapper --- include/retdec/fileformat/fftypes.h | 2 +- .../fileformat/file_format/file_format.h | 2 +- .../fileformat/file_format/pe/pe_format.h | 13 +- .../types/visual_basic/visual_basic_extern.h | 43 ++ .../types/visual_basic/visual_basic_info.h | 116 ++++ .../types/visual_basic/visual_basic_object.h | 49 ++ .../visual_basic/visual_basic_structures.h | 366 +++++++++++ .../visual_basic_header/visual_basic_header.h | 151 ----- .../visual_basic_project_info.h | 97 --- src/fileformat/CMakeLists.txt | 5 +- src/fileformat/file_format/file_format.cpp | 4 +- src/fileformat/file_format/pe/pe_format.cpp | 570 +++++++++++++++--- .../visual_basic/visual_basic_extern.cpp | 66 ++ .../types/visual_basic/visual_basic_info.cpp | 411 +++++++++++++ .../visual_basic/visual_basic_object.cpp | 76 +++ .../visual_basic_header.cpp | 40 -- .../visual_basic_project_info.cpp | 31 - 17 files changed, 1644 insertions(+), 398 deletions(-) create mode 100644 include/retdec/fileformat/types/visual_basic/visual_basic_extern.h create mode 100644 include/retdec/fileformat/types/visual_basic/visual_basic_info.h create mode 100644 include/retdec/fileformat/types/visual_basic/visual_basic_object.h create mode 100644 include/retdec/fileformat/types/visual_basic/visual_basic_structures.h delete mode 100644 include/retdec/fileformat/types/visual_basic_header/visual_basic_header.h delete mode 100644 include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h create mode 100644 src/fileformat/types/visual_basic/visual_basic_extern.cpp create mode 100644 src/fileformat/types/visual_basic/visual_basic_info.cpp create mode 100644 src/fileformat/types/visual_basic/visual_basic_object.cpp delete mode 100644 src/fileformat/types/visual_basic_header/visual_basic_header.cpp delete mode 100644 src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp diff --git a/include/retdec/fileformat/fftypes.h b/include/retdec/fileformat/fftypes.h index d4455f4ea..fa4be530e 100644 --- a/include/retdec/fileformat/fftypes.h +++ b/include/retdec/fileformat/fftypes.h @@ -24,7 +24,7 @@ #include "retdec/fileformat/types/resource_table/resource_icon.h" #include "retdec/fileformat/types/resource_table/resource_icon_group.h" #include "retdec/fileformat/types/rich_header/rich_header.h" -#include "retdec/fileformat/types/visual_basic_header/visual_basic_header.h" +#include "retdec/fileformat/types/visual_basic/visual_basic_info.h" #include "retdec/fileformat/types/sec_seg/elf_section.h" #include "retdec/fileformat/types/sec_seg/elf_segment.h" #include "retdec/fileformat/types/sec_seg/macho_section.h" diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index 9417fc960..66457d260 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -81,7 +81,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils ResourceTable *resourceTable; ///< table of resources ResourceTree *resourceTree; ///< structure of resource tree RichHeader *richHeader; ///< rich header - VisualBasicHeader *visualBasicHeader; ///< visual basic header + VisualBasicInfo *visualBasicInfo; ///< visual basic header information PdbInfo *pdbInfo; ///< information about related PDB debug file CertificateTable *certificateTable; ///< table of certificates ElfCoreInfo *elfCoreInfo; ///< information about core file structures diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index ef22f53e8..9c529fdde 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -61,12 +61,11 @@ class PeFormat : public FileFormat std::size_t getRichHeaderOffset(const std::string &plainFile); bool getResourceNodes(std::vector &nodes, std::vector &levels); void loadRichHeader(); - bool loadVisualBasicHeader(); - bool loadVisualBasicProjectInfo(std::size_t structureOffset); void loadSections(); void loadSymbols(); void loadImports(); void loadExports(); + void loadVisualBasicHeader(); void loadPdbInfo(); void loadResourceNodes(std::vector &nodes, const std::vector &levels); void loadResources(); @@ -95,6 +94,16 @@ class PeFormat : public FileFormat std::uint64_t detectPossibleMetadataHeaderAddress() const; void computeTypeRefHashes(); /// @} + /// @name Visual Basic methods + /// @{ + bool parseVisualBasicProjectInfo(std::size_t structureOffset, std::size_t baseAddress); + bool parseVisualBasicExternTable(std::size_t structureOffset, std::size_t baseAddress, + std::size_t nEntries); + bool parseVisualBasicObjectTable(std::size_t structureOffset, std::size_t baseAddress); + bool parseVisualBasicObjects(std::size_t structureOffset, std::size_t baseAddress, + std::size_t nObjects); + bool parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress); + /// @} protected: PeLib::PeFile *file; ///< PeLib representation of PE file PeLib::PeHeaderT<32> *peHeader32; ///< header of 32-bit PE file diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_extern.h b/include/retdec/fileformat/types/visual_basic/visual_basic_extern.h new file mode 100644 index 000000000..ff8bcf193 --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_extern.h @@ -0,0 +1,43 @@ +/** + * @file include/retdec/fileformat/types/visual_basic/visual_basic_extern.h + * @brief Class for visual basic extern. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_EXTERN_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_EXTERN_H + +#include + +namespace retdec { +namespace fileformat { + +/** + * Class for visual basic information + */ +class VisualBasicExtern +{ + private: + std::string moduleName; + std::string apiName; + public: + VisualBasicExtern(); + ~VisualBasicExtern(); + + /// @name Getters + /// @{ + const std::string &getModuleName() const; + const std::string &getApiName() const; + /// @} + + /// @name Setters + /// @{ + void setModuleName(const std::string &mName); + void setApiName(const std::string &aName); + /// @} +}; + +} // namespace fileformat +} // namespace retdec + +#endif diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h new file mode 100644 index 000000000..453a0bfc6 --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -0,0 +1,116 @@ +/** + * @file include/retdec/fileformat/types/visual_basic/visual_basic_info.h + * @brief Class for visual basic information. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_INFO_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_INFO_H + +#include +#include +#include + +#include "retdec/fileformat/types/visual_basic/visual_basic_object.h" +#include "retdec/fileformat/types/visual_basic/visual_basic_extern.h" + +namespace retdec { +namespace fileformat { + +/** + * Class for visual basic information + */ +class VisualBasicInfo +{ + private: + // VB Header + std::string languageDLL; + std::string backupLanguageDLL; + std::string projectExeName; + std::string projectDescription; + std::string projectHelpFile; + std::string projectName; + std::uint32_t languageDLLPrimaryLCID; + std::uint32_t languageDLLSecondaryLCID; + + // VB Proj Info + std::string projectPath; + + // VB Object table + // object table GUID TODO DATA TYPE + std::uint32_t projectPrimaryLCID; + std::uint32_t projectSecondaryLCID; + std::vector> objects; + + // VB extern table + std::vector> externs; + + // COM register data + // std::uint32_t typeLibCLSID; 16BYTES + std::uint32_t typeLibLCID; + + bool validLanguageDLLPrimaryLCID; + bool validLanguageDLLSecondaryLCID; + bool validProjectPrimaryLCID; + bool validProjectSecondaryLCID; + // bool validTypeLibCLSID; + bool validTypeLibLCID; + + public: + VisualBasicInfo(); + ~VisualBasicInfo(); + + /// @name Getters + /// @{ + const std::string &getLanguageDLL() const; + const std::string &getBackupLanguageDLL() const; + const std::string &getProjectExeName() const; + const std::string &getProjectDescription() const; + const std::string &getProjectHelpFile() const; + const std::string &getProjectName() const; + bool getLanguageDLLPrimaryLCID(std::uint32_t &res) const; + bool getLanguageDLLSecondaryLCID(std::uint32_t &res) const; + const std::string &getProjectPath() const; + bool getProjectPrimaryLCID(std::uint32_t &res) const; + bool getProjectSecondaryLCID(std::uint32_t &res) const; + const std::vector> &getObjects() const; + const std::vector> &getExterns() const; + const VisualBasicObject *getObject(std::size_t position) const; + const VisualBasicExtern *getExtern(std::size_t position) const; + std::size_t getNumberOfObjects() const; + std::size_t getNumberOfExterns() const; + // bool getTypeLibCLSID(std::uint32_t &res) const; + bool getTypeLibLCID(std::uint32_t &res) const; + /// @} + + /// @name Setters + /// @{ + void setLanguageDLL(const std::string &lDll); + void setBackupLanguageDLL(const std::string &blDll); + void setProjectExeName(const std::string &exeName); + void setProjectDescription(const std::string &desc); + void setProjectHelpFile(const std::string &helpFile); + void setProjectName(const std::string &name); + void setLanguageDLLPrimaryLCID(std::uint32_t lDllPrimLCID); + void setLanguageDLLSecondaryLCID(std::uint32_t lDllSecLCID); + void setProjectPath(const std::string &path); + void setProjectPrimaryLCID(std::uint32_t primLCID); + void setProjectSecondaryLCID(std::uint32_t secLCID); + // void setTypeLibCLSID(std::uint32_t tlbCLSID); + void setTypeLibLCID(std::uint32_t tlbLCID); + /// @} + + /// @name Other methods + /// @{ + void addObject(std::unique_ptr&& obj); + void addExtern(std::unique_ptr&& ext); + bool hasProjectName() const; + bool hasProjectDescription() const; + bool hasProjectHelpFile() const; + /// @} +}; + +} // namespace fileformat +} // namespace retdec + +#endif diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_object.h b/include/retdec/fileformat/types/visual_basic/visual_basic_object.h new file mode 100644 index 000000000..0886ddf18 --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_object.h @@ -0,0 +1,49 @@ +/** + * @file include/retdec/fileformat/types/visual_basic/visual_basic_object.h + * @brief Class for visual basic object. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_OBJECT_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_OBJECT_H + +#include +#include + +namespace retdec { +namespace fileformat { + +/** + * Class for visual basic information + */ +class VisualBasicObject +{ + private: + std::string name; + std::vector methods; + public: + VisualBasicObject(); + ~VisualBasicObject(); + + /// @name Getters + /// @{ + const std::string &getName() const; + const std::vector &getMethods() const; + std::size_t getNumberOfMethods() const; + /// @} + + /// @name Setters + /// @{ + void setName(const std::string &n); + /// @} + + /// @name Other methods + /// @{ + void addMethod(const std::string &method); + /// @} +}; + +} // namespace fileformat +} // namespace retdec + +#endif diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h new file mode 100644 index 000000000..df5a91f29 --- /dev/null +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -0,0 +1,366 @@ +/** + * @file include/retdec/fileformat/types/visual_basic/visual_basic_structures.h + * @brief Visual basic metadata structures. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_STRUCTURES_H +#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_VISUAL_BASIC_STRUCTURES_H + +#include + +namespace retdec { +namespace fileformat { + +enum class VBExternTableEntryType +{ + internal = 0x6, + external = 0x7 +}; + +struct VBHeader +{ + std::uint8_t signature[4]; ///< "VB5!" signature + std::uint16_t runtimeBuild; ///< runtime flag + std::uint8_t languageDLL[14]; ///< language DLL + std::uint8_t backupLanguageDLL[14]; ///< backup language DLL + std::uint16_t runtimeDLLVersion; ///< version of the runtime DLL + std::uint32_t LCID1; ///< primary LCID + std::uint32_t LCID2; ///< backup LCID + std::uint32_t subMainAddr; ///< sub main code address + std::uint32_t projectInfoAddr; ///< ProjectInfo address + std::uint32_t MDLIntObjsFlags; ///< VB controll flags for IDs < 32 + std::uint32_t MDLIntObjsFlags2; ///< VB controll flags for IDs > 32 + std::uint32_t threadFlags; ///< thread flags + std::uint32_t nThreads; ///< number of threads to support in pool + std::uint16_t nForms; ///< number of forms in this application + std::uint16_t nExternals; ///< number of external OCX components + std::uint32_t nThunks; ///< number of thunks to create + std::uint32_t GUITableAddr; ///< GUITable address + std::uint32_t externalTableAddr; ///< ExternalTable address + std::uint32_t COMRegisterDataAddr; ///< ComRegisterData address + std::uint32_t projExeNameOffset; ///< offset to the string containing EXE filename + std::uint32_t projDescOffset; ///< offset to the string containing project's description + std::uint32_t helpFileOffset; ///< offset to the string containing name of the Help file + std::uint32_t projNameOffset; ///< offset to the string containing project's name + + VBHeader() + { + + } + + std::size_t headerSize() + { + return + sizeof(signature) + sizeof(runtimeBuild) + sizeof(languageDLL) + + sizeof(backupLanguageDLL) + sizeof(runtimeDLLVersion) + sizeof(LCID1) + + sizeof(LCID2) + sizeof(subMainAddr) + sizeof(projectInfoAddr) + + sizeof(MDLIntObjsFlags) + sizeof(MDLIntObjsFlags2) + sizeof(threadFlags) + + sizeof(nThreads) + sizeof(nForms) + sizeof(nExternals) + + sizeof(nThunks) + sizeof(GUITableAddr) + sizeof(externalTableAddr) + + sizeof(COMRegisterDataAddr) + sizeof(projExeNameOffset) + sizeof(projDescOffset) + + sizeof(helpFileOffset) + sizeof(projNameOffset); + } + + void dump(std::ostream &out) + { + out << "signature:\t\t"; + for (std::size_t i = 0; i < sizeof(signature); i++) + { + out << signature[i]; + } + out << "\n"; + + out << "runtimeBuild:\t\t" << runtimeBuild << "\n"; + + out << "languageDLL:\t\t"; + for (std::size_t i = 0; i < sizeof(languageDLL); i++) + { + if (!languageDLL[i]) + { + break; + } + out << languageDLL[i]; + } + out << "\n"; + + out << "backupLanguageDLL:\t"; + for (std::size_t i = 0; i < sizeof(backupLanguageDLL); i++) + { + if (!backupLanguageDLL[i]) + { + break; + } + out << backupLanguageDLL[i]; + } + out << "\n"; + + out << "runtimeDLLVersion:\t" << runtimeDLLVersion << "\n"; + out << "LCID1:\t\t" << LCID1 << "\n"; + out << "LCID2:\t" << LCID2 << "\n"; + out << "subMainAddr:\t\t" << std::hex << subMainAddr << "\n"; + out << "projectInfoAddr:\t\t" << projectInfoAddr << std::dec << "\n"; + out << "MDLIntObjsFlags:\t\t" << MDLIntObjsFlags << "\n"; + out << "MDLIntObjsFlags2:\t\t" << MDLIntObjsFlags2 << "\n"; + out << "threadFlags:\t\t" << threadFlags << "\n"; + out << "nThreads:\t\t" << nThreads << "\n"; + out << "nForms:\t\t" << nForms << "\n"; + out << "nExternals:\t" << nExternals << "\n"; + out << "nThunks:\t\t" << nThunks << "\n"; + out << "GUITableAddr:\t\t" << std::hex << GUITableAddr << "\n"; + out << "externalTableAddr:" << externalTableAddr << "\n"; + out << "COMRegisterDataAddr:\t" << COMRegisterDataAddr << "\n"; + out << "projExeNameOffset:\t" << projExeNameOffset << "\n"; + out << "projDescOffset:\t\t" << projDescOffset << "\n"; + out << "helpFileOffset:\t\t" << helpFileOffset << "\n"; + out << "projNameOffset:\t\t" << projNameOffset << std::dec << "\n"; + out << "\n"; + } +}; + +struct VBProjInfo +{ + std::uint32_t version; ///< 5.00 in Hex (0x1F4), version + std::uint32_t objectTableAddr; ///< Object table address + std::uint32_t null; ///< unused value after compilation + std::uint32_t codeStartAddr; ///< etart of code address + std::uint32_t codeEndAddr; ///< end of code address + std::uint32_t dataSize; ///< size of VB object structures + std::uint32_t threadSpaceAddr; ///< eddress of address of thread object + std::uint32_t exHandlerAddr; ///< VBA exception handler address + std::uint32_t nativeCodeAddr; ///< .DATA section address + std::uint8_t pathInformation[528]; ///< path and id string, - -namespace retdec { -namespace fileformat { - -struct VBHeader -{ - std::uint8_t signature[4]; ///< "VB5!" signature - std::uint16_t runtimeBuild; ///< Runtime flag - std::uint8_t languageDLL[14]; ///< Language DLL - std::uint8_t backupLanguageDLL[14]; ///< Backup language DLL - std::uint16_t runtimeDLLVersion; ///< Version of the runtime DLL - std::uint32_t languageID; ///< Application language - std::uint32_t backupLanguageID; ///< Used with backup language DLL - std::uint32_t aSubMain; ///< Procedure to start after the application is launched - std::uint32_t aProjectInfo; ///< Pointer to ProjectInfo - std::uint32_t fMDLIntObjs; ///< VB controll flags for IDs < 32 - std::uint32_t fMDLIntObjs2; ///< VB controll flags for IDs > 32 - std::uint32_t threadFlags; ///< Thread flags - std::uint32_t threadCount; ///< Number of threads (themeaning of this field is unclear as VB doesn't let you make multithreaded application) - std::uint16_t formCount; ///< Number of forms in this application - std::uint16_t externalComponentCount; ///< Number of external OCX components - std::uint32_t thunkCount; ///< Number of thunks to create - std::uint32_t aGUITable; ///< Pointer to GUITable - std::uint32_t aExternalComponentTable; ///< Pointer to ExternalComponentTable - std::uint32_t aComRegisterData; ///< Pointer to ComRegisterData - std::uint32_t oProjectExename; ///< Pointer to the string containing EXE filename - std::uint32_t oProjectTitle; ///< Pointer to the string containing project's title - std::uint32_t oHelpFile; ///< Pointer to the string containing name of the Help file - std::uint32_t oProjectName; ///< Pointer to the string containing project's name - - VBHeader() - { - - } - - std::size_t headerSize() - { - return - sizeof(signature) + sizeof(runtimeBuild) + sizeof(languageDLL) + - sizeof(backupLanguageDLL) + sizeof(runtimeDLLVersion) + sizeof(languageID) + - sizeof(backupLanguageID) + sizeof(aSubMain) + sizeof(aProjectInfo) + - sizeof(fMDLIntObjs) + sizeof(fMDLIntObjs2) + sizeof(threadFlags) + - sizeof(threadCount) + sizeof(formCount) + sizeof(externalComponentCount) + - sizeof(thunkCount) + sizeof(aGUITable) + sizeof(aExternalComponentTable) + - sizeof(aComRegisterData) + sizeof(oProjectExename) + sizeof(oProjectTitle) + - sizeof(oHelpFile) + sizeof(oProjectName); - } - - void dump(std::ostream &out) - { - out << "signature:\t\t"; - for (std::size_t i = 0; i < sizeof(signature); i++) - { - out << signature[i]; - } - out << "\n"; - - out << "runtimeBuild:\t\t" << runtimeBuild << "\n"; - - out << "languageDLL:\t\t"; - for (std::size_t i = 0; i < sizeof(languageDLL); i++) - { - if (!languageDLL[i]) - { - break; - } - out << languageDLL[i]; - } - out << "\n"; - - out << "backupLanguageDLL:\t"; - for (std::size_t i = 0; i < sizeof(backupLanguageDLL); i++) - { - if (!backupLanguageDLL[i]) - { - break; - } - out << backupLanguageDLL[i]; - } - out << "\n"; - - out << "runtimeDLLVersion:\t" << runtimeDLLVersion << "\n"; - out << "languageID:\t\t" << languageID << "\n"; - out << "backupLanguageID:\t" << backupLanguageID << "\n"; - out << "aSubMain:\t\t" << std::hex << aSubMain << "\n"; - out << "aProjectInfo:\t\t" << aProjectInfo << std::dec << "\n"; - out << "fMDLIntObjs:\t\t" << fMDLIntObjs << "\n"; - out << "fMDLIntObjs2:\t\t" << fMDLIntObjs2 << "\n"; - out << "threadFlags:\t\t" << threadFlags << "\n"; - out << "threadCount:\t\t" << threadCount << "\n"; - out << "formCount:\t\t" << formCount << "\n"; - out << "externalComponentCount:\t" << externalComponentCount << "\n"; - out << "thunkCount:\t\t" << thunkCount << "\n"; - out << "aGUITable:\t\t" << std::hex << aGUITable << "\n"; - out << "aExternalComponentTable:" << aExternalComponentTable << "\n"; - out << "aComRegisterData:\t" << aComRegisterData << "\n"; - out << "oProjectExename:\t" << oProjectExename << "\n"; - out << "oProjectTitle:\t\t" << oProjectTitle << "\n"; - out << "oHelpFile:\t\t" << oHelpFile << "\n"; - out << "oProjectName:\t\t" << oProjectName << std::dec << "\n"; - out << "\n"; - } -}; - -/** - * Visual basic header - */ -class VisualBasicHeader -{ - private: - std::size_t headerAddress; ///< Header address - - public: - VisualBasicHeader(); - ~VisualBasicHeader(); - - /// @name Getters - /// @{ - - /// @} - - /// @name Setters - /// @{ - void setHeaderAddress(std::size_t address); - /// @} - - /// @name Iterators - /// @{ - - /// @} - - /// @name Other methods - /// @{ - - /// @} -}; - -} // namespace fileformat -} // namespace retdec - -#endif diff --git a/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h b/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h deleted file mode 100644 index 468d0c448..000000000 --- a/include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file include/retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h - * @brief Class for visual basic project info. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_PROJECT_INFO_H -#define RETDEC_FILEFORMAT_TYPES_VISUAL_BASIC_HEADER_VISUAL_BASIC_PROJECT_INFO_H - -#include - -namespace retdec { -namespace fileformat { - -struct VBProjInfo -{ - std::uint32_t dwVersion; ///< 5.00 in Hex (0x1F4), version - std::uint32_t lpObjectTable; ///< pointer to object table - std::uint32_t dwNull; ///< unused value after compilation - std::uint32_t lpCodeStart; ///< pointer to start of code - std::uint32_t lpCodeEnd; ///< pointer to end of code - std::uint32_t dwDataSize; ///< size of VB object structures - std::uint32_t lpThreadSpace; ///< pointer to pointer to thread object - std::uint32_t lpVbaSeh; ///< pointer to VBA exception handler - std::uint32_t lpNativeCode; ///< pointer to .DATA section - uint8_t szPathInformation[528]; ///< path and id string, bytes; unsigned long long version = 0; unsigned long long baseAddress = 0; std::size_t vbHeaderAddress = 0; std::size_t vbHeaderOffset = 0; std::size_t vbProjectInfoOffset = 0; + std::size_t vbComDataRegistrationOffset = 0; + std::string projLanguageDLL; + std::string projBackupLanguageDLL; + std::string projExeName; + std::string projDesc; + std::string helpFile; + std::string projName; std::size_t offset = 0; struct VBHeader vbh; if (!isVisualBasic(version)) { - return false; + return; } // first instruction is expected to be PUSH (0x68 ) if (!getEpBytes(bytes, 5) || bytes.size() != 5 || bytes[0] != 0x68) { - return false; + return; } if (!getImageBaseAddress(baseAddress)) { - return false; + return; } vbHeaderAddress = bytes[4] << 24 | bytes[3] << 16 | bytes[2] << 8 | bytes[1]; + + if (vbHeaderAddress < baseAddress) + { + return; + } + vbHeaderOffset = vbHeaderAddress - baseAddress; if (!getBytes(bytes, vbHeaderOffset, vbh.headerSize()) || bytes.size() != vbh.headerSize()) { - return false; + return; } std::memcpy(&vbh.signature, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.signature)); offset += sizeof(vbh.signature); @@ -670,72 +682,193 @@ bool PeFormat::loadVisualBasicHeader() std::memcpy(&vbh.languageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); std::memcpy(&vbh.backupLanguageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); vbh.runtimeDLLVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeDLLVersion); - vbh.languageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.languageID); - vbh.backupLanguageID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.backupLanguageID); - vbh.aSubMain = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aSubMain); - vbh.aProjectInfo = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aProjectInfo); + vbh.LCID1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.LCID1); + vbh.LCID2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.LCID2); + vbh.subMainAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.subMainAddr); + vbh.projectInfoAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projectInfoAddr); + vbh.MDLIntObjsFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.MDLIntObjsFlags); + vbh.MDLIntObjsFlags2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.MDLIntObjsFlags2); vbh.threadFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadFlags); - vbh.threadCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadCount); - vbh.formCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.formCount); - vbh.externalComponentCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalComponentCount); - vbh.thunkCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.thunkCount); - vbh.aGUITable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aGUITable); - vbh.aExternalComponentTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aExternalComponentTable); - vbh.aComRegisterData = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.aComRegisterData); - vbh.oProjectExename = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectExename); - vbh.oProjectTitle = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectTitle); - vbh.oHelpFile = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oHelpFile); - vbh.oProjectName = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.oProjectName); + vbh.nThreads = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nThreads); + vbh.nForms = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nForms); + vbh.nExternals = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nExternals); + vbh.nThunks = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nThunks); + vbh.GUITableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.GUITableAddr); + vbh.externalTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalTableAddr); + vbh.COMRegisterDataAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.COMRegisterDataAddr); + vbh.projExeNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projExeNameOffset); + vbh.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projDescOffset); + vbh.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.helpFileOffset); + vbh.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projNameOffset); if (!isLittleEndian()) { vbh.runtimeBuild = byteSwap16(vbh.runtimeBuild); vbh.runtimeDLLVersion = byteSwap16(vbh.runtimeDLLVersion); - vbh.languageID = byteSwap32(vbh.languageID); - vbh.backupLanguageID = byteSwap32(vbh.backupLanguageID); - vbh.aSubMain = byteSwap32(vbh.aSubMain); - vbh.aProjectInfo = byteSwap32(vbh.aProjectInfo); + vbh.LCID1 = byteSwap32(vbh.LCID1); + vbh.LCID2 = byteSwap32(vbh.LCID2); + vbh.subMainAddr = byteSwap32(vbh.subMainAddr); + vbh.projectInfoAddr = byteSwap32(vbh.projectInfoAddr); + vbh.MDLIntObjsFlags = byteSwap32(vbh.MDLIntObjsFlags); + vbh.MDLIntObjsFlags2 = byteSwap32(vbh.MDLIntObjsFlags2); vbh.threadFlags = byteSwap32(vbh.threadFlags); - vbh.threadCount = byteSwap32(vbh.threadCount); - vbh.formCount = byteSwap16(vbh.formCount); - vbh.externalComponentCount = byteSwap16(vbh.externalComponentCount); - vbh.thunkCount = byteSwap32(vbh.thunkCount); - vbh.aGUITable = byteSwap32(vbh.aGUITable); - vbh.aExternalComponentTable = byteSwap32(vbh.aExternalComponentTable); - vbh.aComRegisterData = byteSwap32(vbh.aComRegisterData); - vbh.oProjectExename = byteSwap32(vbh.oProjectExename); - vbh.oProjectTitle = byteSwap32(vbh.oProjectTitle); - vbh.oHelpFile = byteSwap32(vbh.oHelpFile); - vbh.oProjectName = byteSwap32(vbh.oProjectName); + vbh.nThreads = byteSwap32(vbh.nThreads); + vbh.nForms = byteSwap16(vbh.nForms); + vbh.nExternals = byteSwap16(vbh.nExternals); + vbh.nThunks = byteSwap32(vbh.nThunks); + vbh.GUITableAddr = byteSwap32(vbh.GUITableAddr); + vbh.externalTableAddr = byteSwap32(vbh.externalTableAddr); + vbh.COMRegisterDataAddr = byteSwap32(vbh.COMRegisterDataAddr); + vbh.projExeNameOffset = byteSwap32(vbh.projExeNameOffset); + vbh.projDescOffset = byteSwap32(vbh.projDescOffset); + vbh.helpFileOffset = byteSwap32(vbh.helpFileOffset); + vbh.projNameOffset = byteSwap32(vbh.projNameOffset); } // TODO check VB header magic - std::cout << "[KUBO] VB header <<<<<<<<<<< " << std::to_string(vbh.headerSize()) << "\n"; + std::cout << "[KUBO] VB header size:" << std::to_string(vbh.headerSize()) << "\n"; vbh.dump(std::cout); - vbProjectInfoOffset = vbh.aProjectInfo - baseAddress; + visualBasicInfo = new VisualBasicInfo(); + if (vbh.projExeNameOffset != 0) + { + projExeName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + vbHeaderOffset + vbh.projExeNameOffset); + visualBasicInfo->setProjectExeName(projExeName); + } + if (vbh.projDescOffset != 0) + { + projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + vbHeaderOffset + vbh.projDescOffset); + visualBasicInfo->setProjectDescription(projDesc); + } + if (vbh.helpFileOffset != 0) + { + helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + vbHeaderOffset + vbh.helpFileOffset); + visualBasicInfo->setProjectHelpFile(helpFile); + } + if (vbh.projNameOffset != 0) + { + projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + vbHeaderOffset + vbh.projNameOffset); + visualBasicInfo->setProjectName(projName); + } + + std::cout << "KUBO KING: " << projExeName << " | " << projDesc << " | " << helpFile << " | " + << projName << "\n\n"; + + for (size_t i = 0; i < sizeof(vbh.languageDLL) && vbh.languageDLL[i]; i++) + { + projLanguageDLL.push_back(vbh.languageDLL[i]); + } + for (size_t i = 0; i < sizeof(vbh.backupLanguageDLL) && vbh.backupLanguageDLL[i]; i++) + { + projBackupLanguageDLL.push_back(vbh.backupLanguageDLL[i]); + } + visualBasicInfo->setLanguageDLL(projLanguageDLL); + visualBasicInfo->setBackupLanguageDLL(projBackupLanguageDLL); + visualBasicInfo->setLanguageDLLPrimaryLCID(vbh.LCID1); + visualBasicInfo->setLanguageDLLSecondaryLCID(vbh.LCID2); + std::cout << "KUBO KING: " << projLanguageDLL << " | " << projBackupLanguageDLL << "\n\n"; - loadVisualBasicProjectInfo(vbProjectInfoOffset); + if (vbh.projectInfoAddr >= baseAddress) + { + vbProjectInfoOffset = vbh.projectInfoAddr - baseAddress; + parseVisualBasicProjectInfo(vbProjectInfoOffset, baseAddress); + } + + if (vbh.COMRegisterDataAddr >= baseAddress) + { + vbComDataRegistrationOffset = vbh.COMRegisterDataAddr - baseAddress; + parseVisualBasicComRegistrationData(vbComDataRegistrationOffset, baseAddress); + } +} - visualBasicHeader = new VisualBasicHeader(); - visualBasicHeader->setHeaderAddress(vbHeaderAddress); +/** + * Parse visual basic COM registration data + * @param structureOffset Offset in file where the structure starts + * @param baseAddress Base address + * @return @c true if COM retistration data was successfuly parsed, @c false otherwise + */ +bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress) +{ + auto allBytes = getBytes(); + std::vector bytes; + std::size_t offset = 0; + struct VBCOMRData vbcrd; + std::string projName; + std::string helpFile; + std::string projDesc; + if (!getBytes(bytes, structureOffset, vbcrd.structureSize()) || bytes.size() != vbcrd.structureSize()) + { + return false; + } - // TODO iclude VB headrov to /fftypes and delete here + vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); + vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); + vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); + vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); + std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); + vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); + vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); + vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); + vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); + + if (!isLittleEndian()) + { + vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); + vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); + vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); + vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); + vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); + vbcrd.unknown = byteSwap32(vbcrd.unknown); + vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); + vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); + } + // visualBasicInfo->setTypeLibCLSID(vbcrd.projCLSID); TODO + visualBasicInfo->setTypeLibLCID(vbcrd.projDescOffset); + if (!visualBasicInfo->hasProjectName()) + { + projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.projNameOffset); + } + if (!visualBasicInfo->hasProjectHelpFile()) + { + helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.helpFileOffset); + } + if (!visualBasicInfo->hasProjectDescription()) + { + projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.projDescOffset); + } + + std::cout << "[KUBO] VB COM register data size: " << std::to_string(vbcrd.structureSize()) << "\n"; + std::cout << "projName: " << projName << "\n"; + std::cout << "helpFile: " << helpFile << "\n"; + std::cout << "projDesc: " << projDesc << "\n"; + + vbcrd.dump(std::cout); return true; } /** - * Load visual basic project info + * Parse visual basic project info * @param structureOffset Offset in file where the structure starts - * @return @c true if project info was successfuly loaded, @c false otherwise + * @param baseAddress Base address + * @return @c true if project info was successfuly parsed, @c false otherwise */ -bool PeFormat::loadVisualBasicProjectInfo(std::size_t structureOffset) +bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::size_t baseAddress) { std::vector bytes; + std::size_t vbExternTableOffset = 0; + std::size_t vbObjectTableOffset = 0; + std::string projPath; std::size_t offset = 0; struct VBProjInfo vbpi; @@ -744,37 +877,332 @@ bool PeFormat::loadVisualBasicProjectInfo(std::size_t structureOffset) return false; } - vbpi.dwVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwVersion); - vbpi.lpObjectTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpObjectTable); - vbpi.dwNull = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwNull); - vbpi.lpCodeStart = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpCodeStart); - vbpi.lpCodeEnd = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpCodeEnd); - vbpi.dwDataSize = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwDataSize); - vbpi.lpThreadSpace = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpThreadSpace); - vbpi.lpVbaSeh = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpVbaSeh); - vbpi.lpNativeCode = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpNativeCode); - std::memcpy(&vbpi.szPathInformation, reinterpret_cast(&bytes.data()[offset]), sizeof(vbpi.szPathInformation)); offset += sizeof(vbpi.szPathInformation); - vbpi.lpExternalTable = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.lpExternalTable); - vbpi.dwExternalCount = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dwExternalCount); + vbpi.version = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.version); + vbpi.objectTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.objectTableAddr); + vbpi.null = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.null); + vbpi.codeStartAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.codeStartAddr); + vbpi.codeEndAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.codeEndAddr); + vbpi.dataSize = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dataSize); + vbpi.threadSpaceAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.threadSpaceAddr); + vbpi.exHandlerAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.exHandlerAddr); + vbpi.nativeCodeAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.nativeCodeAddr); + std::memcpy(&vbpi.pathInformation, reinterpret_cast(&bytes.data()[offset]), sizeof(vbpi.pathInformation)); offset += sizeof(vbpi.pathInformation); + vbpi.externalTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.externalTableAddr); + vbpi.nExternals = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.nExternals); if (!isLittleEndian()) { - vbpi.dwVersion = byteSwap32(vbpi.dwVersion); - vbpi.lpObjectTable = byteSwap32(vbpi.lpObjectTable); - vbpi.dwNull = byteSwap32(vbpi.dwNull); - vbpi.lpCodeStart = byteSwap32(vbpi.lpCodeStart); - vbpi.lpCodeEnd = byteSwap32(vbpi.lpCodeEnd); - vbpi.dwDataSize = byteSwap32(vbpi.dwDataSize); - vbpi.lpThreadSpace = byteSwap32(vbpi.lpThreadSpace); - vbpi.lpVbaSeh = byteSwap32(vbpi.lpVbaSeh); - vbpi.lpNativeCode = byteSwap32(vbpi.lpNativeCode); - vbpi.lpExternalTable = byteSwap32(vbpi.lpExternalTable); - vbpi.dwExternalCount = byteSwap32(vbpi.dwExternalCount); + vbpi.version = byteSwap32(vbpi.version); + vbpi.objectTableAddr = byteSwap32(vbpi.objectTableAddr); + vbpi.null = byteSwap32(vbpi.null); + vbpi.codeStartAddr = byteSwap32(vbpi.codeStartAddr); + vbpi.codeEndAddr = byteSwap32(vbpi.codeEndAddr); + vbpi.dataSize = byteSwap32(vbpi.dataSize); + vbpi.threadSpaceAddr = byteSwap32(vbpi.threadSpaceAddr); + vbpi.exHandlerAddr = byteSwap32(vbpi.exHandlerAddr); + vbpi.nativeCodeAddr = byteSwap32(vbpi.nativeCodeAddr); + vbpi.externalTableAddr = byteSwap32(vbpi.externalTableAddr); + vbpi.nExternals = byteSwap32(vbpi.nExternals); } - std::cout << "[KUBO] VB project info <<<<<<<<<<< " << std::to_string(vbpi.headerSize()) << "\n"; + projPath = retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)); + visualBasicInfo->setProjectPath(projPath); + + std::cout << "[KUBO] VB project info size: " << std::to_string(vbpi.headerSize()) << "\n"; + std::cout << "[KUBO] path: " << retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)) << "\n"; vbpi.dump(std::cout); + if (vbpi.externalTableAddr >= baseAddress) + { + vbExternTableOffset = vbpi.externalTableAddr - baseAddress; + parseVisualBasicExternTable(vbExternTableOffset, vbpi.nExternals, baseAddress); + } + + if (vbpi.objectTableAddr >= baseAddress) + { + vbObjectTableOffset = vbpi.objectTableAddr - baseAddress; + parseVisualBasicObjectTable(vbObjectTableOffset, baseAddress); + } + + return true; +} + +/** + * Parse visual basic extern table + * @param structureOffset Offset in file where the structure starts + * @param baseAddress Base address + * @param nEntries Number of entries in table + * @return @c true if extern table was successfuly parsed, @c false otherwise + */ +bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::size_t baseAddress, + std::size_t nEntries) +{ + auto allBytes = getBytes(); + std::vector bytes; + struct VBExternTableEntry entry; + struct VBExternTableEntryData entryData; + std::size_t vbExternEntryDataOffset = 0; + std::size_t offset = 0; + + for (std::size_t i = 0; i < nEntries; i++) + { + std::string moduleName; + std::string apiName; + + if (!getBytes(bytes, structureOffset + i * entry.structureSize(), entry.structureSize()) + || bytes.size() != entry.structureSize()) + { + break; + } + + offset = 0; + entry.type = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entry.type); + entry.importDataAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entry.importDataAddr); + + if (!isLittleEndian()) + { + entry.type = byteSwap32(entry.type); + entry.importDataAddr = byteSwap32(entry.importDataAddr); + } + + if (entry.type != static_cast(VBExternTableEntryType::external) + || entry.importDataAddr < baseAddress) + { + continue; + } + + vbExternEntryDataOffset = entry.importDataAddr - baseAddress; + + if (!getBytes(bytes, vbExternEntryDataOffset, entryData.structureSize()) + || bytes.size() != entryData.structureSize()) + { + continue; + } + + offset = 0; + entryData.moduleNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entryData.moduleNameAddr); + entryData.apiNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entryData.apiNameAddr); + + if (!isLittleEndian()) + { + entryData.moduleNameAddr = byteSwap32(entryData.moduleNameAddr); + entryData.apiNameAddr = byteSwap32(entryData.apiNameAddr); + } + + if (entryData.moduleNameAddr >= baseAddress) + { + std::size_t moduleNameOffset = entryData.moduleNameAddr - baseAddress; + moduleName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), moduleNameOffset); + } + + if (entryData.apiNameAddr >= baseAddress) + { + std::size_t apiNameOffset = entryData.apiNameAddr - baseAddress; + apiName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), apiNameOffset); + } + + auto ext = std::make_unique(); + ext->setModuleName(moduleName); + ext->setApiName(apiName); + visualBasicInfo->addExtern(std::move(ext)); + std::cout << "[KUBO] moduleName: " << moduleName << "\n"; + std::cout << "[KUBO] apiName: " << apiName << "\n"; + } + + return true; +} + +/** + * Parse visual basic object table + * @param structureOffset Offset in file where the structure starts + * @param baseAddress Base address + * @return @c true if object table was successfuly parsed, @c false otherwise + */ +bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::size_t baseAddress) +{ + auto allBytes = getBytes(); + std::vector bytes; + std::size_t offset = 0; + std::size_t projectNameOffset = 0; + std::size_t objectDescriptorsOffset = 0; + struct VBObjectTable vbot; + std::string projName; + + if (!getBytes(bytes, structureOffset, vbot.structureSize()) || bytes.size() != vbot.structureSize()) + { + return false; + } + + vbot.null1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.null1); + vbot.execCOMAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.execCOMAddr); + vbot.projecInfo2Addr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projecInfo2Addr); + vbot.reserved = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.reserved); + vbot.null2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.null2); + vbot.projectObjectAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projectObjectAddr); + std::memcpy(&vbot.objectGUID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbot.objectGUID)); offset += sizeof(vbot.objectGUID); + vbot.flagsCompileState = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.flagsCompileState); + vbot.nObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nObjects); + vbot.nCompiledObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nCompiledObjects); + vbot.nUsedObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nUsedObjects); + vbot.objectDescriptorsAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.objectDescriptorsAddr); + vbot.IDE1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE1); + vbot.IDE2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE2); + vbot.IDE3 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE3); + vbot.projectNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projectNameAddr); + vbot.LCID1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.LCID1); + vbot.LCID2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.LCID2); + vbot.IDE4 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE4); + vbot.templateVesion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.templateVesion); + + if (!isLittleEndian()) + { + vbot.null1 = byteSwap32(vbot.null1); + vbot.execCOMAddr = byteSwap32(vbot.execCOMAddr); + vbot.projecInfo2Addr = byteSwap32(vbot.projecInfo2Addr); + vbot.reserved = byteSwap32(vbot.reserved); + vbot.null2 = byteSwap32(vbot.null2); + vbot.projectObjectAddr = byteSwap32(vbot.projectObjectAddr); + vbot.flagsCompileState = byteSwap16(vbot.flagsCompileState); + vbot.nObjects = byteSwap16(vbot.nObjects); + vbot.nCompiledObjects = byteSwap16(vbot.nCompiledObjects); + vbot.nUsedObjects = byteSwap16(vbot.nUsedObjects); + vbot.objectDescriptorsAddr = byteSwap32(vbot.objectDescriptorsAddr); + vbot.IDE1 = byteSwap32(vbot.IDE1); + vbot.IDE2 = byteSwap32(vbot.IDE2); + vbot.IDE3 = byteSwap32(vbot.IDE3); + vbot.projectNameAddr = byteSwap32(vbot.projectNameAddr); + vbot.LCID1 = byteSwap32(vbot.LCID1); + vbot.LCID2 = byteSwap32(vbot.LCID2); + vbot.IDE4 = byteSwap32(vbot.IDE4); + vbot.templateVesion = byteSwap32(vbot.templateVesion); + } + + visualBasicInfo->setProjectPrimaryLCID(vbot.LCID1); + visualBasicInfo->setProjectSecondaryLCID(vbot.LCID2); + // TODO KUBO GUID + + std::cout << "[KUBO] VB object table size: " << std::to_string(vbot.structureSize()) << "\n"; + + if (!visualBasicInfo->hasProjectName() && vbot.projectNameAddr >= baseAddress) + { + projectNameOffset = vbot.projectNameAddr - baseAddress; + projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset); + visualBasicInfo->setProjectName(projName); + std::cout << "[KUBO] Project name: " << projName << "\n"; + } + vbot.dump(std::cout); + + if (vbot.objectDescriptorsAddr >= baseAddress) + { + objectDescriptorsOffset = vbot.objectDescriptorsAddr - baseAddress; + parseVisualBasicObjects(objectDescriptorsOffset, baseAddress, vbot.nObjects); + } + + return true; +} + +/** + * Parse visual basic objects + * @param structureOffset Offset in file where the public object descriptors array starts + * @param baseAddress Base address + * @param nEntries Number of objects in array + * @return @c true if objects were successfuly parsed, @c false otherwise + */ +bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t baseAddress, + std::size_t nObjects) +{ + auto allBytes = getBytes(); + std::vector bytes; + struct VBPublicObjectDescriptor vbpod; + std::size_t offset = 0; + + for (std::size_t i = 0; i < nObjects; i++) + { + std::unique_ptr object; + if (!getBytes(bytes, structureOffset + i * vbpod.structureSize(), vbpod.structureSize()) + || bytes.size() != vbpod.structureSize()) + { + break; + } + + offset = 0; + vbpod.objectInfoAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectInfoAddr); + vbpod.reserved = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.reserved); + vbpod.publicBytesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.publicBytesAddr); + vbpod.staticBytesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.staticBytesAddr); + vbpod.modulePublicAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.modulePublicAddr); + vbpod.moduleStaticAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.moduleStaticAddr); + vbpod.objectNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectNameAddr); + vbpod.nMethods = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.nMethods); + vbpod.methodNamesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.methodNamesAddr); + vbpod.staticVarsCopyAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.staticVarsCopyAddr); + vbpod.objectType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectType); + vbpod.null = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.null); + + if (!isLittleEndian()) + { + vbpod.objectInfoAddr = byteSwap32(vbpod.objectInfoAddr); + vbpod.reserved = byteSwap32(vbpod.reserved); + vbpod.publicBytesAddr = byteSwap32(vbpod.publicBytesAddr); + vbpod.staticBytesAddr = byteSwap32(vbpod.staticBytesAddr); + vbpod.modulePublicAddr = byteSwap32(vbpod.modulePublicAddr); + vbpod.moduleStaticAddr = byteSwap32(vbpod.moduleStaticAddr); + vbpod.objectNameAddr = byteSwap32(vbpod.objectNameAddr); + vbpod.nMethods = byteSwap32(vbpod.nMethods); + vbpod.methodNamesAddr = byteSwap32(vbpod.methodNamesAddr); + vbpod.staticVarsCopyAddr = byteSwap32(vbpod.staticVarsCopyAddr); + vbpod.objectType = byteSwap32(vbpod.objectType); + vbpod.null = byteSwap32(vbpod.null); + } + + if (vbpod.objectNameAddr < baseAddress) + { + continue; + } + + + std::size_t objectNameOffset = vbpod.objectNameAddr - baseAddress; + std::string objectName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), objectNameOffset); + object = std::make_unique(); + object->setName(objectName); + std::cout << "[KUBO] objectName: " << objectName << "\n"; + + if (vbpod.methodNamesAddr >= baseAddress) + { + std::size_t methodAddrOffset = vbpod.methodNamesAddr - baseAddress; + for (std::size_t mIdx = 0; mIdx < vbpod.nMethods; mIdx++) + { + if (!getBytes(bytes, methodAddrOffset + mIdx * sizeof(std::uint32_t), sizeof(std::uint32_t)) + || bytes.size() != sizeof(std::uint32_t)) + { + break; + } + + std::uint32_t methodNameAddr = *reinterpret_cast(bytes.data()); + + if (!isLittleEndian()) + { + methodNameAddr = byteSwap32(methodNameAddr); + } + + if (methodNameAddr < baseAddress) + { + continue; + } + + std::size_t methodNameOffset = methodNameAddr - baseAddress; + std::string methodName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), methodNameOffset); + object->addMethod(methodName); + + std::cout << "[KUBO] method" << mIdx << ": " << methodName << "\n"; + } + } + + visualBasicInfo->addObject(std::move(object)); + std::cout << "\n[KUBO] object" << i << "\n"; + vbpod.dump(std::cout); + } + return true; } diff --git a/src/fileformat/types/visual_basic/visual_basic_extern.cpp b/src/fileformat/types/visual_basic/visual_basic_extern.cpp new file mode 100644 index 000000000..59a04b54d --- /dev/null +++ b/src/fileformat/types/visual_basic/visual_basic_extern.cpp @@ -0,0 +1,66 @@ +/** + * @file src/fileformat/types/visual_basic/visual_basic_extern.cpp + * @brief Class visual basic extern. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/fileformat/types/visual_basic/visual_basic_extern.h" + +namespace retdec { +namespace fileformat { + +/** + * Constructor + */ +VisualBasicExtern::VisualBasicExtern() +{ + +} + +/** + * Destructor + */ +VisualBasicExtern::~VisualBasicExtern() +{ + +} + +/** + * Get module name + * @return Module name + */ +const std::string &VisualBasicExtern::getModuleName() const +{ + return moduleName; +} + +/** + * Get api name + * @return Api name + */ +const std::string &VisualBasicExtern::getApiName() const +{ + return apiName; +} + +/** + * Set module name + * @param mName Module name to set + */ +void VisualBasicExtern::setModuleName(const std::string &mName) +{ + moduleName = mName; +} + +/** + * Set api name + * @param aName Api name to set + */ +void VisualBasicExtern::setApiName(const std::string &aName) +{ + apiName = aName; +} + + +} // namespace fileformat +} // namespace retdec diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp new file mode 100644 index 000000000..ed78ef18a --- /dev/null +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -0,0 +1,411 @@ +/** + * @file src/fileformat/types/visual_basic/visual_basic_info.cpp + * @brief Class visual basic information. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/fileformat/types/visual_basic/visual_basic_info.h" + +namespace retdec { +namespace fileformat { + +/** + * Constructor + */ +VisualBasicInfo::VisualBasicInfo() : languageDLLPrimaryLCID(0), languageDLLSecondaryLCID(0), + projectPrimaryLCID(0), projectSecondaryLCID(0), /*typeLibCLSID(0),*/ typeLibLCID(0), + validLanguageDLLPrimaryLCID(false), validLanguageDLLSecondaryLCID(false), + validProjectPrimaryLCID(false), validProjectSecondaryLCID(false), /*validTypeLibCLSID(false),*/ + validTypeLibLCID(false) +{ + +} + +/** + * Destructor + */ +VisualBasicInfo::~VisualBasicInfo() +{ + +} + +/** + * Get language DLL + * @return language DLL + */ +const std::string &VisualBasicInfo::getLanguageDLL() const +{ + return languageDLL; +} + +/** + * Get backup language DLL + * @return backup language DLL + */ +const std::string &VisualBasicInfo::getBackupLanguageDLL() const +{ + return backupLanguageDLL; +} + +/** + * Get project exe name + * @return project exe name + */ +const std::string &VisualBasicInfo::getProjectExeName() const +{ + return projectExeName; +} + +/** + * Get project description + * @return project description + */ +const std::string &VisualBasicInfo::getProjectDescription() const +{ + return projectDescription; +} + +/** + * Get project help file + * @return project help file + */ +const std::string &VisualBasicInfo::getProjectHelpFile() const +{ + return projectHelpFile; +} + +/** + * Get project name + * @return project name + */ +const std::string &VisualBasicInfo::getProjectName() const +{ + return projectName; +} + +/** + * Get language DLL primary LCID + * @param res Variable to store the result to + * @return @c true if language DLL primary LCID is valid, @c false otherwise + */ +bool VisualBasicInfo::getLanguageDLLPrimaryLCID(std::uint32_t &res) const +{ + if (!validLanguageDLLPrimaryLCID) + { + return false; + } + res = languageDLLPrimaryLCID; + return true; +} +/** + * Get language DLL secondary LCID + * @param res Variable to store the result to + * @return @c true if language DLL secondary LCID is valid, @c false otherwise + */ +bool VisualBasicInfo::getLanguageDLLSecondaryLCID(std::uint32_t &res) const +{ + if (!validLanguageDLLSecondaryLCID) + { + return false; + } + res = languageDLLSecondaryLCID; + return true; +} + +/** + * Get project path + * @return project path + */ +const std::string &VisualBasicInfo::getProjectPath() const +{ + // if prefix else TODO + return projectPath; +} + +/** + * Get project primary LCID + * @param res Variable to store the result to + * @return @c true if project primary LCID is valid, @c false otherwise + */ +bool VisualBasicInfo::getProjectPrimaryLCID(std::uint32_t &res) const +{ + if (!validProjectPrimaryLCID) + { + return false; + } + res = projectPrimaryLCID; + return true; +} + +/** + * Get project secondary LCID + * @param res Variable to store the result to + * @return @c true if project secondary LCID is valid, @c false otherwise + */ +bool VisualBasicInfo::getProjectSecondaryLCID(std::uint32_t &res) const +{ + if (!validProjectSecondaryLCID) + { + return false; + } + res = projectSecondaryLCID; + return true; +} + +/** + * Get objects + * @return Visual basic objects + */ +const std::vector> &VisualBasicInfo::getObjects() const +{ + return objects; +} + +/** + * Get externs + * @return Visual basic externs + */ +const std::vector> &VisualBasicInfo::getExterns() const +{ + return externs; +} + +/** + * Get object + * @param position Index of selected visual basic object (indexed from 0) + * @return Visual basic object + */ +const VisualBasicObject *VisualBasicInfo::getObject(std::size_t position) const +{ + return (position < objects.size()) ? objects[position].get() : nullptr; +} + +/** + * Get extern + * @param position Index of selected visual basic extern (indexed from 0) + * @return Visual basic extern + */ +const VisualBasicExtern *VisualBasicInfo::getExtern(std::size_t position) const +{ + return (position < externs.size()) ? externs[position].get() : nullptr; +} + +/** + * Get number of objects + * @return Number of objects + */ +size_t VisualBasicInfo::getNumberOfObjects() const +{ + return objects.size(); +} + +/** + * Get number of externs + * @return Number of externs + */ +size_t VisualBasicInfo::getNumberOfExterns() const +{ + return externs.size(); +} + +// /** +// * Get typeLib CLSID +// * @param res Variable to store the result to +// * @return @c true if project typeLib CLSID is valid, @c false otherwise +// */ +// bool VisualBasicInfo::getTypeLibCLSID(std::uint32_t &res) const +// { +// if (!validTypeLibCLSID) +// { +// return false; +// } +// res = typeLibCLSID; +// return true; +// } + +/** + * Get typeLib LCID + * @param res Variable to store the result to + * @return @c true if typeLib LCID is valid, @c false otherwise + */ +bool VisualBasicInfo::getTypeLibLCID(std::uint32_t &res) const +{ + if (!validTypeLibLCID) + { + return false; + } + res = typeLibLCID; + return true; +} + +/** + * Set language DLL + * @param lDLL Language DLL to set + */ +void VisualBasicInfo::setLanguageDLL(const std::string &lDLL) +{ + languageDLL = lDLL; +} + +/** + * Set backup language DLL + * @param blDLL Backup language DLL to set + */ +void VisualBasicInfo::setBackupLanguageDLL(const std::string &blDLL) +{ + backupLanguageDLL = blDLL; +} + +/** + * Set project exe name + * @param exeName Project exe name to set + */ +void VisualBasicInfo::setProjectExeName(const std::string &exeName) +{ + projectExeName = exeName; +} + +/** + * Set project description + * @param desc Project description to set + */ +void VisualBasicInfo::setProjectDescription(const std::string &desc) +{ + projectDescription = desc; +} + +/** + * Set project help file + * @param helpFile Project help file to set + */ +void VisualBasicInfo::setProjectHelpFile(const std::string &helpFile) +{ + projectHelpFile = helpFile; +} + +/** + * Set project name + * @param name Project name to set + */ +void VisualBasicInfo::setProjectName(const std::string &name) +{ + projectName = name; +} + +/** + * Set language DLL primary LCID + * @param lDLLPrimLCID Language DLL primary LCID to set + */ +void VisualBasicInfo::setLanguageDLLPrimaryLCID(std::uint32_t lDLLPrimLCID) +{ + languageDLLPrimaryLCID = lDLLPrimLCID; + validLanguageDLLPrimaryLCID = true; +} + +/** + * Set language DLL secondary LCID + * @param lDLLSecLCID Language DLL secondary LCID to set + */ +void VisualBasicInfo::setLanguageDLLSecondaryLCID(std::uint32_t lDLLSecLCID) +{ + languageDLLSecondaryLCID = lDLLSecLCID; + validLanguageDLLSecondaryLCID = true; +} + +/** + * Set project path + * @param path Project path to set + */ +void VisualBasicInfo::setProjectPath(const std::string &path) +{ + projectPath = path; +} + +/** + * Set project primary LCID + * @param primLCID Project primary LCID to set + */ +void VisualBasicInfo::setProjectPrimaryLCID(std::uint32_t primLCID) +{ + projectPrimaryLCID = primLCID; + validProjectPrimaryLCID = true; +} + +/** + * Set project secondary LCID + * @param secLCID Project secondary LCID to set + */ +void VisualBasicInfo::setProjectSecondaryLCID(std::uint32_t secLCID) +{ + projectSecondaryLCID = secLCID; + validProjectSecondaryLCID = true; +} + +// /** +// * Set typeLib CLSID +// * @param tlbCLSID TypeLib CLSID to set +// */ +// void VisualBasicInfo::setTypeLibCLSID(std::uint32_t tlbCLSID) +// { +// typeLibCLSID = tlbCLSID; +// validTypeLibCLSID = true; +// } + +/** + * Set typeLib LCID + * @param tlbLCID TypeLib LCID to set + */ +void VisualBasicInfo::setTypeLibLCID(std::uint32_t tlbLCID) +{ + typeLibLCID = tlbLCID; + validTypeLibLCID = true; +} + +/** + * Add visual basic object + * @param obj Object to add + */ +void VisualBasicInfo::addObject(std::unique_ptr&& obj) +{ + objects.push_back(std::move(obj)); +} + +/** + * Add visual basic extern + * @param ext Extern to add + */ +void VisualBasicInfo::addExtern(std::unique_ptr&& ext) +{ + externs.push_back(std::move(ext)); +} + +/** + * Check if visual basic file has project name + * @return @c true if visual basic file has project name, @c false otherwise + */ +bool VisualBasicInfo::hasProjectName() const +{ + return !projectName.empty(); +} + +/** + * Check if visual basic file has project description + * @return @c true if visual basic file has project description, @c false otherwise + */ +bool VisualBasicInfo::hasProjectDescription() const +{ + return !projectDescription.empty(); +} + +/** + * Check if visual basic file has project help file + * @return @c true if visual basic file has project help file, @c false otherwise + */ +bool VisualBasicInfo::hasProjectHelpFile() const +{ + return !projectHelpFile.empty(); +} + + +} // namespace fileformat +} // namespace retdec diff --git a/src/fileformat/types/visual_basic/visual_basic_object.cpp b/src/fileformat/types/visual_basic/visual_basic_object.cpp new file mode 100644 index 000000000..100a1b048 --- /dev/null +++ b/src/fileformat/types/visual_basic/visual_basic_object.cpp @@ -0,0 +1,76 @@ +/** + * @file src/fileformat/types/visual_basic/visual_basic_object.cpp + * @brief Class visual basic object. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/fileformat/types/visual_basic/visual_basic_object.h" + +namespace retdec { +namespace fileformat { + +/** + * Constructor + */ +VisualBasicObject::VisualBasicObject() +{ + +} + +/** + * Destructor + */ +VisualBasicObject::~VisualBasicObject() +{ + +} + +/** + * Get name + * @return name + */ +const std::string &VisualBasicObject::getName() const +{ + return name; +} + +/** + * Get methods + * @return Object methods + */ +const std::vector &VisualBasicObject::getMethods() const +{ + return methods; +} + +/** + * Get number of methods + * @return number of methods + */ +std::size_t VisualBasicObject::getNumberOfMethods() const +{ + return methods.size(); +} + +/** + * Set name + * @param n Name to set + */ +void VisualBasicObject::setName(const std::string &n) +{ + name = n; +} + +/** + * Add method + * @param method Method to add + */ +void VisualBasicObject::addMethod(const std::string &method) +{ + methods.push_back(method); +} + + + +} // namespace fileformat +} // namespace retdec diff --git a/src/fileformat/types/visual_basic_header/visual_basic_header.cpp b/src/fileformat/types/visual_basic_header/visual_basic_header.cpp deleted file mode 100644 index f7d99bc2d..000000000 --- a/src/fileformat/types/visual_basic_header/visual_basic_header.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file src/fileformat/types/visual_basic_header/visual_basic_header.cpp - * @brief Class for visual basic header. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "retdec/fileformat/types/visual_basic_header/visual_basic_header.h" - -namespace retdec { -namespace fileformat { - -/** - * Constructor - */ -VisualBasicHeader::VisualBasicHeader() -{ - -} - -/** - * Destructor - */ -VisualBasicHeader::~VisualBasicHeader() -{ - -} - -/** - * Set header address - * @param address Header address to be set - */ -void VisualBasicHeader::setHeaderAddress(std::size_t address) -{ - headerAddress = address; -} - -} // namespace fileformat -} // namespace retdec diff --git a/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp b/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp deleted file mode 100644 index 55fe97fa0..000000000 --- a/src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file src/fileformat/types/visual_basic_header/visual_basic_project_info.cpp - * @brief Class for visual basic project info. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "retdec/fileformat/types/visual_basic_header/visual_basic_project_info.h" - -namespace retdec { -namespace fileformat { - -/** - * Constructor - */ -VisualBasicProjectInfo::VisualBasicProjectInfo() -{ - -} - -/** - * Destructor - */ -VisualBasicProjectInfo::~VisualBasicProjectInfo() -{ - -} - -} // namespace fileformat -} // namespace retdec From bf7494abee7016e21cdb451a30f609f67234769d Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 13 Dec 2018 00:18:59 +0100 Subject: [PATCH 05/33] string utils --- include/retdec/utils/string.h | 3 ++ src/utils/string.cpp | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/include/retdec/utils/string.h b/include/retdec/utils/string.h index 021d7e519..2b9c35dfb 100644 --- a/include/retdec/utils/string.h +++ b/include/retdec/utils/string.h @@ -51,6 +51,9 @@ std::string toLower(std::string str); std::string toUpper(std::string str); std::string toWide(const std::string &str, std::string::size_type length); +std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes); +std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t maxBytes, + std::size_t offset = 0); std::string trim(std::string str, const std::string &toTrim = " \t\r\n\v"); diff --git a/src/utils/string.cpp b/src/utils/string.cpp index cdbba0115..822b0c514 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -404,6 +404,73 @@ std::string toWide(const std::string &str, std::string::size_type length) { return result; } +/** +* @brief Converts unicode @a bytes to ASCII string. +* +* @param[in] bytes Bytes for conversion. +* @param[in] nBytes Number of bytes. +* +* @return Converted string in ASCII. +*/ +std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) +{ + std::stringstream result; + if (!bytes || !nBytes) + { + return ""; + } + if (nBytes & 1) + { + nBytes--; + } + + for (std::size_t i = 0; i < nBytes; i += 2) + { + if (bytes[i] == 0 && bytes[i + 1] == 0) + { + break; + } + if (bytes[i + 1] == 0 && isPrintableChar(bytes[i])) + { + result << bytes[i]; + } + else + { + const std::size_t maxC = std::pow(2, sizeof(std::string::value_type) * CHAR_BIT) - 1; + const auto val1 = numToStr(bytes[i] & maxC, std::hex); + const auto val2 = numToStr(bytes[i + 1] & maxC, std::hex); + result << "\\x" << std::setw(2) << std::setfill('0') << val1; + result << "\\x" << std::setw(2) << std::setfill('0') << val2; + } + } + + return result.str(); +} + +/** +* @brief Read up to @a maxBytes bytes as ASCII string. +* +* @param[in] bytes Bytes to read from. +* @param[in] maxBytes Maximum bytes to read. +* @param[in] offset Offset in bytes. +* +* @return Converted string in ASCII. +*/ +std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t maxBytes, std::size_t offset) +{ + std::string result; + if (!bytes) + { + return ""; + } + for (std::size_t i = offset; i < maxBytes && bytes[i]; i++) + { + result.push_back(bytes[i]); + } + + return replaceNonprintableChars(result); +} + /** * @brief Trims the given string. * From 38f4512ec98fac2ff8bd9417aa4c1dffa2306cb2 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 13 Dec 2018 13:07:02 +0100 Subject: [PATCH 06/33] etern table plain presentation --- include/retdec/fileformat/fftypes.h | 1 - .../fileformat/file_format/file_format.h | 1 - .../fileformat/file_format/pe/pe_format.h | 3 + src/fileformat/file_format/file_format.cpp | 2 - src/fileformat/file_format/pe/pe_format.cpp | 58 ++--- src/fileinfo/CMakeLists.txt | 1 + src/fileinfo/file_detector/pe_detector.cpp | 15 ++ src/fileinfo/file_detector/pe_detector.h | 1 + .../file_information/file_information.cpp | 204 ++++++++++++++++++ .../file_information/file_information.h | 26 +++ .../visual_basic_info.cpp | 43 +++- .../visual_basic_info.h | 5 + ...visual_basic_extern_table_plain_getter.cpp | 99 +++++++++ .../visual_basic_extern_table_plain_getter.h | 31 +++ .../file_presentation/getters/plain_getters.h | 1 + .../file_presentation/plain_presentation.cpp | 1 + 16 files changed, 462 insertions(+), 30 deletions(-) create mode 100644 src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp create mode 100644 src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h diff --git a/include/retdec/fileformat/fftypes.h b/include/retdec/fileformat/fftypes.h index fa4be530e..3ea50776c 100644 --- a/include/retdec/fileformat/fftypes.h +++ b/include/retdec/fileformat/fftypes.h @@ -24,7 +24,6 @@ #include "retdec/fileformat/types/resource_table/resource_icon.h" #include "retdec/fileformat/types/resource_table/resource_icon_group.h" #include "retdec/fileformat/types/rich_header/rich_header.h" -#include "retdec/fileformat/types/visual_basic/visual_basic_info.h" #include "retdec/fileformat/types/sec_seg/elf_section.h" #include "retdec/fileformat/types/sec_seg/elf_segment.h" #include "retdec/fileformat/types/sec_seg/macho_section.h" diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index 66457d260..4b2b7efd6 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -81,7 +81,6 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils ResourceTable *resourceTable; ///< table of resources ResourceTree *resourceTree; ///< structure of resource tree RichHeader *richHeader; ///< rich header - VisualBasicInfo *visualBasicInfo; ///< visual basic header information PdbInfo *pdbInfo; ///< information about related PDB debug file CertificateTable *certificateTable; ///< table of certificates ElfCoreInfo *elfCoreInfo; ///< information about core file structures diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index 9c529fdde..df0f571a1 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -18,6 +18,7 @@ #include "retdec/fileformat/types/dotnet_headers/string_stream.h" #include "retdec/fileformat/types/dotnet_headers/user_string_stream.h" #include "retdec/fileformat/types/dotnet_types/dotnet_class.h" +#include "retdec/fileformat/types/visual_basic/visual_basic_info.h" namespace retdec { namespace fileformat { @@ -44,6 +45,7 @@ class PeFormat : public FileFormat std::string typeRefHashCrc32; ///< .NET typeref table hash as CRC32 std::string typeRefHashMd5; ///< .NET typeref table hash as MD5 std::string typeRefHashSha256; ///< .NET typeref table hash as SHA256 + VisualBasicInfo visualBasicInfo; ///< visual basic header information /// @name Initialization methods /// @{ @@ -191,6 +193,7 @@ class PeFormat : public FileFormat const std::string& getTypeRefhashCrc32() const; const std::string& getTypeRefhashMd5() const; const std::string& getTypeRefhashSha256() const; + const VisualBasicInfo* getVisualBasicInfo() const; /// @} }; diff --git a/src/fileformat/file_format/file_format.cpp b/src/fileformat/file_format/file_format.cpp index b548d7f12..fe50fbeaf 100644 --- a/src/fileformat/file_format/file_format.cpp +++ b/src/fileformat/file_format/file_format.cpp @@ -185,7 +185,6 @@ void FileFormat::init() resourceTable = nullptr; resourceTree = nullptr; richHeader = nullptr; - visualBasicInfo = nullptr; pdbInfo = nullptr; certificateTable = nullptr; elfCoreInfo = nullptr; @@ -231,7 +230,6 @@ void FileFormat::clear() delete resourceTable; delete resourceTree; delete richHeader; - delete visualBasicInfo; delete pdbInfo; delete certificateTable; delete elfCoreInfo; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 762b70d93..932b0ec08 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -730,30 +730,29 @@ void PeFormat::loadVisualBasicHeader() std::cout << "[KUBO] VB header size:" << std::to_string(vbh.headerSize()) << "\n"; vbh.dump(std::cout); - visualBasicInfo = new VisualBasicInfo(); if (vbh.projExeNameOffset != 0) { projExeName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), vbHeaderOffset + vbh.projExeNameOffset); - visualBasicInfo->setProjectExeName(projExeName); + visualBasicInfo.setProjectExeName(projExeName); } if (vbh.projDescOffset != 0) { projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), vbHeaderOffset + vbh.projDescOffset); - visualBasicInfo->setProjectDescription(projDesc); + visualBasicInfo.setProjectDescription(projDesc); } if (vbh.helpFileOffset != 0) { helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), vbHeaderOffset + vbh.helpFileOffset); - visualBasicInfo->setProjectHelpFile(helpFile); + visualBasicInfo.setProjectHelpFile(helpFile); } if (vbh.projNameOffset != 0) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), vbHeaderOffset + vbh.projNameOffset); - visualBasicInfo->setProjectName(projName); + visualBasicInfo.setProjectName(projName); } std::cout << "KUBO KING: " << projExeName << " | " << projDesc << " | " << helpFile << " | " @@ -767,10 +766,10 @@ void PeFormat::loadVisualBasicHeader() { projBackupLanguageDLL.push_back(vbh.backupLanguageDLL[i]); } - visualBasicInfo->setLanguageDLL(projLanguageDLL); - visualBasicInfo->setBackupLanguageDLL(projBackupLanguageDLL); - visualBasicInfo->setLanguageDLLPrimaryLCID(vbh.LCID1); - visualBasicInfo->setLanguageDLLSecondaryLCID(vbh.LCID2); + visualBasicInfo.setLanguageDLL(projLanguageDLL); + visualBasicInfo.setBackupLanguageDLL(projBackupLanguageDLL); + visualBasicInfo.setLanguageDLLPrimaryLCID(vbh.LCID1); + visualBasicInfo.setLanguageDLLSecondaryLCID(vbh.LCID2); std::cout << "KUBO KING: " << projLanguageDLL << " | " << projBackupLanguageDLL << "\n\n"; @@ -829,19 +828,19 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); } - // visualBasicInfo->setTypeLibCLSID(vbcrd.projCLSID); TODO - visualBasicInfo->setTypeLibLCID(vbcrd.projDescOffset); - if (!visualBasicInfo->hasProjectName()) + // visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); TODO + visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); + if (!visualBasicInfo.hasProjectName()) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.projNameOffset); } - if (!visualBasicInfo->hasProjectHelpFile()) + if (!visualBasicInfo.hasProjectHelpFile()) { helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.helpFileOffset); } - if (!visualBasicInfo->hasProjectDescription()) + if (!visualBasicInfo.hasProjectDescription()) { projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.projDescOffset); @@ -906,7 +905,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz } projPath = retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)); - visualBasicInfo->setProjectPath(projPath); + visualBasicInfo.setProjectPath(projPath); std::cout << "[KUBO] VB project info size: " << std::to_string(vbpi.headerSize()) << "\n"; std::cout << "[KUBO] path: " << retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)) << "\n"; @@ -915,7 +914,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz if (vbpi.externalTableAddr >= baseAddress) { vbExternTableOffset = vbpi.externalTableAddr - baseAddress; - parseVisualBasicExternTable(vbExternTableOffset, vbpi.nExternals, baseAddress); + parseVisualBasicExternTable(vbExternTableOffset, baseAddress, vbpi.nExternals); } if (vbpi.objectTableAddr >= baseAddress) @@ -965,6 +964,8 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz entry.importDataAddr = byteSwap32(entry.importDataAddr); } + // std::cerr << "Entry type: " << entry.type << "\n"; + if (entry.type != static_cast(VBExternTableEntryType::external) || entry.importDataAddr < baseAddress) { @@ -1004,9 +1005,12 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz auto ext = std::make_unique(); ext->setModuleName(moduleName); ext->setApiName(apiName); - visualBasicInfo->addExtern(std::move(ext)); - std::cout << "[KUBO] moduleName: " << moduleName << "\n"; - std::cout << "[KUBO] apiName: " << apiName << "\n"; + // std::cerr << "[<3] " << ext->getModuleName() << "\n"; + // std::cerr << "[<3] " << ext->getApiName() << "\n"; + visualBasicInfo.addExtern(std::move(ext)); + // std::cerr << "[<3] " << visualBasicInfo.getNumberOfExterns() << "\n"; + // std::cout << "[KUBO] moduleName: " << moduleName << "\n"; + // std::cout << "[KUBO] apiName: " << apiName << "\n"; } return true; @@ -1077,17 +1081,17 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz vbot.templateVesion = byteSwap32(vbot.templateVesion); } - visualBasicInfo->setProjectPrimaryLCID(vbot.LCID1); - visualBasicInfo->setProjectSecondaryLCID(vbot.LCID2); + visualBasicInfo.setProjectPrimaryLCID(vbot.LCID1); + visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); // TODO KUBO GUID std::cout << "[KUBO] VB object table size: " << std::to_string(vbot.structureSize()) << "\n"; - if (!visualBasicInfo->hasProjectName() && vbot.projectNameAddr >= baseAddress) + if (!visualBasicInfo.hasProjectName() && vbot.projectNameAddr >= baseAddress) { projectNameOffset = vbot.projectNameAddr - baseAddress; projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset); - visualBasicInfo->setProjectName(projName); + visualBasicInfo.setProjectName(projName); std::cout << "[KUBO] Project name: " << projName << "\n"; } vbot.dump(std::cout); @@ -1198,7 +1202,7 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t } } - visualBasicInfo->addObject(std::move(object)); + visualBasicInfo.addObject(std::move(object)); std::cout << "\n[KUBO] object" << i << "\n"; vbpod.dump(std::cout); } @@ -3322,7 +3326,6 @@ const std::vector>& PeFormat::getImportedDotnetClas return importedClasses; } - const std::string& PeFormat::getTypeRefhashCrc32() const { return typeRefHashCrc32; @@ -3338,5 +3341,10 @@ const std::string& PeFormat::getTypeRefhashSha256() const return typeRefHashSha256; } +const VisualBasicInfo* PeFormat::getVisualBasicInfo() const +{ + return &visualBasicInfo; +} + } // namespace fileformat } // namespace retdec diff --git a/src/fileinfo/CMakeLists.txt b/src/fileinfo/CMakeLists.txt index ae4c4acf9..bfd50ae31 100644 --- a/src/fileinfo/CMakeLists.txt +++ b/src/fileinfo/CMakeLists.txt @@ -52,6 +52,7 @@ set(FILEINFO_SOURCES file_presentation/getters/iterative_getter/iterative_distribution_getter/relocation_tables_plain_getter.cpp file_presentation/getters/iterative_getter/iterative_distribution_getter/resource_plain_getter.cpp file_presentation/getters/iterative_getter/iterative_distribution_getter/rich_header_plain_getter.cpp + file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp file_presentation/getters/iterative_getter/iterative_distribution_getter/section_plain_getter.cpp file_presentation/getters/iterative_getter/iterative_distribution_getter/segment_plain_getter.cpp file_presentation/getters/iterative_getter/iterative_distribution_getter/strings_plain_getter.cpp diff --git a/src/fileinfo/file_detector/pe_detector.cpp b/src/fileinfo/file_detector/pe_detector.cpp index 4085ebff4..3b77a1915 100644 --- a/src/fileinfo/file_detector/pe_detector.cpp +++ b/src/fileinfo/file_detector/pe_detector.cpp @@ -337,6 +337,20 @@ void PeDetector::getDotnetInfo() fileInfo.setDotnetTypeRefhashSha256(peParser->getTypeRefhashSha256()); } +/** + * Get information about .NET + */ +void PeDetector::getVisualBasicInfo() +{ + unsigned long long version; + if (!peParser->isVisualBasic(version)) + { + return; + } + fileInfo.setVisualBasicUsed(true); + fileInfo.setVisualBasicInfo(peParser->getVisualBasicInfo()); +} + void PeDetector::detectFileClass() { switch(peParser->getPeClass()) @@ -494,6 +508,7 @@ void PeDetector::getAdditionalInfo() getCoffSymbols(); getRelocationTableInfo(); getDotnetInfo(); + getVisualBasicInfo(); /* In future we can detect more information about PE files: - TimeDateStamp diff --git a/src/fileinfo/file_detector/pe_detector.h b/src/fileinfo/file_detector/pe_detector.h index b39ea8b48..9f88a67db 100644 --- a/src/fileinfo/file_detector/pe_detector.h +++ b/src/fileinfo/file_detector/pe_detector.h @@ -30,6 +30,7 @@ class PeDetector : public FileDetector void getDirectories(); void getSections(); void getDotnetInfo(); + void getVisualBasicInfo(); /// @} protected: /// @name Detection methods diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index eaad8df13..e8d67fff3 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -781,6 +781,192 @@ bool FileInformation::hasRichHeaderRecords() const return richHeader.hasRecords(); } + + + + +/** + * Check whether visual basic informations are used. + * @return @c true if it is used, otherwise @c false/ + */ +bool FileInformation::isVisualBasicUsed() const +{ + return visualBasicInfo.isUsed(); +} + +/** + * Get visual basic language DLL + * @return Visual basic language DLL + */ +std::string FileInformation::getVisualBasicLanguageDLL() const +{ + return visualBasicInfo.getLanguageDLL(); +} + +/** + * Get visual basic backup language DLL + * @return Visual basic backup language DLL + */ +std::string FileInformation::getVisualBasicBackupLanguageDLL() const +{ + return visualBasicInfo.getBackupLanguageDLL(); +} + +/** + * Get visual basic project exe name + * @return Visual basic project exe name + */ +std::string FileInformation::getVisualBasicProjectExeName() const +{ + return visualBasicInfo.getProjectExeName(); +} + +/** + * Get visual basic project description + * @return Visual basic project description + */ +std::string FileInformation::getVisualBasicProjectDescription() const +{ + return visualBasicInfo.getProjectDescription(); +} + +/** + * Get visual basic project help file + * @return Visual basic project help file + */ +std::string FileInformation::getVisualBasicProjectHelpFile() const +{ + return visualBasicInfo.getProjectHelpFile(); +} + +/** + * Get visual basic project name + * @return Visual basic project name + */ +std::string FileInformation::getVisualBasicProjectName() const +{ + return visualBasicInfo.getProjectName(); +} + +/** + * Get visual basic language DLL primary LCID + * @return Visual basic language DLL primary LCID + */ +std::string FileInformation::getVisualBasicLanguageDLLPrimaryLCIDStr() const +{ + return visualBasicInfo.getLanguageDLLPrimaryLCIDStr(); +} + +/** + * Get visual basic language DLL secondary LCID + * @return Visual basic language DLL secondary LCID + */ +std::string FileInformation::getVisualBasicLanguageDLLSecondaryLCIDStr() const +{ + return visualBasicInfo.getLanguageDLLSecondaryLCIDStr(); +} + +/** + * Get visual basic project path + * @return Visual basic project path + */ +std::string FileInformation::getVisualBasicProjectPath() const +{ + return visualBasicInfo.getProjectPath(); +} + +/** + * Get visual basic project primary LCID + * @return Visual basic project primary LCID + */ +std::string FileInformation::getVisualBasicProjectPrimaryLCIDStr() const +{ + return visualBasicInfo.getProjectPrimaryLCIDStr(); +} + +/** + * Get visual basic project secondary LCID + * @return Visual basic project secondary LCID + */ +std::string FileInformation::getVisualBasicProjectSecondaryLCIDStr() const +{ + return visualBasicInfo.getProjectSecondaryLCIDStr(); +} + +/** + * Get visual basic object + * @param position Index of selected object (indexed from 0) + * @return Visual basic object + */ +const retdec::fileformat::VisualBasicObject *FileInformation::getVisualBasicObject(std::size_t position) const +{ + return visualBasicInfo.getObject(position); +} + +/** + * Get visual basic extern + * @param position Index of selected extern (indexed from 0) + * @return Visual basic extern + */ +const retdec::fileformat::VisualBasicExtern *FileInformation::getVisualBasicExtern(std::size_t position) const +{ + return visualBasicInfo.getExtern(position); +} + +/** + * Get visual basic number of objects + * @return Visual basic number of objects + */ +std::size_t FileInformation::getVisualBasicNumberOfObjects() const +{ + return visualBasicInfo.getNumberOfObjects(); +} + +/** + * Get visual basic number of externs + * @return Visual basic number of externs + */ +std::size_t FileInformation::getVisualBasicNumberOfExterns() const +{ + return visualBasicInfo.getNumberOfExterns(); +} + +/** + * Get visual basic extern module name + * @param position Index of selected extern (indexed from 0) + * @return Visual basic extern module name + */ +std::string FileInformation::getVisualBasicExternModuleName(std::size_t position) const +{ + return visualBasicInfo.getExternModuleName(position); +} + +/** + * Get visual basic extern api name + * @param position Index of selected extern (indexed from 0) + * @return Visual basic extern api name + */ +std::string FileInformation::getVisualBasicExternApiName(std::size_t position) const +{ + return visualBasicInfo.getExternApiName(position); +} + +/** + * Get visual basic typeLib LCID + * @return Visual basic typeLib LCID + */ +std::string FileInformation::getVisualBasicTypeLibLCIDStr() const +{ + return visualBasicInfo.getTypeLibLCIDStr(); +} + + + + + + + + /** * Get type of related PDB file * @return Type of related PDB file @@ -3597,6 +3783,24 @@ void FileInformation::setRichHeader(const retdec::fileformat::RichHeader *rHeade richHeader.setHeader(rHeader); } +/** + * Set visual basic information + * @param vbInfo Information about visual basic + */ +void FileInformation::setVisualBasicInfo(const retdec::fileformat::VisualBasicInfo *vbInfo) +{ + visualBasicInfo.setInfo(vbInfo); +} + +/** + * Sets whether visual basic informations are used. + * @param set @c true if used, otherwise @c false. + */ +void FileInformation::setVisualBasicUsed(bool set) +{ + visualBasicInfo.setUsed(set); +} + /** * Set type of related PDB file * @param sType Type of related PDB file diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 9a610f648..23c34f218 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -153,6 +153,30 @@ class FileInformation bool hasRichHeaderRecords() const; /// @} + /// @name Getters of @a visualBasicInfo + /// @{ + bool isVisualBasicUsed() const; + std::string getVisualBasicLanguageDLL() const; + std::string getVisualBasicBackupLanguageDLL() const; + std::string getVisualBasicProjectExeName() const; + std::string getVisualBasicProjectDescription() const; + std::string getVisualBasicProjectHelpFile() const; + std::string getVisualBasicProjectName() const; + std::string getVisualBasicLanguageDLLPrimaryLCIDStr() const; + std::string getVisualBasicLanguageDLLSecondaryLCIDStr() const; + std::string getVisualBasicProjectPath() const; + std::string getVisualBasicProjectPrimaryLCIDStr() const; + std::string getVisualBasicProjectSecondaryLCIDStr() const; + const retdec::fileformat::VisualBasicObject *getVisualBasicObject(std::size_t position) const; + const retdec::fileformat::VisualBasicExtern *getVisualBasicExtern(std::size_t position) const; + std::size_t getVisualBasicNumberOfObjects() const; + std::size_t getVisualBasicNumberOfExterns() const; + std::string getVisualBasicExternModuleName(std::size_t position) const; + std::string getVisualBasicExternApiName(std::size_t position) const; + std::string getVisualBasicTypeLibLCIDStr() const; + /// @} + + /// @name Getters of @a pdbInfo /// @{ std::string getPdbType() const; @@ -511,6 +535,8 @@ class FileInformation void setOverlayOffset(unsigned long long offset); void setOverlaySize(unsigned long long size); void setRichHeader(const retdec::fileformat::RichHeader *rHeader); + void setVisualBasicInfo(const retdec::fileformat::VisualBasicInfo *vbInfo); + void setVisualBasicUsed(bool set); void setPdbType(const std::string &sType); void setPdbPath(const std::string &sPath); void setPdbGuid(const std::string &sGuid); diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index f5e40b8c5..201fb13c5 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -14,7 +14,7 @@ namespace fileinfo { /** * Constructor */ -VisualBasicInfo::VisualBasicInfo() : visualBasicInfo(nullptr) +VisualBasicInfo::VisualBasicInfo() : used(false), visualBasicInfo(nullptr) { } @@ -184,6 +184,29 @@ std::size_t VisualBasicInfo::getNumberOfExterns() const return visualBasicInfo ? visualBasicInfo->getNumberOfExterns() : 0; } +/** + * Get extern module name + * @param position Index of selected visual basic extern (indexed from 0) + * @return Extern module name + */ +std::string VisualBasicInfo::getExternModuleName(std::size_t position) const +{ + auto ext = getExtern(position); + return ext ? ext->getModuleName() : ""; +} + +/** + * Get extern api name + * @param position Index of selected visual basic extern (indexed from 0) + * @return Extern api name + */ +std::string VisualBasicInfo::getExternApiName(std::size_t position) const +{ + auto ext = getExtern(position); + return ext ? ext->getApiName() : ""; +} + + // /** // * Get typeLib CLSID // * @return Visual basic typeLib CLSID as string @@ -221,4 +244,22 @@ void VisualBasicInfo::setInfo(const retdec::fileformat::VisualBasicInfo *vbInfo) visualBasicInfo = vbInfo; } +/** + * Set whether visual basic info is used. + * @param set @c true if used, @c false otherwise. + */ +void VisualBasicInfo::setUsed(bool set) +{ + used = set; +} + +/** + * Check whether visual basic informations are used. + * @return @c true if used, otherwise @c false. + */ +bool VisualBasicInfo::isUsed() const +{ + return used; +} + } // namespace fileinfo diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h index 72c8ba7f6..9fe27c1b5 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.h +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -19,6 +19,7 @@ namespace fileinfo { class VisualBasicInfo { private: + bool used; const retdec::fileformat::VisualBasicInfo *visualBasicInfo; public: VisualBasicInfo(); @@ -41,6 +42,8 @@ class VisualBasicInfo const retdec::fileformat::VisualBasicExtern *getExtern(std::size_t position) const; std::size_t getNumberOfObjects() const; std::size_t getNumberOfExterns() const; + std::string getExternModuleName(std::size_t position) const; + std::string getExternApiName(std::size_t position) const; // std::string getTypeLibCLSIDStr() const; std::string getTypeLibLCIDStr() const; /// @} @@ -48,10 +51,12 @@ class VisualBasicInfo /// @name Setters /// @{ void setInfo(const retdec::fileformat::VisualBasicInfo *vbInfo); + void setUsed(bool set); /// @} /// @name Other methods /// @{ + bool isUsed() const; /// @} }; diff --git a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp new file mode 100644 index 000000000..7e2833b73 --- /dev/null +++ b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp @@ -0,0 +1,99 @@ +/** + * @file src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h + * @brief Definition of VisualBasicExternTablePlainGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/utils/conversion.h" +#include "retdec/utils/string.h" +#include "retdec/fileformat/utils/conversions.h" +#include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h" + +using namespace retdec::utils; +using namespace retdec::fileformat; + +namespace fileinfo { + +namespace +{ + +const std::size_t distributionArray[] = {6, 40, 40}; +const std::string headerArray[] = {"i", "apiName", "moduleName"}; +const std::string headerDesc[] = {"index", "api name of extern", "module name of extern"}; + +} // anonymous namespace + +/** + * Constructor + * @param fileInfo Information about file + */ +VisualBasicExternTablePlainGetter::VisualBasicExternTablePlainGetter(FileInformation &fileInfo) : IterativeDistributionGetter(fileInfo) +{ + numberOfStructures = 1; + numberOfStoredRecords.push_back(fileinfo.getVisualBasicNumberOfExterns()); + numberOfExtraElements.push_back(0); + title = "Visual basic extern table"; + distribution.insert(distribution.begin(), std::begin(distributionArray), std::end(distributionArray)); + commonHeaderElements.insert(commonHeaderElements.begin(), std::begin(headerArray), std::end(headerArray)); + commonHeaderDesc.insert(commonHeaderDesc.begin(), std::begin(headerDesc), std::end(headerDesc)); + loadRecords(); +} + +/** + * Destructor + */ +VisualBasicExternTablePlainGetter::~VisualBasicExternTablePlainGetter() +{ + +} + +std::size_t VisualBasicExternTablePlainGetter::getBasicInfo(std::size_t structIndex, std::vector &desc, std::vector &info) const +{ + if(structIndex >= numberOfStructures || !fileinfo.isVisualBasicUsed()) + { + return 0; + } + + desc.clear(); + info.clear(); + + desc.push_back("Number of visual basic externs: "); + desc.push_back("CRC32 : "); + desc.push_back("MD5 : "); + desc.push_back("SHA256 : "); + info.push_back(numToStr(fileinfo.getVisualBasicNumberOfExterns())); + info.push_back("TODO"); + info.push_back("TODO"); + info.push_back("TODO"); + + return info.size(); +} + +bool VisualBasicExternTablePlainGetter::loadRecord(std::size_t structIndex, std::size_t recIndex, std::vector &record) +{ + if(structIndex >= numberOfStructures || recIndex >= numberOfStoredRecords[structIndex]) + { + return false; + } + + record.clear(); + record.push_back(numToStr(recIndex)); + record.push_back(replaceNonprintableChars(fileinfo.getVisualBasicExternApiName(recIndex))); + record.push_back(replaceNonprintableChars(fileinfo.getVisualBasicExternModuleName(recIndex))); + return true; +} + +bool VisualBasicExternTablePlainGetter::getFlagDescriptors(std::size_t structIndex, std::vector &desc, std::vector &abbv) const +{ + if(structIndex >= numberOfStructures) + { + return false; + } + + desc.clear(); + abbv.clear(); + + return true; +} + +} // namespace fileinfo diff --git a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h new file mode 100644 index 000000000..24533f90e --- /dev/null +++ b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h @@ -0,0 +1,31 @@ +/** + * @file src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h + * @brief Definition of VisualBasicExternTablePlainGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef FILEINFO_FILE_PRESENTATION_GETTERS_ITERATIVE_GETTER_ITERATIVE_DISTRIBUTION_GETTER_VISUAL_BASIC_EXTERN_TABLE_PLAIN_GETTER_H +#define FILEINFO_FILE_PRESENTATION_GETTERS_ITERATIVE_GETTER_ITERATIVE_DISTRIBUTION_GETTER_VISUAL_BASIC_EXTERN_TABLE_PLAIN_GETTER_H + +#include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/iterative_distribution_getter.h" + +namespace fileinfo { + +/** + * Getter for visual basic objects + */ +class VisualBasicExternTablePlainGetter : public IterativeDistributionGetter +{ + protected: + virtual bool loadRecord(std::size_t structIndex, std::size_t recIndex, std::vector &record) override; + public: + VisualBasicExternTablePlainGetter(FileInformation &fileInfo); + virtual ~VisualBasicExternTablePlainGetter() override; + + virtual std::size_t getBasicInfo(std::size_t structIndex, std::vector &desc, std::vector &info) const override; + virtual bool getFlagDescriptors(std::size_t structIndex, std::vector &desc, std::vector &abbv) const override; +}; + +} // namespace fileinfo + +#endif diff --git a/src/fileinfo/file_presentation/getters/plain_getters.h b/src/fileinfo/file_presentation/getters/plain_getters.h index 25cc964b0..f71dec2d5 100644 --- a/src/fileinfo/file_presentation/getters/plain_getters.h +++ b/src/fileinfo/file_presentation/getters/plain_getters.h @@ -25,6 +25,7 @@ #include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/symbol_tables_plain_getter.h" #include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/typeref_table_plain_getter.h" #include "fileinfo/file_presentation/getters/iterative_getter/iterative_simple_getter/certificate_table_plain_getter.h" +#include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/dotnet_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/header_plain_getter.h" diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index d8ebeb02f..5437df857 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -704,6 +704,7 @@ bool PlainPresentation::present() presentIterativeDistribution(ImportTablePlainGetter(fileinfo), explanatory); presentIterativeDistribution(ExportTablePlainGetter(fileinfo), explanatory); presentIterativeDistribution(TypeRefTablePlainGetter(fileinfo), explanatory); + presentIterativeDistribution(VisualBasicExternTablePlainGetter(fileinfo), explanatory); presentIterativeDistribution(RelocationTablesPlainGetter(fileinfo), explanatory); presentIterativeDistribution(DynamicSectionsPlainGetter(fileinfo), explanatory); presentIterativeDistribution(ResourcePlainGetter(fileinfo), explanatory); From 775f5250f568179cab02a55e29357d4629175389 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 13 Dec 2018 14:29:22 +0100 Subject: [PATCH 07/33] Visual Basic Objects presentation --- src/fileinfo/CMakeLists.txt | 1 + .../file_presentation/getters/plain_getters.h | 1 + .../visual_basic_plain_getter.cpp | 49 +++++++++++++++++++ .../simple_getter/visual_basic_plain_getter.h | 28 +++++++++++ .../file_presentation/plain_presentation.cpp | 32 ++++++++++++ .../file_presentation/plain_presentation.h | 1 + 6 files changed, 112 insertions(+) create mode 100644 src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp create mode 100644 src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h diff --git a/src/fileinfo/CMakeLists.txt b/src/fileinfo/CMakeLists.txt index bfd50ae31..224178ee2 100644 --- a/src/fileinfo/CMakeLists.txt +++ b/src/fileinfo/CMakeLists.txt @@ -81,6 +81,7 @@ set(FILEINFO_SOURCES file_presentation/getters/simple_getter/basic_plain_getter.cpp file_presentation/getters/simple_getter/dotnet_json_getter.cpp file_presentation/getters/simple_getter/dotnet_plain_getter.cpp + file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp file_presentation/getters/simple_getter/entry_point_json_getter.cpp file_presentation/getters/simple_getter/header_json_getter.cpp file_presentation/getters/simple_getter/header_plain_getter.cpp diff --git a/src/fileinfo/file_presentation/getters/plain_getters.h b/src/fileinfo/file_presentation/getters/plain_getters.h index f71dec2d5..8a01af36d 100644 --- a/src/fileinfo/file_presentation/getters/plain_getters.h +++ b/src/fileinfo/file_presentation/getters/plain_getters.h @@ -28,6 +28,7 @@ #include "fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/dotnet_plain_getter.h" +#include "fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/header_plain_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/pdb_plain_getter.h" diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp new file mode 100644 index 000000000..2c1852a83 --- /dev/null +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -0,0 +1,49 @@ +/** + * @file src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp + * @brief Methods of VisualBasicPlainGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/fileformat/utils/conversions.h" +#include "fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h" + +using namespace retdec::fileformat; + +namespace fileinfo { + +/** + * Constructor + * @param fileInfo Information about file + */ +VisualBasicPlainGetter::VisualBasicPlainGetter(FileInformation &fileInfo) : SimpleGetter(fileInfo) +{ + +} + +/** + * Destructor + */ +VisualBasicPlainGetter::~VisualBasicPlainGetter() +{ + +} + +std::size_t VisualBasicPlainGetter::loadInformation(std::vector &desc, std::vector &info) const +{ + desc.clear(); + info.clear(); + + if (!fileinfo.isVisualBasicUsed()) + { + return 0; + } + + desc.push_back("Super Cool Info : "); + desc.push_back("More Super Cool Info : "); + info.push_back("TODO"); + info.push_back("TODO"); + + return info.size(); +} + +} // namespace fileinfo diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h new file mode 100644 index 000000000..03afdc4e3 --- /dev/null +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h @@ -0,0 +1,28 @@ +/** + * @file src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h + * @brief Definition of VisualBasicPlainGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef FILEINFO_FILE_PRESENTATION_GETTERS_SIMPLE_GETTER_VISUAL_BASIC_PLAIN_GETTER_H +#define FILEINFO_FILE_PRESENTATION_GETTERS_SIMPLE_GETTER_VISUAL_BASIC_PLAIN_GETTER_H + +#include "fileinfo/file_presentation/getters/simple_getter/simple_getter.h" + +namespace fileinfo { + +/** + * Getter for information about visual basic + */ +class VisualBasicPlainGetter : public SimpleGetter +{ + public: + VisualBasicPlainGetter(FileInformation &fileInfo); + virtual ~VisualBasicPlainGetter() override; + + virtual std::size_t loadInformation(std::vector &desc, std::vector &info) const override; +}; + +} // namespace fileinfo + +#endif diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index 5437df857..9f7ba96bc 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -627,6 +627,36 @@ void PlainPresentation::presentDotnetClasses() const } } +void PlainPresentation::presentVisualBasicObjects() const +{ + auto nObjs = fileinfo.getVisualBasicNumberOfObjects(); + if (!fileinfo.isVisualBasicUsed() || nObjs == 0) + { + return; + } + + std::cout << "\n"; + std::cout << "Visual Basic objects" << "\n"; + for (std::size_t i = 0; i < nObjs; i++) + { + auto obj = fileinfo.getVisualBasicObject(i); + if (!obj) + { + continue; + } + auto objName = obj->getName(); + if (objName.empty()) + { + continue; + } + std::cout << " object name: " << objName << "\n"; + for (const auto &m : obj->getMethods()) + { + std::cout << " method name: " << m << "\n"; + } + } +} + /** * Present ELF notes */ @@ -729,6 +759,8 @@ bool PlainPresentation::present() presentIterativeSimple(CertificateTablePlainGetter(fileinfo)); presentSimple(DotnetPlainGetter(fileinfo), false, ".NET Information"); presentDotnetClasses(); + presentSimple(VisualBasicPlainGetter(fileinfo), false, "Visual Basic Information"); + presentVisualBasicObjects(); if(returnCode != ReturnCode::FILE_NOT_EXIST && returnCode != ReturnCode::UNKNOWN_FORMAT) { diff --git a/src/fileinfo/file_presentation/plain_presentation.h b/src/fileinfo/file_presentation/plain_presentation.h index 76a74e4c0..3196d24db 100644 --- a/src/fileinfo/file_presentation/plain_presentation.h +++ b/src/fileinfo/file_presentation/plain_presentation.h @@ -30,6 +30,7 @@ class PlainPresentation : public FilePresentation void presentSimpleFlags(const std::string &title, const std::string &flags, const std::vector &desc, const std::vector &abbv) const; void presentPatterns(const std::string &title, const std::vector &patterns); void presentDotnetClasses() const; + void presentVisualBasicObjects() const; void presentNotes() const; void presentCore() const; /// @} From d3e3ef0236778c211bf95cba4e227b56ad7f364e Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Tue, 18 Dec 2018 10:46:32 +0100 Subject: [PATCH 08/33] some more presentation --- .../types/visual_basic/visual_basic_info.h | 3 +++ src/fileformat/file_format/pe/pe_format.cpp | 1 + .../types/visual_basic/visual_basic_info.cpp | 20 +++++++++++++++++- .../visual_basic_info.cpp | 10 +++++++++ .../visual_basic_info.h | 1 + .../visual_basic_plain_getter.cpp | 21 +++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h index 453a0bfc6..dd14154e8 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -55,6 +55,7 @@ class VisualBasicInfo bool validProjectSecondaryLCID; // bool validTypeLibCLSID; bool validTypeLibLCID; + bool pcodeFlag; public: VisualBasicInfo(); @@ -98,6 +99,7 @@ class VisualBasicInfo void setProjectSecondaryLCID(std::uint32_t secLCID); // void setTypeLibCLSID(std::uint32_t tlbCLSID); void setTypeLibLCID(std::uint32_t tlbLCID); + void setPcode(bool set); /// @} /// @name Other methods @@ -107,6 +109,7 @@ class VisualBasicInfo bool hasProjectName() const; bool hasProjectDescription() const; bool hasProjectHelpFile() const; + bool isPcode() const; /// @} }; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 932b0ec08..78c631fd6 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -906,6 +906,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz projPath = retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)); visualBasicInfo.setProjectPath(projPath); + visualBasicInfo.setPcode(vbpi.nativeCodeAddr == 0); std::cout << "[KUBO] VB project info size: " << std::to_string(vbpi.headerSize()) << "\n"; std::cout << "[KUBO] path: " << retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)) << "\n"; diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index ed78ef18a..c554fa668 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -16,7 +16,7 @@ VisualBasicInfo::VisualBasicInfo() : languageDLLPrimaryLCID(0), languageDLLSecon projectPrimaryLCID(0), projectSecondaryLCID(0), /*typeLibCLSID(0),*/ typeLibLCID(0), validLanguageDLLPrimaryLCID(false), validLanguageDLLSecondaryLCID(false), validProjectPrimaryLCID(false), validProjectSecondaryLCID(false), /*validTypeLibCLSID(false),*/ - validTypeLibLCID(false) + validTypeLibLCID(false), pcodeFlag(false) { } @@ -361,6 +361,15 @@ void VisualBasicInfo::setTypeLibLCID(std::uint32_t tlbLCID) validTypeLibLCID = true; } +/** + * Set whether visual basic file is a P-code file. + * @param set @c true if file is a P-code, @c false otherwise. + */ +void VisualBasicInfo::setPcode(bool set) +{ + pcodeFlag = set; +} + /** * Add visual basic object * @param obj Object to add @@ -406,6 +415,15 @@ bool VisualBasicInfo::hasProjectHelpFile() const return !projectHelpFile.empty(); } +/** + * Check if visual basic file is a P-code file + * @return @c true if visual basic file is P-code, @c false otherwise + */ +bool VisualBasicInfo::isPcode() const +{ + return pcodeFlag; +} + } // namespace fileformat } // namespace retdec diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index 201fb13c5..08ebf9785 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -262,4 +262,14 @@ bool VisualBasicInfo::isUsed() const return used; } +/** + * Check whether visual basic file is a P-code file. + * @return @c true if is a P-code file, otherwise @c false. + */ +bool VisualBasicInfo::isPcode() const +{ + return visualBasicInfo ? visualBasicInfo->isPcode() : false; +} + + } // namespace fileinfo diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h index 9fe27c1b5..d94479470 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.h +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -57,6 +57,7 @@ class VisualBasicInfo /// @name Other methods /// @{ bool isUsed() const; + bool isPcode() const; /// @} }; diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp index 2c1852a83..9065bdf62 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -43,6 +43,27 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de info.push_back("TODO"); info.push_back("TODO"); + // isPcode + // getLanguageDLL + // getBackupLanguageDLL + // getProjectExeName + // getProjectDescription + // getProjectHelpFile + // getProjectName + // getLanguageDLLPrimaryLCID + // getLanguageDLLSecondaryLCID + // getProjectPath + // getProjectPrimaryLCID + // getProjectSecondaryLCID + // getObjects + // getExterns + // getObject + // getExtern + // getNumberOfObjects + // getNumberOfExterns + // getTypeLibCLSID + // getTypeLibLCID + return info.size(); } From 3c85d1e1435e07c6441a79db32b961a9298b6130 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 31 Jan 2019 17:54:24 +0100 Subject: [PATCH 09/33] presentation of language and project related stuff --- src/fileformat/file_format/pe/pe_format.cpp | 150 ++++++++---------- .../file_information/file_information.cpp | 9 ++ .../file_information/file_information.h | 1 + .../visual_basic_plain_getter.cpp | 51 +++--- 4 files changed, 100 insertions(+), 111 deletions(-) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 78c631fd6..26c66ce9c 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -727,9 +727,6 @@ void PeFormat::loadVisualBasicHeader() // TODO check VB header magic - std::cout << "[KUBO] VB header size:" << std::to_string(vbh.headerSize()) << "\n"; - vbh.dump(std::cout); - if (vbh.projExeNameOffset != 0) { projExeName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), @@ -755,9 +752,6 @@ void PeFormat::loadVisualBasicHeader() visualBasicInfo.setProjectName(projName); } - std::cout << "KUBO KING: " << projExeName << " | " << projDesc << " | " << helpFile << " | " - << projName << "\n\n"; - for (size_t i = 0; i < sizeof(vbh.languageDLL) && vbh.languageDLL[i]; i++) { projLanguageDLL.push_back(vbh.languageDLL[i]); @@ -770,8 +764,6 @@ void PeFormat::loadVisualBasicHeader() visualBasicInfo.setBackupLanguageDLL(projBackupLanguageDLL); visualBasicInfo.setLanguageDLLPrimaryLCID(vbh.LCID1); visualBasicInfo.setLanguageDLLSecondaryLCID(vbh.LCID2); - std::cout << "KUBO KING: " << projLanguageDLL << " | " << projBackupLanguageDLL << "\n\n"; - if (vbh.projectInfoAddr >= baseAddress) { @@ -794,65 +786,67 @@ void PeFormat::loadVisualBasicHeader() */ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress) { - auto allBytes = getBytes(); - std::vector bytes; - std::size_t offset = 0; - struct VBCOMRData vbcrd; - std::string projName; - std::string helpFile; - std::string projDesc; - - if (!getBytes(bytes, structureOffset, vbcrd.structureSize()) || bytes.size() != vbcrd.structureSize()) - { - return false; - } - - vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); - vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); - vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); - vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); - std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); - vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); - vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); - vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); - vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); - - if (!isLittleEndian()) - { - vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); - vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); - vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); - vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); - vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); - vbcrd.unknown = byteSwap32(vbcrd.unknown); - vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); - vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); - } - // visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); TODO - visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); - if (!visualBasicInfo.hasProjectName()) - { - projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.projNameOffset); - } - if (!visualBasicInfo.hasProjectHelpFile()) - { - helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.helpFileOffset); - } - if (!visualBasicInfo.hasProjectDescription()) - { - projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.projDescOffset); - } - - std::cout << "[KUBO] VB COM register data size: " << std::to_string(vbcrd.structureSize()) << "\n"; - std::cout << "projName: " << projName << "\n"; - std::cout << "helpFile: " << helpFile << "\n"; - std::cout << "projDesc: " << projDesc << "\n"; - - vbcrd.dump(std::cout); - + // auto allBytes = getBytes(); + // std::vector bytes; + // std::size_t offset = 0; + // struct VBCOMRData vbcrd; + // std::string projName; + // std::string helpFile; + // std::string projDesc; + + // if (!getBytes(bytes, structureOffset, vbcrd.structureSize()) || bytes.size() != vbcrd.structureSize()) + // { + // return false; + // } + + // vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); + // vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); + // vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); + // vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); + // std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); + // vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); + // vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); + // vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); + // vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); + + // if (!isLittleEndian()) + // { + // vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); + // vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); + // vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); + // vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); + // vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); + // vbcrd.unknown = byteSwap32(vbcrd.unknown); + // vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); + // vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); + // } + // // visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); TODO + // visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); + // if (!visualBasicInfo.hasProjectName()) + // { + // projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + // structureOffset + vbcrd.projNameOffset); + // } + // if (!visualBasicInfo.hasProjectHelpFile()) + // { + // helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + // structureOffset + vbcrd.helpFileOffset); + // } + // if (!visualBasicInfo.hasProjectDescription()) + // { + // projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + // structureOffset + vbcrd.projDescOffset); + // } + + // std::cout << "[KUBO] VB COM register data size: " << std::to_string(vbcrd.structureSize()) << "\n"; + // std::cout << "projName: " << projName << "\n"; + // std::cout << "helpFile: " << helpFile << "\n"; + // std::cout << "projDesc: " << projDesc << "\n"; + + // vbcrd.dump(std::cout); + + // return true; + (void)structureOffset; (void)baseAddress; return true; } @@ -908,10 +902,6 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz visualBasicInfo.setProjectPath(projPath); visualBasicInfo.setPcode(vbpi.nativeCodeAddr == 0); - std::cout << "[KUBO] VB project info size: " << std::to_string(vbpi.headerSize()) << "\n"; - std::cout << "[KUBO] path: " << retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)) << "\n"; - vbpi.dump(std::cout); - if (vbpi.externalTableAddr >= baseAddress) { vbExternTableOffset = vbpi.externalTableAddr - baseAddress; @@ -965,8 +955,6 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz entry.importDataAddr = byteSwap32(entry.importDataAddr); } - // std::cerr << "Entry type: " << entry.type << "\n"; - if (entry.type != static_cast(VBExternTableEntryType::external) || entry.importDataAddr < baseAddress) { @@ -1006,12 +994,7 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz auto ext = std::make_unique(); ext->setModuleName(moduleName); ext->setApiName(apiName); - // std::cerr << "[<3] " << ext->getModuleName() << "\n"; - // std::cerr << "[<3] " << ext->getApiName() << "\n"; visualBasicInfo.addExtern(std::move(ext)); - // std::cerr << "[<3] " << visualBasicInfo.getNumberOfExterns() << "\n"; - // std::cout << "[KUBO] moduleName: " << moduleName << "\n"; - // std::cout << "[KUBO] apiName: " << apiName << "\n"; } return true; @@ -1084,18 +1067,14 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz visualBasicInfo.setProjectPrimaryLCID(vbot.LCID1); visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); - // TODO KUBO GUID - - std::cout << "[KUBO] VB object table size: " << std::to_string(vbot.structureSize()) << "\n"; + // TODO GUID if (!visualBasicInfo.hasProjectName() && vbot.projectNameAddr >= baseAddress) { projectNameOffset = vbot.projectNameAddr - baseAddress; projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset); visualBasicInfo.setProjectName(projName); - std::cout << "[KUBO] Project name: " << projName << "\n"; } - vbot.dump(std::cout); if (vbot.objectDescriptorsAddr >= baseAddress) { @@ -1170,7 +1149,6 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t std::string objectName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), objectNameOffset); object = std::make_unique(); object->setName(objectName); - std::cout << "[KUBO] objectName: " << objectName << "\n"; if (vbpod.methodNamesAddr >= baseAddress) { @@ -1198,14 +1176,10 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t std::size_t methodNameOffset = methodNameAddr - baseAddress; std::string methodName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), methodNameOffset); object->addMethod(methodName); - - std::cout << "[KUBO] method" << mIdx << ": " << methodName << "\n"; } } visualBasicInfo.addObject(std::move(object)); - std::cout << "\n[KUBO] object" << i << "\n"; - vbpod.dump(std::cout); } return true; diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index e8d67fff3..248f147ed 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -794,6 +794,15 @@ bool FileInformation::isVisualBasicUsed() const return visualBasicInfo.isUsed(); } +/** + * Check whether visual basic uses P-Code. + * @return @c true if it does, otherwise @c false/ + */ +bool FileInformation::getVisualBasicIsPcode() const +{ + return visualBasicInfo.isPcode(); +} + /** * Get visual basic language DLL * @return Visual basic language DLL diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 23c34f218..c55217e79 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -156,6 +156,7 @@ class FileInformation /// @name Getters of @a visualBasicInfo /// @{ bool isVisualBasicUsed() const; + bool getVisualBasicIsPcode() const; std::string getVisualBasicLanguageDLL() const; std::string getVisualBasicBackupLanguageDLL() const; std::string getVisualBasicProjectExeName() const; diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp index 9065bdf62..daf9a1eb8 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -7,6 +7,7 @@ #include "retdec/fileformat/utils/conversions.h" #include "fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.h" +using namespace retdec::utils; using namespace retdec::fileformat; namespace fileinfo { @@ -38,31 +39,35 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de return 0; } - desc.push_back("Super Cool Info : "); - desc.push_back("More Super Cool Info : "); - info.push_back("TODO"); - info.push_back("TODO"); + desc.push_back("Project name : "); + desc.push_back("Project exe name : "); + desc.push_back("Project path : "); + desc.push_back("Project description : "); + desc.push_back("Project help file : "); + desc.push_back("Language DLL : "); + desc.push_back("Backup Language DLL : "); + desc.push_back("Language DLL primary LCID : "); + desc.push_back("Language DLL secondary LCID : "); + desc.push_back("Project primary LCID : "); + desc.push_back("Project secondary LCID : "); + desc.push_back("TypeLibLCID : "); + desc.push_back("Is P-Code : "); + + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectExeName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPath())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectDescription())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectHelpFile())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLL())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicBackupLanguageDLL())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLPrimaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPrimaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); + info.push_back((fileinfo.getVisualBasicIsPcode()) ? "Yes" : "No"); - // isPcode - // getLanguageDLL - // getBackupLanguageDLL - // getProjectExeName - // getProjectDescription - // getProjectHelpFile - // getProjectName - // getLanguageDLLPrimaryLCID - // getLanguageDLLSecondaryLCID - // getProjectPath - // getProjectPrimaryLCID - // getProjectSecondaryLCID - // getObjects - // getExterns - // getObject - // getExtern - // getNumberOfObjects - // getNumberOfExterns // getTypeLibCLSID - // getTypeLibLCID return info.size(); } From b275bbdd385d61e72208c7ad6003a1231d099209 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 31 Jan 2019 19:36:28 +0100 Subject: [PATCH 10/33] extern and object table hashes --- .../types/visual_basic/visual_basic_info.h | 15 ++ src/fileformat/file_format/pe/pe_format.cpp | 3 + .../types/visual_basic/visual_basic_info.cpp | 134 ++++++++++++++++++ .../file_information/file_information.cpp | 54 +++++++ .../file_information/file_information.h | 7 + .../visual_basic_info.cpp | 54 +++++++ .../visual_basic_info.h | 6 + ...visual_basic_extern_table_plain_getter.cpp | 8 +- 8 files changed, 277 insertions(+), 4 deletions(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h index dd14154e8..962e8e367 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -49,6 +49,13 @@ class VisualBasicInfo // std::uint32_t typeLibCLSID; 16BYTES std::uint32_t typeLibLCID; + std::string externTableHashCrc32; + std::string externTableHashMd5; + std::string externTableHashSha256; + std::string objectTableHashCrc32; + std::string objectTableHashMd5; + std::string objectTableHashSha256; + bool validLanguageDLLPrimaryLCID; bool validLanguageDLLSecondaryLCID; bool validProjectPrimaryLCID; @@ -82,6 +89,12 @@ class VisualBasicInfo std::size_t getNumberOfExterns() const; // bool getTypeLibCLSID(std::uint32_t &res) const; bool getTypeLibLCID(std::uint32_t &res) const; + const std::string &getExternTableHashCrc32() const; + const std::string &getExternTableHashMd5() const; + const std::string &getExternTableHashSha256() const; + const std::string &getObjectTableHashCrc32() const; + const std::string &getObjectTableHashMd5() const; + const std::string &getObjectTableHashSha256() const; /// @} /// @name Setters @@ -110,6 +123,8 @@ class VisualBasicInfo bool hasProjectDescription() const; bool hasProjectHelpFile() const; bool isPcode() const; + void computeExternTableHashes(); + void computeObjectTableHashes(); /// @} }; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 26c66ce9c..8830714d7 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -997,6 +997,8 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz visualBasicInfo.addExtern(std::move(ext)); } + visualBasicInfo.computeExternTableHashes(); + return true; } @@ -1082,6 +1084,7 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz parseVisualBasicObjects(objectDescriptorsOffset, baseAddress, vbot.nObjects); } + visualBasicInfo.computeObjectTableHashes(); return true; } diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index c554fa668..6169c8eaf 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -4,8 +4,13 @@ * @copyright (c) 2017 Avast Software, licensed under the MIT license */ +#include "retdec/crypto/crypto.h" +#include "retdec/utils/string.h" #include "retdec/fileformat/types/visual_basic/visual_basic_info.h" + +using namespace retdec::utils; + namespace retdec { namespace fileformat { @@ -238,6 +243,60 @@ bool VisualBasicInfo::getTypeLibLCID(std::uint32_t &res) const return true; } +/** + * Get extern table hash as CRC32 + * @return Extern table hash + */ +const std::string &VisualBasicInfo::getExternTableHashCrc32() const +{ + return externTableHashCrc32; +} + +/** + * Get extern table hash as MD5 + * @return Extern table hash + */ +const std::string &VisualBasicInfo::getExternTableHashMd5() const +{ + return externTableHashMd5; +} + +/** + * Get extern table hash as SHA256 + * @return Extern table hash + */ +const std::string &VisualBasicInfo::getExternTableHashSha256() const +{ + return externTableHashSha256; +} + +/** + * Get object table hash as CRC32 + * @return Object table hash + */ +const std::string &VisualBasicInfo::getObjectTableHashCrc32() const +{ + return objectTableHashCrc32; +} + +/** + * Get object table hash as MD5 + * @return Object table hash + */ +const std::string &VisualBasicInfo::getObjectTableHashMd5() const +{ + return objectTableHashMd5; +} + +/** + * Get object table hash as SHA256 + * @return Object table hash + */ +const std::string &VisualBasicInfo::getObjectTableHashSha256() const +{ + return objectTableHashSha256; +} + /** * Set language DLL * @param lDLL Language DLL to set @@ -424,6 +483,81 @@ bool VisualBasicInfo::isPcode() const return pcodeFlag; } +/** + * Compute external table hashes - CRC32, MD5, SHA256. + */ +void VisualBasicInfo::computeExternTableHashes() +{ + std::vector hashBytes; + + for (const auto& ext : externs) + { + auto moduleName = toLower(ext->getModuleName()); + auto apiName = toLower(ext->getApiName()); + + if(apiName.empty() || moduleName.empty()) + { + continue; + } + + if(!hashBytes.empty()) + { + hashBytes.push_back(static_cast(',')); + } + + for(const auto c : std::string(apiName + "." + moduleName)) + { + hashBytes.push_back(static_cast(c)); + } + } + + externTableHashCrc32 = retdec::crypto::getCrc32(hashBytes.data(), hashBytes.size()); + externTableHashMd5 = retdec::crypto::getMd5(hashBytes.data(), hashBytes.size()); + externTableHashSha256 = retdec::crypto::getSha256(hashBytes.data(), hashBytes.size()); +} + +/** + * Compute object table hashes - CRC32, MD5, SHA256. + */ +void VisualBasicInfo::computeObjectTableHashes() +{ + std::vector hashBytes; + + for (const auto& obj : objects) + { + auto objName = toLower(obj->getName()); + if(objName.empty()) + { + continue; + } + + std::string methods = ""; + for (const auto &method : obj->getMethods()) + { + if (!methods.empty()) + { + methods.push_back('.'); + } + + methods += method; + } + + if(!hashBytes.empty()) + { + hashBytes.push_back(static_cast(',')); + } + + for(const auto c : std::string(objName + "." + methods)) + { + hashBytes.push_back(static_cast(c)); + } + } + + objectTableHashCrc32 = retdec::crypto::getCrc32(hashBytes.data(), hashBytes.size()); + objectTableHashMd5 = retdec::crypto::getMd5(hashBytes.data(), hashBytes.size()); + objectTableHashSha256 = retdec::crypto::getSha256(hashBytes.data(), hashBytes.size()); +} + } // namespace fileformat } // namespace retdec diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index 248f147ed..c6f581fc3 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -969,6 +969,60 @@ std::string FileInformation::getVisualBasicTypeLibLCIDStr() const return visualBasicInfo.getTypeLibLCIDStr(); } +/** + * Get visual basic extern table hash as Crc32 + * @return Visual basic extern table hash + */ +std::string FileInformation::getVisualBasicExternTableHashCrc32() const +{ + return visualBasicInfo.getExternTableHashCrc32(); +} + +/** + * Get visual basic extern table hash as Md5 + * @return Visual basic extern table hash + */ +std::string FileInformation::getVisualBasicExternTableHashMd5() const +{ + return visualBasicInfo.getExternTableHashMd5(); +} + +/** + * Get visual basic extern table hash as Sha256 + * @return Visual basic extern table hash + */ +std::string FileInformation::getVisualBasicExternTableHashSha256() const +{ + return visualBasicInfo.getExternTableHashSha256(); +} + +/** + * Get visual basic object table hash as Crc32 + * @return Visual basic object table hash + */ +std::string FileInformation::getVisualBasicObjectTableHashCrc32() const +{ + return visualBasicInfo.getObjectTableHashCrc32(); +} + +/** + * Get visual basic object table hash as Md5 + * @return Visual basic object table hash + */ +std::string FileInformation::getVisualBasicObjectTableHashMd5() const +{ + return visualBasicInfo.getObjectTableHashMd5(); +} + +/** + * Get visual basic object table hash as Sha256 + * @return Visual basic object table hash + */ +std::string FileInformation::getVisualBasicObjectTableHashSha256() const +{ + return visualBasicInfo.getObjectTableHashSha256(); +} + diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index c55217e79..0642fb0ae 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -175,6 +175,13 @@ class FileInformation std::string getVisualBasicExternModuleName(std::size_t position) const; std::string getVisualBasicExternApiName(std::size_t position) const; std::string getVisualBasicTypeLibLCIDStr() const; + std::string getExternTableHashCrc32() const; + std::string getVisualBasicExternTableHashCrc32() const; + std::string getVisualBasicExternTableHashMd5() const; + std::string getVisualBasicExternTableHashSha256() const; + std::string getVisualBasicObjectTableHashCrc32() const; + std::string getVisualBasicObjectTableHashMd5() const; + std::string getVisualBasicObjectTableHashSha256() const; /// @} diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index 08ebf9785..51bdb8f2d 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -235,6 +235,60 @@ std::string VisualBasicInfo::getTypeLibLCIDStr() const return getNumberAsString(lcid); } +/** + * Get extern table hash as CRC32 + * @return Extern table hash + */ +std::string VisualBasicInfo::getExternTableHashCrc32() const +{ + return visualBasicInfo ? visualBasicInfo->getExternTableHashCrc32() : ""; +} + +/** + * Get extern table hash as MD5 + * @return Extern table hash + */ +std::string VisualBasicInfo::getExternTableHashMd5() const +{ + return visualBasicInfo ? visualBasicInfo->getExternTableHashMd5() : ""; +} + +/** + * Get extern table hash as SHA256 + * @return Extern table hash + */ +std::string VisualBasicInfo::getExternTableHashSha256() const +{ + return visualBasicInfo ? visualBasicInfo->getExternTableHashSha256() : ""; +} + +/** + * Get object table hash as CRC32 + * @return Object table hash + */ +std::string VisualBasicInfo::getObjectTableHashCrc32() const +{ + return visualBasicInfo ? visualBasicInfo->getObjectTableHashCrc32() : ""; +} + +/** + * Get object table hash as MD5 + * @return Object table hash + */ +std::string VisualBasicInfo::getObjectTableHashMd5() const +{ + return visualBasicInfo ? visualBasicInfo->getObjectTableHashMd5() : ""; +} + +/** + * Get object table hash as SHA256 + * @return Object table hash + */ +std::string VisualBasicInfo::getObjectTableHashSha256() const +{ + return visualBasicInfo ? visualBasicInfo->getObjectTableHashSha256() : ""; +} + /** * Set visual basic information * @param vbInfo Instance of class with original information about visual basic diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h index d94479470..45e936b32 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.h +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -46,6 +46,12 @@ class VisualBasicInfo std::string getExternApiName(std::size_t position) const; // std::string getTypeLibCLSIDStr() const; std::string getTypeLibLCIDStr() const; + std::string getExternTableHashCrc32() const; + std::string getExternTableHashMd5() const; + std::string getExternTableHashSha256() const; + std::string getObjectTableHashCrc32() const; + std::string getObjectTableHashMd5() const; + std::string getObjectTableHashSha256() const; /// @} /// @name Setters diff --git a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp index 7e2833b73..e87425223 100644 --- a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp @@ -57,14 +57,14 @@ std::size_t VisualBasicExternTablePlainGetter::getBasicInfo(std::size_t structIn desc.clear(); info.clear(); - desc.push_back("Number of visual basic externs: "); + desc.push_back("Number of externs: "); desc.push_back("CRC32 : "); desc.push_back("MD5 : "); desc.push_back("SHA256 : "); info.push_back(numToStr(fileinfo.getVisualBasicNumberOfExterns())); - info.push_back("TODO"); - info.push_back("TODO"); - info.push_back("TODO"); + info.push_back(fileinfo.getVisualBasicExternTableHashCrc32()); + info.push_back(fileinfo.getVisualBasicExternTableHashMd5()); + info.push_back(fileinfo.getVisualBasicExternTableHashSha256()); return info.size(); } From 0dea3e30fad5f8ebfbb067414e8501c998d1a92c Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 1 Feb 2019 14:04:55 +0100 Subject: [PATCH 11/33] obj table hash presentation --- .../file_presentation/plain_presentation.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index 9f7ba96bc..6b6077cc6 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -636,7 +636,13 @@ void PlainPresentation::presentVisualBasicObjects() const } std::cout << "\n"; - std::cout << "Visual Basic objects" << "\n"; + std::cout << "Visual Basic Object table" << "\n"; + std::cout << "-------------------------" << "\n"; + std::cout << "CRC32 : " << fileinfo.getVisualBasicObjectTableHashCrc32() << "\n"; + std::cout << "MD5 : " << fileinfo.getVisualBasicObjectTableHashMd5() << "\n"; + std::cout << "SHA256 : " << fileinfo.getVisualBasicObjectTableHashSha256() << "\n"; + std::cout << "\n"; + std::size_t cnt = 0; for (std::size_t i = 0; i < nObjs; i++) { auto obj = fileinfo.getVisualBasicObject(i); @@ -649,11 +655,12 @@ void PlainPresentation::presentVisualBasicObjects() const { continue; } - std::cout << " object name: " << objName << "\n"; + std::cout << cnt << ". " << "object name: " << objName << "\n"; for (const auto &m : obj->getMethods()) { - std::cout << " method name: " << m << "\n"; + std::cout << " method name: " << m << "\n"; } + cnt++; } } From 17b8798fe8e2860af000000a1a18ae47548b8385 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 1 Feb 2019 17:41:07 +0100 Subject: [PATCH 12/33] doxygen fix --- src/fileformat/file_format/pe/pe_format.cpp | 2 +- src/fileformat/types/visual_basic/visual_basic_info.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 8830714d7..a0cf3c13b 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -1092,7 +1092,7 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz * Parse visual basic objects * @param structureOffset Offset in file where the public object descriptors array starts * @param baseAddress Base address - * @param nEntries Number of objects in array + * @param nObjects Number of objects in array * @return @c true if objects were successfuly parsed, @c false otherwise */ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t baseAddress, diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index 6169c8eaf..c950958b3 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -402,7 +402,7 @@ void VisualBasicInfo::setProjectSecondaryLCID(std::uint32_t secLCID) // /** // * Set typeLib CLSID -// * @param tlbCLSID TypeLib CLSID to set +// * @ TODO param tlbCLSID TypeLib CLSID to set // */ // void VisualBasicInfo::setTypeLibCLSID(std::uint32_t tlbCLSID) // { From 5dacd58d74fc5c9fceba20ab5dcb4be047b2cf56 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 1 Feb 2019 18:29:33 +0100 Subject: [PATCH 13/33] basic json presentation --- src/fileinfo/CMakeLists.txt | 1 + .../file_presentation/getters/json_getters.h | 1 + .../visual_basic_json_getter.cpp | 73 +++++++++++++++++++ .../simple_getter/visual_basic_json_getter.h | 28 +++++++ .../file_presentation/json_presentation.cpp | 17 +++++ .../file_presentation/json_presentation.h | 1 + 6 files changed, 121 insertions(+) create mode 100644 src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp create mode 100644 src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h diff --git a/src/fileinfo/CMakeLists.txt b/src/fileinfo/CMakeLists.txt index 224178ee2..2970c8162 100644 --- a/src/fileinfo/CMakeLists.txt +++ b/src/fileinfo/CMakeLists.txt @@ -82,6 +82,7 @@ set(FILEINFO_SOURCES file_presentation/getters/simple_getter/dotnet_json_getter.cpp file_presentation/getters/simple_getter/dotnet_plain_getter.cpp file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp + file_presentation/getters/simple_getter/visual_basic_json_getter.cpp file_presentation/getters/simple_getter/entry_point_json_getter.cpp file_presentation/getters/simple_getter/header_json_getter.cpp file_presentation/getters/simple_getter/header_plain_getter.cpp diff --git a/src/fileinfo/file_presentation/getters/json_getters.h b/src/fileinfo/file_presentation/getters/json_getters.h index 8737b05e8..1c9af60c8 100644 --- a/src/fileinfo/file_presentation/getters/json_getters.h +++ b/src/fileinfo/file_presentation/getters/json_getters.h @@ -26,5 +26,6 @@ #include "fileinfo/file_presentation/getters/simple_getter/entry_point_json_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/header_json_getter.h" #include "fileinfo/file_presentation/getters/simple_getter/pdb_json_getter.h" +#include "fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h" #endif diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp new file mode 100644 index 000000000..0d593e30c --- /dev/null +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp @@ -0,0 +1,73 @@ +/** + * @file src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp + * @brief Methods of VisualBasicJsonGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "retdec/fileformat/utils/conversions.h" +#include "fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h" + +using namespace retdec::utils; +using namespace retdec::fileformat; + +namespace fileinfo { + +/** + * Constructor + * @param fileInfo Information about file + */ +VisualBasicJsonGetter::VisualBasicJsonGetter(FileInformation &fileInfo) : SimpleGetter(fileInfo) +{ + +} + +/** + * Destructor + */ +VisualBasicJsonGetter::~VisualBasicJsonGetter() +{ + +} + +std::size_t VisualBasicJsonGetter::loadInformation(std::vector &desc, std::vector &info) const +{ + desc.clear(); + info.clear(); + + if (!fileinfo.isVisualBasicUsed()) + { + return 0; + } + + desc.push_back("projectName"); + desc.push_back("projectExeName"); + desc.push_back("projectPath"); + desc.push_back("projectDescription"); + desc.push_back("projectHelpFile"); + desc.push_back("languageDLL"); + desc.push_back("backupLanguageDLL"); + desc.push_back("languageDLLPrimaryLCID"); + desc.push_back("languageDLLSecondaryLCID"); + desc.push_back("projectPrimaryLCID"); + desc.push_back("projectSecondaryLCID"); + desc.push_back("typeLibLCID"); + desc.push_back("isPCode"); + + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectExeName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPath())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectDescription())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectHelpFile())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLL())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicBackupLanguageDLL())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLPrimaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPrimaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); + info.push_back((fileinfo.getVisualBasicIsPcode()) ? "yes" : "no"); + + return info.size(); +} + +} // namespace fileinfo diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h new file mode 100644 index 000000000..c82ec2eb7 --- /dev/null +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h @@ -0,0 +1,28 @@ +/** + * @file src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.h + * @brief Definition of VisualBasicJsonGetter class. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#ifndef FILEINFO_FILE_PRESENTATION_GETTERS_SIMPLE_GETTER_VISUAL_BASIC_JSON_GETTER_H +#define FILEINFO_FILE_PRESENTATION_GETTERS_SIMPLE_GETTER_VISUAL_BASIC_JSON_GETTER_H + +#include "fileinfo/file_presentation/getters/simple_getter/simple_getter.h" + +namespace fileinfo { + +/** + * Getter for information about Visual Basic + */ +class VisualBasicJsonGetter : public SimpleGetter +{ + public: + VisualBasicJsonGetter(FileInformation &fileInfo); + virtual ~VisualBasicJsonGetter() override; + + virtual std::size_t loadInformation(std::vector &desc, std::vector &info) const override; +}; + +} // namespace fileinfo + +#endif diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index 6b987f7a9..f4ba35ed9 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -480,6 +480,22 @@ void JsonPresentation::presentDotnetInfo(Json::Value &root) const root["dotnetInfo"] = jDotnet; } +/** + * Present information about Visual Basic + * @param root Parent node in output document + */ +void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const +{ + // TODO add object table and export table dump (as above in .NET) + Value jVBasic; + if (!presentSimple(VisualBasicJsonGetter(fileinfo), jVBasic)) + { + return; + } + + root["visualBasicInfo"] = jVBasic; +} + /** * Present ELF notes * @param root Parent node in output document @@ -740,6 +756,7 @@ bool JsonPresentation::present() presentPatterns(root); presentCertificateAttributes(root); presentDotnetInfo(root); + presentVisualBasicInfo(root); } else { diff --git a/src/fileinfo/file_presentation/json_presentation.h b/src/fileinfo/file_presentation/json_presentation.h index 4593efe97..e53023019 100644 --- a/src/fileinfo/file_presentation/json_presentation.h +++ b/src/fileinfo/file_presentation/json_presentation.h @@ -33,6 +33,7 @@ class JsonPresentation : public FilePresentation void presentLoaderInfo(Json::Value &root) const; void presentCertificateAttributes(Json::Value &root) const; void presentDotnetInfo(Json::Value &root) const; + void presentVisualBasicInfo(Json::Value &root) const; void presentElfNotes(Json::Value &root) const; void presentFlags(Json::Value &root, const std::string &title, const std::string &flags, const std::vector &desc) const; void presentIterativeSubtitleStructure(Json::Value &root, const IterativeSubtitleGetter &getter, std::size_t structIndex) const; From c6bad0003ee50a963af68709dec8551b10eba025 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 2 Feb 2019 00:32:31 +0100 Subject: [PATCH 14/33] extern and object tables json presentation --- .../file_information/file_information.h | 1 - .../file_presentation/json_presentation.cpp | 48 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 0642fb0ae..37b487622 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -175,7 +175,6 @@ class FileInformation std::string getVisualBasicExternModuleName(std::size_t position) const; std::string getVisualBasicExternApiName(std::size_t position) const; std::string getVisualBasicTypeLibLCIDStr() const; - std::string getExternTableHashCrc32() const; std::string getVisualBasicExternTableHashCrc32() const; std::string getVisualBasicExternTableHashMd5() const; std::string getVisualBasicExternTableHashSha256() const; diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index f4ba35ed9..315c4ed36 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -486,13 +486,59 @@ void JsonPresentation::presentDotnetInfo(Json::Value &root) const */ void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const { - // TODO add object table and export table dump (as above in .NET) Value jVBasic; if (!presentSimple(VisualBasicJsonGetter(fileinfo), jVBasic)) { return; } + auto nExterns = fileinfo.getVisualBasicNumberOfExterns(); + if (nExterns) + { + Value jExternTable; + jExternTable["crc32"] = fileinfo.getVisualBasicExternTableHashCrc32(); + jExternTable["md5"] = fileinfo.getVisualBasicExternTableHashMd5(); + jExternTable["sha256"] = fileinfo.getVisualBasicExternTableHashSha256(); + for (std::size_t i = 0; i < nExterns; i++) + { + auto ext = fileinfo.getVisualBasicExtern(i); + if (!ext) + { + continue; + } + Value jExtern; + jExtern["moduleName"] = ext->getModuleName(); + jExtern["apiName"] = ext->getApiName(); + jExternTable["externs"].append(jExtern); + } + jVBasic["externTable"] = jExternTable; + } + + auto nObjects = fileinfo.getVisualBasicNumberOfObjects(); + if (nObjects) + { + Value jObjectTable; + jObjectTable["crc32"] = fileinfo.getVisualBasicObjectTableHashCrc32(); + jObjectTable["md5"] = fileinfo.getVisualBasicObjectTableHashMd5(); + jObjectTable["sha256"] = fileinfo.getVisualBasicObjectTableHashSha256(); + for (std::size_t i = 0; i < nObjects; i++) + { + auto obj = fileinfo.getVisualBasicObject(i); + if (!obj) + { + continue; + } + Value jObject; + jObject["name"] = obj->getName(); + for (const auto &method : obj->getMethods()) + { + jObject["methods"].append(method); + } + jObjectTable["objects"].append(jObject); + } + jVBasic["objectTable"] = jObjectTable; + } + root["visualBasicInfo"] = jVBasic; } From 433010ac57b083bff675ed661380f85a6e1c3e80 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Mon, 4 Feb 2019 15:55:31 +0100 Subject: [PATCH 15/33] COM Registration Data extraction and presentation + object Table GUID --- .../types/visual_basic/visual_basic_info.h | 20 ++- include/retdec/utils/conversion.h | 1 + src/fileformat/file_format/pe/pe_format.cpp | 118 ++++++++--------- .../types/visual_basic/visual_basic_info.cpp | 121 ++++++++++++++---- .../file_information/file_information.cpp | 36 ++++++ .../file_information/file_information.h | 4 + .../visual_basic_info.cpp | 47 +++++-- .../visual_basic_info.h | 5 +- .../visual_basic_json_getter.cpp | 6 + .../visual_basic_plain_getter.cpp | 10 +- .../file_presentation/json_presentation.cpp | 6 +- .../file_presentation/plain_presentation.cpp | 1 + src/utils/conversion.cpp | 19 +++ 13 files changed, 281 insertions(+), 113 deletions(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h index 962e8e367..9d32b2742 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -37,7 +37,7 @@ class VisualBasicInfo std::string projectPath; // VB Object table - // object table GUID TODO DATA TYPE + std::string objectTableGUID; std::uint32_t projectPrimaryLCID; std::uint32_t projectSecondaryLCID; std::vector> objects; @@ -46,9 +46,12 @@ class VisualBasicInfo std::vector> externs; // COM register data - // std::uint32_t typeLibCLSID; 16BYTES + std::string typeLibCLSID; std::uint32_t typeLibLCID; + std::uint16_t typeLibMajorVersion; + std::uint16_t typeLibMinorVersion; + // others std::string externTableHashCrc32; std::string externTableHashMd5; std::string externTableHashSha256; @@ -60,10 +63,11 @@ class VisualBasicInfo bool validLanguageDLLSecondaryLCID; bool validProjectPrimaryLCID; bool validProjectSecondaryLCID; - // bool validTypeLibCLSID; bool validTypeLibLCID; bool pcodeFlag; + std::string guidToStr(const std::uint8_t data[16]); + public: VisualBasicInfo(); ~VisualBasicInfo(); @@ -87,8 +91,11 @@ class VisualBasicInfo const VisualBasicExtern *getExtern(std::size_t position) const; std::size_t getNumberOfObjects() const; std::size_t getNumberOfExterns() const; - // bool getTypeLibCLSID(std::uint32_t &res) const; + const std::string &getObjectTableGUID() const; + const std::string &getTypeLibCLSID() const; bool getTypeLibLCID(std::uint32_t &res) const; + std::uint16_t getTypeLibMajorVersion() const; + std::uint16_t getTypeLibMinorVersion() const; const std::string &getExternTableHashCrc32() const; const std::string &getExternTableHashMd5() const; const std::string &getExternTableHashSha256() const; @@ -110,9 +117,12 @@ class VisualBasicInfo void setProjectPath(const std::string &path); void setProjectPrimaryLCID(std::uint32_t primLCID); void setProjectSecondaryLCID(std::uint32_t secLCID); - // void setTypeLibCLSID(std::uint32_t tlbCLSID); + void setTypeLibCLSID(const std::uint8_t data[16]); void setTypeLibLCID(std::uint32_t tlbLCID); void setPcode(bool set); + void setObjectTableGUID(const std::uint8_t data[16]); + void setTypeLibMajorVersion(std::uint16_t majVer); + void setTypeLibMinorVersion(std::uint16_t minVer); /// @} /// @name Other methods diff --git a/include/retdec/utils/conversion.h b/include/retdec/utils/conversion.h index 8c2109586..f1129ec07 100644 --- a/include/retdec/utils/conversion.h +++ b/include/retdec/utils/conversion.h @@ -300,6 +300,7 @@ void double10ToDouble8(std::vector &dest, unsigned short byteSwap16(unsigned short val); unsigned int byteSwap32(unsigned int val); +unsigned long byteSwap64(unsigned long val); std::string byteSwap16(const std::string &val); std::string byteSwap32(const std::string &val); diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index a0cf3c13b..8db7c70fa 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -786,67 +786,61 @@ void PeFormat::loadVisualBasicHeader() */ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress) { - // auto allBytes = getBytes(); - // std::vector bytes; - // std::size_t offset = 0; - // struct VBCOMRData vbcrd; - // std::string projName; - // std::string helpFile; - // std::string projDesc; - - // if (!getBytes(bytes, structureOffset, vbcrd.structureSize()) || bytes.size() != vbcrd.structureSize()) - // { - // return false; - // } - - // vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); - // vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); - // vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); - // vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); - // std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); - // vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); - // vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); - // vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); - // vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); - - // if (!isLittleEndian()) - // { - // vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); - // vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); - // vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); - // vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); - // vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); - // vbcrd.unknown = byteSwap32(vbcrd.unknown); - // vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); - // vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); - // } - // // visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); TODO - // visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); - // if (!visualBasicInfo.hasProjectName()) - // { - // projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - // structureOffset + vbcrd.projNameOffset); - // } - // if (!visualBasicInfo.hasProjectHelpFile()) - // { - // helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - // structureOffset + vbcrd.helpFileOffset); - // } - // if (!visualBasicInfo.hasProjectDescription()) - // { - // projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - // structureOffset + vbcrd.projDescOffset); - // } - - // std::cout << "[KUBO] VB COM register data size: " << std::to_string(vbcrd.structureSize()) << "\n"; - // std::cout << "projName: " << projName << "\n"; - // std::cout << "helpFile: " << helpFile << "\n"; - // std::cout << "projDesc: " << projDesc << "\n"; - - // vbcrd.dump(std::cout); - - // return true; - (void)structureOffset; (void)baseAddress; + auto allBytes = getBytes(); + std::vector bytes; + std::size_t offset = 0; + struct VBCOMRData vbcrd; + std::string projName; + std::string helpFile; + std::string projDesc; + + if (!getBytes(bytes, structureOffset, vbcrd.structureSize()) || bytes.size() != vbcrd.structureSize()) + { + return false; + } + + vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); + vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); + vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); + vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); + std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); + vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); + vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); + vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); + vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); + + if (!isLittleEndian()) + { + vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); + vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); + vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); + vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); + vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); + vbcrd.unknown = byteSwap32(vbcrd.unknown); + vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); + vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); + } + + visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); + visualBasicInfo.setTypeLibMajorVersion(vbcrd.tlbVerMajor); + visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); + if (!visualBasicInfo.hasProjectName()) + { + projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.projNameOffset); + } + if (!visualBasicInfo.hasProjectHelpFile()) + { + helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.helpFileOffset); + } + if (!visualBasicInfo.hasProjectDescription()) + { + projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + structureOffset + vbcrd.projDescOffset); + } + + visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); return true; } @@ -1069,7 +1063,7 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz visualBasicInfo.setProjectPrimaryLCID(vbot.LCID1); visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); - // TODO GUID + visualBasicInfo.setObjectTableGUID(vbot.objectGUID); if (!visualBasicInfo.hasProjectName() && vbot.projectNameAddr >= baseAddress) { diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index c950958b3..8c5a2fcd5 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -6,6 +6,8 @@ #include "retdec/crypto/crypto.h" #include "retdec/utils/string.h" +#include "retdec/utils/system.h" +#include "retdec/utils/conversion.h" #include "retdec/fileformat/types/visual_basic/visual_basic_info.h" @@ -18,10 +20,10 @@ namespace fileformat { * Constructor */ VisualBasicInfo::VisualBasicInfo() : languageDLLPrimaryLCID(0), languageDLLSecondaryLCID(0), - projectPrimaryLCID(0), projectSecondaryLCID(0), /*typeLibCLSID(0),*/ typeLibLCID(0), - validLanguageDLLPrimaryLCID(false), validLanguageDLLSecondaryLCID(false), - validProjectPrimaryLCID(false), validProjectSecondaryLCID(false), /*validTypeLibCLSID(false),*/ - validTypeLibLCID(false), pcodeFlag(false) + projectPrimaryLCID(0), projectSecondaryLCID(0), typeLibLCID(0), typeLibMajorVersion(1), + typeLibMinorVersion(0), validLanguageDLLPrimaryLCID(false), validLanguageDLLSecondaryLCID(false), + validProjectPrimaryLCID(false), validProjectSecondaryLCID(false), validTypeLibLCID(false), + pcodeFlag(false) { } @@ -213,20 +215,23 @@ size_t VisualBasicInfo::getNumberOfExterns() const return externs.size(); } -// /** -// * Get typeLib CLSID -// * @param res Variable to store the result to -// * @return @c true if project typeLib CLSID is valid, @c false otherwise -// */ -// bool VisualBasicInfo::getTypeLibCLSID(std::uint32_t &res) const -// { -// if (!validTypeLibCLSID) -// { -// return false; -// } -// res = typeLibCLSID; -// return true; -// } +/** + * Get object table GUID + * @return Object table GUID as string + */ +const std::string &VisualBasicInfo::getObjectTableGUID() const +{ + return objectTableGUID; +} + +/** + * Get typeLib CLSID + * @return typeLib CLSID as string + */ +const std::string &VisualBasicInfo::getTypeLibCLSID() const +{ + return typeLibCLSID; +} /** * Get typeLib LCID @@ -243,6 +248,25 @@ bool VisualBasicInfo::getTypeLibLCID(std::uint32_t &res) const return true; } +/** + * Get typeLib major version + * @return TypeLib major version + */ +std::uint16_t VisualBasicInfo::getTypeLibMajorVersion() const +{ + return typeLibMajorVersion; +} + +/** + * Get typeLib minor version + * @return TypeLib minor version + */ +std::uint16_t VisualBasicInfo::getTypeLibMinorVersion() const +{ + return typeLibMinorVersion; +} + + /** * Get extern table hash as CRC32 * @return Extern table hash @@ -400,15 +424,14 @@ void VisualBasicInfo::setProjectSecondaryLCID(std::uint32_t secLCID) validProjectSecondaryLCID = true; } -// /** -// * Set typeLib CLSID -// * @ TODO param tlbCLSID TypeLib CLSID to set -// */ -// void VisualBasicInfo::setTypeLibCLSID(std::uint32_t tlbCLSID) -// { -// typeLibCLSID = tlbCLSID; -// validTypeLibCLSID = true; -// } +/** + * Set typeLib CLSID + * @param data CLSID raw data + */ +void VisualBasicInfo::setTypeLibCLSID(const std::uint8_t data[16]) +{ + typeLibCLSID = guidToStr(data); +} /** * Set typeLib LCID @@ -429,6 +452,34 @@ void VisualBasicInfo::setPcode(bool set) pcodeFlag = set; } +/** + * Set object table GUID + * @param data Raw GUID data + */ +void VisualBasicInfo::setObjectTableGUID(const std::uint8_t data[16]) +{ + objectTableGUID = guidToStr(data); +} + +/** + * Set typeLib major version + * @param majVer Version to set + */ +void VisualBasicInfo::setTypeLibMajorVersion(std::uint16_t majVer) +{ + typeLibMajorVersion = majVer; +} + +/** + * Set typeLib minor version + * @param minVer Version to set + */ +void VisualBasicInfo::setTypeLibMinorVersion(std::uint16_t minVer) +{ + typeLibMinorVersion = minVer; +} + + /** * Add visual basic object * @param obj Object to add @@ -558,6 +609,22 @@ void VisualBasicInfo::computeObjectTableHashes() objectTableHashSha256 = retdec::crypto::getSha256(hashBytes.data(), hashBytes.size()); } +/** + * Convert raw GUID data to string + * @param data Raw GUID data + */ +std::string VisualBasicInfo::guidToStr(const std::uint8_t data[16]) +{ + std::string r1, r2, r3, r4, r5; + bytesToHexString(data, 16, r1, 0, 4); + bytesToHexString(data, 16, r2, 4, 2); + bytesToHexString(data, 16, r3, 6, 2); + bytesToHexString(data, 16, r4, 8, 2); + bytesToHexString(data, 16, r5, 10, 6); + + return r1 + "-" + r2 + "-" + r3 + "-" + r4 + "-" + r5; +} + } // namespace fileformat } // namespace retdec diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index c6f581fc3..b1b003f59 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -960,6 +960,42 @@ std::string FileInformation::getVisualBasicExternApiName(std::size_t position) c return visualBasicInfo.getExternApiName(position); } +/** + * Get visual basic object table GUID + * @return Object table GUID as string + */ +std::string FileInformation::getVisualBasicObjectTableGUID() const +{ + return visualBasicInfo.getObjectTableGUID(); +} + +/** + * Get visual basic typeLib CLSID + * @return typeLib CLSID as string + */ +std::string FileInformation::getVisualBasicTypeLibCLSID() const +{ + return visualBasicInfo.getTypeLibCLSID(); +} + +/** + * Get visual basic typeLib major version + * @return TypeLib major version + */ +std::string FileInformation::getVisualBasicTypeLibMajorVersionStr() const +{ + return visualBasicInfo.getTypeLibMajorVersionStr(); +} + +/** + * Get visual basic typeLib minor version + * @return TypeLib minor version + */ +std::string FileInformation::getVisualBasicTypeLibMinorVersionStr() const +{ + return visualBasicInfo.getTypeLibMinorVersionStr(); +} + /** * Get visual basic typeLib LCID * @return Visual basic typeLib LCID diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 37b487622..595221dad 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -174,6 +174,10 @@ class FileInformation std::size_t getVisualBasicNumberOfExterns() const; std::string getVisualBasicExternModuleName(std::size_t position) const; std::string getVisualBasicExternApiName(std::size_t position) const; + std::string getVisualBasicObjectTableGUID() const; + std::string getVisualBasicTypeLibCLSID() const; + std::string getVisualBasicTypeLibMajorVersionStr() const; + std::string getVisualBasicTypeLibMinorVersionStr() const; std::string getVisualBasicTypeLibLCIDStr() const; std::string getVisualBasicExternTableHashCrc32() const; std::string getVisualBasicExternTableHashMd5() const; diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index 51bdb8f2d..81b65fc6d 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -206,20 +206,41 @@ std::string VisualBasicInfo::getExternApiName(std::size_t position) const return ext ? ext->getApiName() : ""; } +/** + * Get object table GUID + * @return Object table GUID as string + */ +std::string VisualBasicInfo::getObjectTableGUID() const +{ + return visualBasicInfo ? visualBasicInfo->getObjectTableGUID() : ""; +} + +/** + * Get typeLib CLSID + * @return typeLib CLSID as string + */ +std::string VisualBasicInfo::getTypeLibCLSID() const +{ + return visualBasicInfo ? visualBasicInfo->getTypeLibCLSID() : ""; +} -// /** -// * Get typeLib CLSID -// * @return Visual basic typeLib CLSID as string -// */ -// std::string VisualBasicInfo::getTypeLibCLSIDStr() const -// { -// std::uint32_t clsid; -// if (!visualBasicInfo || !visualBasicInfo->getTypeLibCLSID(clsid)) -// { -// return ""; -// } -// return getNumberAsString(clsid); -// } +/** + * Get typeLib major version + * @return TypeLib major version + */ +std::string VisualBasicInfo::getTypeLibMajorVersionStr() const +{ + return visualBasicInfo ? getNumberAsString(visualBasicInfo->getTypeLibMajorVersion()) : ""; +} + +/** + * Get typeLib minor version + * @return TypeLib minor version + */ +std::string VisualBasicInfo::getTypeLibMinorVersionStr() const +{ + return visualBasicInfo ? getNumberAsString(visualBasicInfo->getTypeLibMinorVersion()) : ""; +} /** * Get typeLib LCID diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h index 45e936b32..9b31eece9 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.h +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -44,7 +44,10 @@ class VisualBasicInfo std::size_t getNumberOfExterns() const; std::string getExternModuleName(std::size_t position) const; std::string getExternApiName(std::size_t position) const; - // std::string getTypeLibCLSIDStr() const; + std::string getObjectTableGUID() const; + std::string getTypeLibCLSID() const; + std::string getTypeLibMajorVersionStr() const; + std::string getTypeLibMinorVersionStr() const; std::string getTypeLibLCIDStr() const; std::string getExternTableHashCrc32() const; std::string getExternTableHashMd5() const; diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp index 0d593e30c..be9705af1 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp @@ -50,6 +50,9 @@ std::size_t VisualBasicJsonGetter::loadInformation(std::vector &des desc.push_back("languageDLLSecondaryLCID"); desc.push_back("projectPrimaryLCID"); desc.push_back("projectSecondaryLCID"); + desc.push_back("typeLibCLSID"); + desc.push_back("typeLibMajorVersion"); + desc.push_back("typeLibMinorVersion"); desc.push_back("typeLibLCID"); desc.push_back("isPCode"); @@ -64,6 +67,9 @@ std::size_t VisualBasicJsonGetter::loadInformation(std::vector &des info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLSecondaryLCIDStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPrimaryLCIDStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibCLSID())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMajorVersionStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMinorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); info.push_back((fileinfo.getVisualBasicIsPcode()) ? "yes" : "no"); diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp index daf9a1eb8..4d14f9283 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -50,7 +50,10 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de desc.push_back("Language DLL secondary LCID : "); desc.push_back("Project primary LCID : "); desc.push_back("Project secondary LCID : "); - desc.push_back("TypeLibLCID : "); + desc.push_back("TypeLib CLSID : "); + desc.push_back("TypeLib major version : "); + desc.push_back("TypeLib minor version : "); + desc.push_back("TypeLib LCID : "); desc.push_back("Is P-Code : "); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectName())); @@ -64,11 +67,12 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicLanguageDLLSecondaryLCIDStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectPrimaryLCIDStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectSecondaryLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibCLSID())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMajorVersionStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMinorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); info.push_back((fileinfo.getVisualBasicIsPcode()) ? "Yes" : "No"); - // getTypeLibCLSID - return info.size(); } diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index 315c4ed36..b9fe05419 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -514,10 +514,12 @@ void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const jVBasic["externTable"] = jExternTable; } + Value jObjectTable; + jObjectTable["guid"] = fileinfo.getVisualBasicObjectTableGUID(); + auto nObjects = fileinfo.getVisualBasicNumberOfObjects(); if (nObjects) { - Value jObjectTable; jObjectTable["crc32"] = fileinfo.getVisualBasicObjectTableHashCrc32(); jObjectTable["md5"] = fileinfo.getVisualBasicObjectTableHashMd5(); jObjectTable["sha256"] = fileinfo.getVisualBasicObjectTableHashSha256(); @@ -536,9 +538,9 @@ void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const } jObjectTable["objects"].append(jObject); } - jVBasic["objectTable"] = jObjectTable; } + jVBasic["objectTable"] = jObjectTable; root["visualBasicInfo"] = jVBasic; } diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index 6b6077cc6..26d3a51e5 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -641,6 +641,7 @@ void PlainPresentation::presentVisualBasicObjects() const std::cout << "CRC32 : " << fileinfo.getVisualBasicObjectTableHashCrc32() << "\n"; std::cout << "MD5 : " << fileinfo.getVisualBasicObjectTableHashMd5() << "\n"; std::cout << "SHA256 : " << fileinfo.getVisualBasicObjectTableHashSha256() << "\n"; + std::cout << "GUID : " << fileinfo.getVisualBasicObjectTableGUID() << "\n"; std::cout << "\n"; std::size_t cnt = 0; for (std::size_t i = 0; i < nObjs; i++) diff --git a/src/utils/conversion.cpp b/src/utils/conversion.cpp index 1526574b2..16331b40d 100644 --- a/src/utils/conversion.cpp +++ b/src/utils/conversion.cpp @@ -184,6 +184,25 @@ unsigned int byteSwap32(unsigned int val) { (0xFF & val) << 24; } +/** +* @brief Swap bytes for Intel x86 64-bit little-endian immediate. +* +* @param val Original value. +* +* @return Value with swapped bytes +*/ +unsigned long byteSwap64(unsigned long val) { + return (0xFF00000000000000 & val) >> 56 | + (0xFF000000000000 & val) >> 40 | + (0xFF0000000000 & val) >> 24 | + (0xFF00000000 & val) >> 8 | + (0xFF000000 & val) << 8 | + (0xFF0000 & val) << 24 | + (0xFF00 & val) << 40 | + (0xFF & val) << 56; +} + + /** * @brief Swap bytes for Intel x86 16-bit little-endian immediate. * From 894525476bfb5d01ade0c4e5114565d058cc6034 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Tue, 5 Feb 2019 15:09:00 +0100 Subject: [PATCH 16/33] prefix cut for project path --- .../types/visual_basic/visual_basic_info.cpp | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index 8c5a2fcd5..3bda9a7ef 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -125,7 +125,6 @@ bool VisualBasicInfo::getLanguageDLLSecondaryLCID(std::uint32_t &res) const */ const std::string &VisualBasicInfo::getProjectPath() const { - // if prefix else TODO return projectPath; } @@ -401,7 +400,24 @@ void VisualBasicInfo::setLanguageDLLSecondaryLCID(std::uint32_t lDLLSecLCID) */ void VisualBasicInfo::setProjectPath(const std::string &path) { - projectPath = path; + const std::string prefix = "*\\\\A"; + + if (prefix.size() > path.size()) + { + projectPath = path; + } + else + { + auto res = std::mismatch(prefix.begin(), prefix.end(), path.begin()); + if (res.first == prefix.end()) + { + projectPath = path.substr(prefix.size(), path.size() - prefix.size()); + } + else + { + projectPath = path; + } + } } /** From 12bebfc98e6c7d0f2291c6aecec56a9692c4d2b8 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Tue, 5 Feb 2019 15:09:30 +0100 Subject: [PATCH 17/33] modification for clawler needs --- src/fileformat/file_format/pe/pe_format.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 8db7c70fa..9d736cd06 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -841,6 +841,10 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, } visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); + + // TODO this line is added here just for convenient extraction of info offset + // for crawler tool and MUST BE DELETED WHEN DONE + visualBasicInfo.setTypeLibMinorVersion(vbcrd.regInfoOffset); return true; } From 998b227e50640e35fe0a79297a0d2e33a6cc2f1c Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 8 Feb 2019 14:33:58 +0100 Subject: [PATCH 18/33] addresses fixed --- .../fileformat/file_format/pe/pe_format.h | 12 +- src/fileformat/file_format/file_format.cpp | 16 ++- src/fileformat/file_format/pe/pe_format.cpp | 107 +++++++----------- 3 files changed, 61 insertions(+), 74 deletions(-) diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index df0f571a1..b175a1e3d 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -98,13 +98,11 @@ class PeFormat : public FileFormat /// @} /// @name Visual Basic methods /// @{ - bool parseVisualBasicProjectInfo(std::size_t structureOffset, std::size_t baseAddress); - bool parseVisualBasicExternTable(std::size_t structureOffset, std::size_t baseAddress, - std::size_t nEntries); - bool parseVisualBasicObjectTable(std::size_t structureOffset, std::size_t baseAddress); - bool parseVisualBasicObjects(std::size_t structureOffset, std::size_t baseAddress, - std::size_t nObjects); - bool parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress); + bool parseVisualBasicProjectInfo(std::size_t structureOffset); + bool parseVisualBasicExternTable(std::size_t structureOffset, std::size_t nEntries); + bool parseVisualBasicObjectTable(std::size_t structureOffset); + bool parseVisualBasicObjects(std::size_t structureOffset, std::size_t nObjects); + bool parseVisualBasicComRegistrationData(std::size_t structureOffset); /// @} protected: PeLib::PeFile *file; ///< PeLib representation of PE file diff --git a/src/fileformat/file_format/file_format.cpp b/src/fileformat/file_format/file_format.cpp index fe50fbeaf..c86004182 100644 --- a/src/fileformat/file_format/file_format.cpp +++ b/src/fileformat/file_format/file_format.cpp @@ -1121,7 +1121,13 @@ bool FileFormat::getOffsetFromAddress(unsigned long long &result, unsigned long return false; } - result = secSeg->getOffset() + (address - secSeg->getAddress()); + auto secSegAddr = secSeg->getAddress(); + if (secSegAddr > address) + { + return false; + } + + result = secSeg->getOffset() + (address - secSegAddr); return true; } @@ -1141,7 +1147,13 @@ bool FileFormat::getAddressFromOffset(unsigned long long &result, unsigned long return false; } - result = secSeg->getAddress() + (offset - secSeg->getOffset()); + auto secSegOffset = secSeg->getOffset(); + if (secSegOffset > offset) + { + return false; + } + + result = secSeg->getAddress() + (offset - secSegOffset); return true; } diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 9d736cd06..50aa3ccda 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -633,11 +633,10 @@ void PeFormat::loadVisualBasicHeader() auto allBytes = getBytes(); std::vector bytes; unsigned long long version = 0; - unsigned long long baseAddress = 0; - std::size_t vbHeaderAddress = 0; - std::size_t vbHeaderOffset = 0; - std::size_t vbProjectInfoOffset = 0; - std::size_t vbComDataRegistrationOffset = 0; + unsigned long long vbHeaderAddress = 0; + unsigned long long vbHeaderOffset = 0; + unsigned long long vbProjectInfoOffset = 0; + unsigned long long vbComDataRegistrationOffset = 0; std::string projLanguageDLL; std::string projBackupLanguageDLL; std::string projExeName; @@ -658,20 +657,12 @@ void PeFormat::loadVisualBasicHeader() return; } - if (!getImageBaseAddress(baseAddress)) - { - return; - } - vbHeaderAddress = bytes[4] << 24 | bytes[3] << 16 | bytes[2] << 8 | bytes[1]; - - if (vbHeaderAddress < baseAddress) + if (!getOffsetFromAddress(vbHeaderOffset, vbHeaderAddress)) { return; } - vbHeaderOffset = vbHeaderAddress - baseAddress; - if (!getBytes(bytes, vbHeaderOffset, vbh.headerSize()) || bytes.size() != vbh.headerSize()) { return; @@ -725,8 +716,6 @@ void PeFormat::loadVisualBasicHeader() vbh.projNameOffset = byteSwap32(vbh.projNameOffset); } - // TODO check VB header magic - if (vbh.projExeNameOffset != 0) { projExeName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), @@ -765,26 +754,23 @@ void PeFormat::loadVisualBasicHeader() visualBasicInfo.setLanguageDLLPrimaryLCID(vbh.LCID1); visualBasicInfo.setLanguageDLLSecondaryLCID(vbh.LCID2); - if (vbh.projectInfoAddr >= baseAddress) + if (getOffsetFromAddress(vbProjectInfoOffset, vbh.projectInfoAddr)) { - vbProjectInfoOffset = vbh.projectInfoAddr - baseAddress; - parseVisualBasicProjectInfo(vbProjectInfoOffset, baseAddress); + parseVisualBasicProjectInfo(vbProjectInfoOffset); } - if (vbh.COMRegisterDataAddr >= baseAddress) + if (getOffsetFromAddress(vbComDataRegistrationOffset, vbh.COMRegisterDataAddr)) { - vbComDataRegistrationOffset = vbh.COMRegisterDataAddr - baseAddress; - parseVisualBasicComRegistrationData(vbComDataRegistrationOffset, baseAddress); + parseVisualBasicComRegistrationData(vbComDataRegistrationOffset); } } /** * Parse visual basic COM registration data * @param structureOffset Offset in file where the structure starts - * @param baseAddress Base address * @return @c true if COM retistration data was successfuly parsed, @c false otherwise */ -bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, std::size_t baseAddress) +bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) { auto allBytes = getBytes(); std::vector bytes; @@ -851,14 +837,13 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset, /** * Parse visual basic project info * @param structureOffset Offset in file where the structure starts - * @param baseAddress Base address * @return @c true if project info was successfuly parsed, @c false otherwise */ -bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::size_t baseAddress) +bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset) { std::vector bytes; - std::size_t vbExternTableOffset = 0; - std::size_t vbObjectTableOffset = 0; + unsigned long long vbExternTableOffset = 0; + unsigned long long vbObjectTableOffset = 0; std::string projPath; std::size_t offset = 0; struct VBProjInfo vbpi; @@ -900,16 +885,14 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz visualBasicInfo.setProjectPath(projPath); visualBasicInfo.setPcode(vbpi.nativeCodeAddr == 0); - if (vbpi.externalTableAddr >= baseAddress) + if (getOffsetFromAddress(vbExternTableOffset, vbpi.externalTableAddr)) { - vbExternTableOffset = vbpi.externalTableAddr - baseAddress; - parseVisualBasicExternTable(vbExternTableOffset, baseAddress, vbpi.nExternals); + parseVisualBasicExternTable(vbExternTableOffset, vbpi.nExternals); } - if (vbpi.objectTableAddr >= baseAddress) + if (getOffsetFromAddress(vbObjectTableOffset, vbpi.objectTableAddr)) { - vbObjectTableOffset = vbpi.objectTableAddr - baseAddress; - parseVisualBasicObjectTable(vbObjectTableOffset, baseAddress); + parseVisualBasicObjectTable(vbObjectTableOffset); } return true; @@ -918,18 +901,16 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset, std::siz /** * Parse visual basic extern table * @param structureOffset Offset in file where the structure starts - * @param baseAddress Base address * @param nEntries Number of entries in table * @return @c true if extern table was successfuly parsed, @c false otherwise */ -bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::size_t baseAddress, - std::size_t nEntries) +bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::size_t nEntries) { auto allBytes = getBytes(); std::vector bytes; struct VBExternTableEntry entry; struct VBExternTableEntryData entryData; - std::size_t vbExternEntryDataOffset = 0; + unsigned long long vbExternEntryDataOffset = 0; std::size_t offset = 0; for (std::size_t i = 0; i < nEntries; i++) @@ -953,13 +934,15 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz entry.importDataAddr = byteSwap32(entry.importDataAddr); } - if (entry.type != static_cast(VBExternTableEntryType::external) - || entry.importDataAddr < baseAddress) + if (entry.type != static_cast(VBExternTableEntryType::external)) { continue; } - vbExternEntryDataOffset = entry.importDataAddr - baseAddress; + if (!getOffsetFromAddress(vbExternEntryDataOffset, entry.importDataAddr)) + { + continue; + } if (!getBytes(bytes, vbExternEntryDataOffset, entryData.structureSize()) || bytes.size() != entryData.structureSize()) @@ -977,15 +960,15 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz entryData.apiNameAddr = byteSwap32(entryData.apiNameAddr); } - if (entryData.moduleNameAddr >= baseAddress) + unsigned long long moduleNameOffset; + if (!getOffsetFromAddress(moduleNameOffset, entryData.moduleNameAddr)) { - std::size_t moduleNameOffset = entryData.moduleNameAddr - baseAddress; moduleName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), moduleNameOffset); } - if (entryData.apiNameAddr >= baseAddress) + unsigned long long apiNameOffset; + if (!getOffsetFromAddress(apiNameOffset, entryData.apiNameAddr)) { - std::size_t apiNameOffset = entryData.apiNameAddr - baseAddress; apiName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), apiNameOffset); } @@ -1003,16 +986,15 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz /** * Parse visual basic object table * @param structureOffset Offset in file where the structure starts - * @param baseAddress Base address * @return @c true if object table was successfuly parsed, @c false otherwise */ -bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::size_t baseAddress) +bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) { auto allBytes = getBytes(); std::vector bytes; std::size_t offset = 0; - std::size_t projectNameOffset = 0; - std::size_t objectDescriptorsOffset = 0; + unsigned long long projectNameOffset = 0; + unsigned long long objectDescriptorsOffset = 0; struct VBObjectTable vbot; std::string projName; @@ -1069,17 +1051,15 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); visualBasicInfo.setObjectTableGUID(vbot.objectGUID); - if (!visualBasicInfo.hasProjectName() && vbot.projectNameAddr >= baseAddress) + if (!visualBasicInfo.hasProjectName() && getOffsetFromAddress(projectNameOffset, vbot.projectNameAddr)) { - projectNameOffset = vbot.projectNameAddr - baseAddress; projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset); visualBasicInfo.setProjectName(projName); } - if (vbot.objectDescriptorsAddr >= baseAddress) + if (getOffsetFromAddress(objectDescriptorsOffset, vbot.objectDescriptorsAddr)) { - objectDescriptorsOffset = vbot.objectDescriptorsAddr - baseAddress; - parseVisualBasicObjects(objectDescriptorsOffset, baseAddress, vbot.nObjects); + parseVisualBasicObjects(objectDescriptorsOffset, vbot.nObjects); } visualBasicInfo.computeObjectTableHashes(); @@ -1089,12 +1069,10 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset, std::siz /** * Parse visual basic objects * @param structureOffset Offset in file where the public object descriptors array starts - * @param baseAddress Base address * @param nObjects Number of objects in array * @return @c true if objects were successfuly parsed, @c false otherwise */ -bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t baseAddress, - std::size_t nObjects) +bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t nObjects) { auto allBytes = getBytes(); std::vector bytes; @@ -1140,20 +1118,19 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t vbpod.null = byteSwap32(vbpod.null); } - if (vbpod.objectNameAddr < baseAddress) + unsigned long long objectNameOffset; + if (!getOffsetFromAddress(objectNameOffset, vbpod.objectNameAddr)) { continue; } - - std::size_t objectNameOffset = vbpod.objectNameAddr - baseAddress; std::string objectName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), objectNameOffset); object = std::make_unique(); object->setName(objectName); - if (vbpod.methodNamesAddr >= baseAddress) + unsigned long long methodAddrOffset; + if (getOffsetFromAddress(methodAddrOffset, vbpod.methodNamesAddr)) { - std::size_t methodAddrOffset = vbpod.methodNamesAddr - baseAddress; for (std::size_t mIdx = 0; mIdx < vbpod.nMethods; mIdx++) { if (!getBytes(bytes, methodAddrOffset + mIdx * sizeof(std::uint32_t), sizeof(std::uint32_t)) @@ -1162,19 +1139,19 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t break; } - std::uint32_t methodNameAddr = *reinterpret_cast(bytes.data()); + auto methodNameAddr = *reinterpret_cast(bytes.data()); if (!isLittleEndian()) { methodNameAddr = byteSwap32(methodNameAddr); } - if (methodNameAddr < baseAddress) + unsigned long long methodNameOffset; + if (!getOffsetFromAddress(methodNameOffset, methodNameAddr)) { continue; } - std::size_t methodNameOffset = methodNameAddr - baseAddress; std::string methodName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), methodNameOffset); object->addMethod(methodName); } From 62d479f3bdbf66b39e2c6df1eeef0b603d7a433e Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 9 Feb 2019 14:44:08 +0100 Subject: [PATCH 19/33] export table extraction fixed --- src/fileformat/file_format/pe/pe_format.cpp | 4 ++-- .../visual_basic_extern_table_plain_getter.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 50aa3ccda..f510a2b8e 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -961,13 +961,13 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz } unsigned long long moduleNameOffset; - if (!getOffsetFromAddress(moduleNameOffset, entryData.moduleNameAddr)) + if (getOffsetFromAddress(moduleNameOffset, entryData.moduleNameAddr)) { moduleName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), moduleNameOffset); } unsigned long long apiNameOffset; - if (!getOffsetFromAddress(apiNameOffset, entryData.apiNameAddr)) + if (getOffsetFromAddress(apiNameOffset, entryData.apiNameAddr)) { apiName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), apiNameOffset); } diff --git a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp index e87425223..4596a3326 100644 --- a/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/iterative_getter/iterative_distribution_getter/visual_basic_extern_table_plain_getter.cpp @@ -49,7 +49,8 @@ VisualBasicExternTablePlainGetter::~VisualBasicExternTablePlainGetter() std::size_t VisualBasicExternTablePlainGetter::getBasicInfo(std::size_t structIndex, std::vector &desc, std::vector &info) const { - if(structIndex >= numberOfStructures || !fileinfo.isVisualBasicUsed()) + if(structIndex >= numberOfStructures || !fileinfo.isVisualBasicUsed() + || !fileinfo.getVisualBasicNumberOfExterns()) { return 0; } From b722c0de17c1cf9b18df1beaf11c71cef9c18932 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 9 Feb 2019 19:36:29 +0100 Subject: [PATCH 20/33] COM Registration Info parsed --- .../fileformat/file_format/pe/pe_format.h | 2 + .../types/visual_basic/visual_basic_info.h | 20 +++ .../visual_basic/visual_basic_structures.h | 58 +++++++++ src/fileformat/file_format/pe/pe_format.cpp | 117 +++++++++++++++++- .../types/visual_basic/visual_basic_info.cpp | 115 ++++++++++++++++- 5 files changed, 306 insertions(+), 6 deletions(-) diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index b175a1e3d..a52dcc931 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -103,6 +103,8 @@ class PeFormat : public FileFormat bool parseVisualBasicObjectTable(std::size_t structureOffset); bool parseVisualBasicObjects(std::size_t structureOffset, std::size_t nObjects); bool parseVisualBasicComRegistrationData(std::size_t structureOffset); + bool parseVisualBasicComRegistrationInfo(std::size_t structureOffset, + std::size_t comRegDataOffset); /// @} protected: PeLib::PeFile *file; ///< PeLib representation of PE file diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h index 9d32b2742..d56b7ff02 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -51,6 +51,14 @@ class VisualBasicInfo std::uint16_t typeLibMajorVersion; std::uint16_t typeLibMinorVersion; + // COM register info + std::string COMObjectName; + std::string COMObjectDescription; + std::string COMObjectCLSID; + std::string COMObjectInterfaceCLSID; + std::string COMObjectEventsCLSID; + std::string COMObjectType; + // others std::string externTableHashCrc32; std::string externTableHashMd5; @@ -96,6 +104,12 @@ class VisualBasicInfo bool getTypeLibLCID(std::uint32_t &res) const; std::uint16_t getTypeLibMajorVersion() const; std::uint16_t getTypeLibMinorVersion() const; + const std::string &getCOMObjectName(); + const std::string &getCOMObjectDescription(); + const std::string &getCOMObjectCLSID(); + const std::string &getCOMObjectInterfaceCLSID(); + const std::string &getCOMObjectEventsCLSID(); + const std::string &getCOMObjectType(); const std::string &getExternTableHashCrc32() const; const std::string &getExternTableHashMd5() const; const std::string &getExternTableHashSha256() const; @@ -123,6 +137,12 @@ class VisualBasicInfo void setObjectTableGUID(const std::uint8_t data[16]); void setTypeLibMajorVersion(std::uint16_t majVer); void setTypeLibMinorVersion(std::uint16_t minVer); + void setCOMObjectName(const std::string &name); + void setCOMObjectDescription(const std::string &description); + void setCOMObjectCLSID(const std::uint8_t data[16]); + void setCOMObjectInterfaceCLSID(const std::uint8_t data[16]); + void setCOMObjectEventsCLSID(const std::uint8_t data[16]); + void setCOMObjectType(std::uint8_t type); /// @} /// @name Other methods diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h index df5a91f29..9b1471ba7 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -360,6 +360,64 @@ struct VBCOMRData } }; +struct VBCOMRInfo +{ + std::uint32_t ifInfoOffset; ///< Offset to COM Interface Info + std::uint32_t objNameOffset; ///< Offset to object name + std::uint32_t objDescOffset; ///< Offset to object description + std::uint32_t instancing; ///< Instancing mode + std::uint32_t objID; ///< Object ID within project + std::uint8_t objCLSID[16]; ///< Object CLSID + std::uint32_t isInterfaceFlag; ///< Specifies whether Interface CLSID is valid + std::uint32_t ifCLSIDOffset; ///< Interface CLSID + std::uint32_t eventCLSIDOffset; ///< Event CLSID + std::uint32_t hasEvents; ///< Specifies whether Event CLSID is valid + std::uint32_t olemicsFlags; ///< Status + std::uint8_t classType; ///< Class Type + std::uint8_t objectType; ///< Object Type + std::uint16_t toolboxBitmap32; ///< Control Bitmap ID in toobox + std::uint16_t defaultIcon; ///< Minimized icon of control window + std::uint16_t isDesignerFlag; ///< Specifies whether Designed Data offset is valid + std::uint32_t designerDataOffset; ///< Offset to Designed Data + + VBCOMRInfo() + { + + } + + std::size_t structureSize() + { + return + sizeof(ifInfoOffset) + sizeof(objNameOffset) + sizeof(objDescOffset) + + sizeof(instancing) + sizeof(objID) + sizeof(objCLSID) + sizeof(isInterfaceFlag) + + sizeof(ifCLSIDOffset) + sizeof(eventCLSIDOffset) + sizeof(hasEvents) + + sizeof(olemicsFlags) + sizeof(classType) + sizeof(objectType) + + sizeof(toolboxBitmap32) + sizeof(defaultIcon) + sizeof(isDesignerFlag) + + sizeof(designerDataOffset); + } + + void dump(std::ostream &out) + { + out << std::hex; + out << "ifInfoOffset:\t\t" << ifInfoOffset << "\n"; + out << "objNameOffset:\t\t" << objNameOffset << "\n"; + out << "objDescOffset:\t\t" << objDescOffset << "\n"; + out << "instancing:\t\t" << instancing << "\n"; + out << "objID:\t\t" << objID << "\n"; + out << "isInterfaceFlag:\t\t" << isInterfaceFlag << "\n"; + out << "ifCLSIDOffset:\t\t" << ifCLSIDOffset << "\n"; + out << "eventCLSIDOffset:\t\t" << eventCLSIDOffset << "\n"; + out << "hasEvents:\t\t" << hasEvents << "\n"; + out << "olemicsFlags:\t\t" << olemicsFlags << "\n"; + out << "classType:\t\t" << static_cast(classType) << "\n"; + out << "objectType:\t\t" << static_cast(objectType) << "\n"; + out << "toolboxBitmap32:\t\t" << toolboxBitmap32 << "\n"; + out << "defaultIcon:\t\t" << defaultIcon << "\n"; + out << "isDesignerFlag:\t\t" << isDesignerFlag << "\n"; + out << "designerDataOffset:\t\t" << designerDataOffset << "\n"; + } +}; + } // namespace fileformat } // namespace retdec diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index f510a2b8e..3ce62e892 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -768,7 +768,7 @@ void PeFormat::loadVisualBasicHeader() /** * Parse visual basic COM registration data * @param structureOffset Offset in file where the structure starts - * @return @c true if COM retistration data was successfuly parsed, @c false otherwise + * @return @c true if COM registration data was successfuly parsed, @c false otherwise */ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) { @@ -807,20 +807,20 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); } - visualBasicInfo.setTypeLibLCID(vbcrd.projDescOffset); + visualBasicInfo.setTypeLibLCID(vbcrd.projTlbLCID); visualBasicInfo.setTypeLibMajorVersion(vbcrd.tlbVerMajor); visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); - if (!visualBasicInfo.hasProjectName()) + if (!visualBasicInfo.hasProjectName() && vbcrd.projNameOffset != 0) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.projNameOffset); } - if (!visualBasicInfo.hasProjectHelpFile()) + if (!visualBasicInfo.hasProjectHelpFile() && vbcrd.helpFileOffset != 0) { helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.helpFileOffset); } - if (!visualBasicInfo.hasProjectDescription()) + if (!visualBasicInfo.hasProjectDescription() && vbcrd.projDescOffset != 0) { projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), structureOffset + vbcrd.projDescOffset); @@ -831,6 +831,113 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) // TODO this line is added here just for convenient extraction of info offset // for crawler tool and MUST BE DELETED WHEN DONE visualBasicInfo.setTypeLibMinorVersion(vbcrd.regInfoOffset); + + if (vbcrd.regInfoOffset != 0) + { + parseVisualBasicComRegistrationInfo(structureOffset + vbcrd.regInfoOffset, structureOffset); + } + + return true; +} + +/** + * Parse visual basic COM registration info + * @param structureOffset Offset in file where the structure starts + * @param comRegDataOffset Offset in file where the com registration data structure starts + * @return @c true if COM registration info was successfuly parsed, @c false otherwise + */ +bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, + std::size_t comRegDataOffset) +{ + auto allBytes = getBytes(); + std::vector bytes; + std::size_t offset = 0; + struct VBCOMRInfo vbcri; + std::string COMObjectName; + std::string COMObjectDesc; + + if (!getBytes(bytes, structureOffset, vbcri.structureSize()) || bytes.size() != vbcri.structureSize()) + { + return false; + } + + vbcri.ifInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.ifInfoOffset); + vbcri.objNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objNameOffset); + vbcri.objDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objDescOffset); + vbcri.instancing = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.instancing); + vbcri.objID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objID); + std::memcpy(&vbcri.objCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcri.objCLSID)); offset += sizeof(vbcri.objCLSID); + vbcri.isInterfaceFlag = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.isInterfaceFlag); + vbcri.ifCLSIDOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.ifCLSIDOffset); + vbcri.eventCLSIDOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.eventCLSIDOffset); + vbcri.hasEvents = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.hasEvents); + vbcri.olemicsFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.olemicsFlags); + vbcri.classType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.classType); + vbcri.objectType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objectType); + vbcri.toolboxBitmap32 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.toolboxBitmap32); + vbcri.defaultIcon = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.defaultIcon); + vbcri.isDesignerFlag = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.isDesignerFlag); + vbcri.designerDataOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.designerDataOffset); + + if (!isLittleEndian()) + { + vbcri.ifInfoOffset = byteSwap32(vbcri.ifInfoOffset); + vbcri.objNameOffset = byteSwap32(vbcri.objNameOffset); + vbcri.objDescOffset = byteSwap32(vbcri.objDescOffset); + vbcri.instancing = byteSwap32(vbcri.instancing); + vbcri.objID = byteSwap32(vbcri.objID); + vbcri.isInterfaceFlag = byteSwap32(vbcri.isInterfaceFlag); + vbcri.ifCLSIDOffset = byteSwap32(vbcri.ifCLSIDOffset); + vbcri.eventCLSIDOffset = byteSwap32(vbcri.eventCLSIDOffset); + vbcri.hasEvents = byteSwap32(vbcri.hasEvents); + vbcri.olemicsFlags = byteSwap32(vbcri.olemicsFlags); + vbcri.toolboxBitmap32 = byteSwap16(vbcri.toolboxBitmap32); + vbcri.defaultIcon = byteSwap16(vbcri.defaultIcon); + vbcri.isDesignerFlag = byteSwap16(vbcri.isDesignerFlag); + vbcri.designerDataOffset = byteSwap32(vbcri.designerDataOffset); + } + + // kubo TODO DELME + if (vbcri.objNameOffset != 0) + { + COMObjectName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + comRegDataOffset + vbcri.objNameOffset); + visualBasicInfo.setCOMObjectName(COMObjectName); + } + if (vbcri.objDescOffset != 0) + { + COMObjectDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + comRegDataOffset + vbcri.objDescOffset); + visualBasicInfo.setCOMObjectDescription(COMObjectDesc); + } + + visualBasicInfo.setCOMObjectCLSID(vbcri.objCLSID); + visualBasicInfo.setCOMObjectType(vbcri.objectType); + + if (vbcri.isInterfaceFlag != 0 && vbcri.ifCLSIDOffset != 0 && + getBytes(bytes, comRegDataOffset + vbcri.ifCLSIDOffset, 16) && bytes.size() == 16) + { + visualBasicInfo.setCOMObjectInterfaceCLSID(bytes.data()); + } + + if (vbcri.hasEvents != 0 && vbcri.eventCLSIDOffset != 0 && + getBytes(bytes, comRegDataOffset + vbcri.eventCLSIDOffset, 16) && bytes.size() == 16) + { + visualBasicInfo.setCOMObjectEventsCLSID(bytes.data()); + } + + // if (DESIGNER) + // { + // TODO DESIGNER + // } + + std::cerr << "name: " << COMObjectName << "\n"; + std::cerr << "desc: " << COMObjectDesc << "\n"; + std::cerr << "type: " << visualBasicInfo.getCOMObjectType() << "\n"; + std::cerr << "objCLSID: " << visualBasicInfo.getCOMObjectCLSID() << "\n"; + std::cerr << "ifCLSID: " << visualBasicInfo.getCOMObjectInterfaceCLSID() << "\n"; + std::cerr << "evCLSID: " << visualBasicInfo.getCOMObjectEventsCLSID() << "\n"; + return true; } diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index 3bda9a7ef..924d46eec 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -265,6 +265,59 @@ std::uint16_t VisualBasicInfo::getTypeLibMinorVersion() const return typeLibMinorVersion; } +/** + * Get COM object name + * @return COM object name + */ +const std::string &VisualBasicInfo::getCOMObjectName() +{ + return COMObjectName; +} + +/** + * Get COM object description + * @return COM object description + */ +const std::string &VisualBasicInfo::getCOMObjectDescription() +{ + return COMObjectDescription; +} + +/** + * Get COM object CLSID + * @return COM object CLSID + */ +const std::string &VisualBasicInfo::getCOMObjectCLSID() +{ + return COMObjectCLSID; +} + +/** + * Get COM object interface CLSID + * @return COM object interface CLSID + */ +const std::string &VisualBasicInfo::getCOMObjectInterfaceCLSID() +{ + return COMObjectInterfaceCLSID; +} + +/** + * Get COM object events CLSID + * @return COM object events CLSID + */ +const std::string &VisualBasicInfo::getCOMObjectEventsCLSID() +{ + return COMObjectEventsCLSID; +} + +/** + * Get COM object type + * @return COM object type + */ +const std::string &VisualBasicInfo::getCOMObjectType() +{ + return COMObjectType; +} /** * Get extern table hash as CRC32 @@ -400,7 +453,7 @@ void VisualBasicInfo::setLanguageDLLSecondaryLCID(std::uint32_t lDLLSecLCID) */ void VisualBasicInfo::setProjectPath(const std::string &path) { - const std::string prefix = "*\\\\A"; + const std::string prefix = "*\\A"; if (prefix.size() > path.size()) { @@ -495,6 +548,66 @@ void VisualBasicInfo::setTypeLibMinorVersion(std::uint16_t minVer) typeLibMinorVersion = minVer; } +/** + * Set COM object name + * @param name COM object name to set + */ +void VisualBasicInfo::setCOMObjectName(const std::string &name) +{ + COMObjectName = name; +} + +/** + * Set COM object description + * @param description COM object description to set + */ +void VisualBasicInfo::setCOMObjectDescription(const std::string &description) +{ + COMObjectDescription = description; +} + +/** + * Set COM object CLSID + * @param data Raw CLSID data + */ +void VisualBasicInfo::setCOMObjectCLSID(const std::uint8_t data[16]) +{ + COMObjectCLSID = guidToStr(data); +} + +/** + * Set COM object interfaceCLSID + * @param data Raw CLSID data + */ +void VisualBasicInfo::setCOMObjectInterfaceCLSID(const std::uint8_t data[16]) +{ + COMObjectInterfaceCLSID = guidToStr(data); +} + +/** + * Set COM object eventsCLSID + * @param data Raw CLSID data + */ +void VisualBasicInfo::setCOMObjectEventsCLSID(const std::uint8_t data[16]) +{ + COMObjectEventsCLSID = guidToStr(data); +} + +/** + * Set COM object type + * @param type COM object type to set + */ +void VisualBasicInfo::setCOMObjectType(std::uint8_t type) +{ + switch (type) + { + case 0x2: COMObjectType = "Designer"; break; + case 0x10: COMObjectType = "ClassModule"; break; + case 0x20: COMObjectType = "ActiveXUserControl"; break; + case 0x80: COMObjectType = "UserDocument"; break; + default: COMObjectType = "unknown"; break; + } +} /** * Add visual basic object From 699c1fbf76814d39da26b5d0211ecb3504d16c20 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 9 Feb 2019 20:56:40 +0100 Subject: [PATCH 21/33] COM Registration Info plain presentation --- .../types/visual_basic/visual_basic_info.h | 18 ++--- src/fileformat/file_format/pe/pe_format.cpp | 17 ----- .../types/visual_basic/visual_basic_info.cpp | 42 ++++++++---- .../file_information/file_information.cpp | 54 +++++++++++++++ .../file_information/file_information.h | 6 ++ .../visual_basic_info.cpp | 68 ++++++++++++++++++- .../visual_basic_info.h | 6 ++ .../visual_basic_plain_getter.cpp | 13 ++++ 8 files changed, 183 insertions(+), 41 deletions(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h index d56b7ff02..a6281eef0 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_info.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_info.h @@ -72,6 +72,8 @@ class VisualBasicInfo bool validProjectPrimaryLCID; bool validProjectSecondaryLCID; bool validTypeLibLCID; + bool validTypeLibMajorVersion; + bool validTypeLibMinorVersion; bool pcodeFlag; std::string guidToStr(const std::uint8_t data[16]); @@ -102,14 +104,14 @@ class VisualBasicInfo const std::string &getObjectTableGUID() const; const std::string &getTypeLibCLSID() const; bool getTypeLibLCID(std::uint32_t &res) const; - std::uint16_t getTypeLibMajorVersion() const; - std::uint16_t getTypeLibMinorVersion() const; - const std::string &getCOMObjectName(); - const std::string &getCOMObjectDescription(); - const std::string &getCOMObjectCLSID(); - const std::string &getCOMObjectInterfaceCLSID(); - const std::string &getCOMObjectEventsCLSID(); - const std::string &getCOMObjectType(); + bool getTypeLibMajorVersion(std::uint16_t &res) const; + bool getTypeLibMinorVersion(std::uint16_t &res) const; + const std::string &getCOMObjectName() const; + const std::string &getCOMObjectDescription() const; + const std::string &getCOMObjectCLSID() const; + const std::string &getCOMObjectInterfaceCLSID() const; + const std::string &getCOMObjectEventsCLSID() const; + const std::string &getCOMObjectType() const; const std::string &getExternTableHashCrc32() const; const std::string &getExternTableHashMd5() const; const std::string &getExternTableHashSha256() const; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 3ce62e892..4890fde3a 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -828,10 +828,6 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); - // TODO this line is added here just for convenient extraction of info offset - // for crawler tool and MUST BE DELETED WHEN DONE - visualBasicInfo.setTypeLibMinorVersion(vbcrd.regInfoOffset); - if (vbcrd.regInfoOffset != 0) { parseVisualBasicComRegistrationInfo(structureOffset + vbcrd.regInfoOffset, structureOffset); @@ -897,7 +893,6 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, vbcri.designerDataOffset = byteSwap32(vbcri.designerDataOffset); } - // kubo TODO DELME if (vbcri.objNameOffset != 0) { COMObjectName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), @@ -926,18 +921,6 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, visualBasicInfo.setCOMObjectEventsCLSID(bytes.data()); } - // if (DESIGNER) - // { - // TODO DESIGNER - // } - - std::cerr << "name: " << COMObjectName << "\n"; - std::cerr << "desc: " << COMObjectDesc << "\n"; - std::cerr << "type: " << visualBasicInfo.getCOMObjectType() << "\n"; - std::cerr << "objCLSID: " << visualBasicInfo.getCOMObjectCLSID() << "\n"; - std::cerr << "ifCLSID: " << visualBasicInfo.getCOMObjectInterfaceCLSID() << "\n"; - std::cerr << "evCLSID: " << visualBasicInfo.getCOMObjectEventsCLSID() << "\n"; - return true; } diff --git a/src/fileformat/types/visual_basic/visual_basic_info.cpp b/src/fileformat/types/visual_basic/visual_basic_info.cpp index 924d46eec..46d147ae4 100644 --- a/src/fileformat/types/visual_basic/visual_basic_info.cpp +++ b/src/fileformat/types/visual_basic/visual_basic_info.cpp @@ -20,10 +20,10 @@ namespace fileformat { * Constructor */ VisualBasicInfo::VisualBasicInfo() : languageDLLPrimaryLCID(0), languageDLLSecondaryLCID(0), - projectPrimaryLCID(0), projectSecondaryLCID(0), typeLibLCID(0), typeLibMajorVersion(1), + projectPrimaryLCID(0), projectSecondaryLCID(0), typeLibLCID(0), typeLibMajorVersion(0), typeLibMinorVersion(0), validLanguageDLLPrimaryLCID(false), validLanguageDLLSecondaryLCID(false), validProjectPrimaryLCID(false), validProjectSecondaryLCID(false), validTypeLibLCID(false), - pcodeFlag(false) + validTypeLibMajorVersion(false), validTypeLibMinorVersion(false), pcodeFlag(false) { } @@ -249,27 +249,39 @@ bool VisualBasicInfo::getTypeLibLCID(std::uint32_t &res) const /** * Get typeLib major version - * @return TypeLib major version + * @param res Variable to store result to + * @return @c true if typeLib major version is valid, @c false otherwise */ -std::uint16_t VisualBasicInfo::getTypeLibMajorVersion() const +bool VisualBasicInfo::getTypeLibMajorVersion(std::uint16_t &res) const { - return typeLibMajorVersion; + if (!validTypeLibMajorVersion) + { + return false; + } + res = typeLibMajorVersion; + return true; } /** * Get typeLib minor version - * @return TypeLib minor version + * @param res Variable to store result to + * @return @c true if typeLib minor version is valid, @c false otherwise */ -std::uint16_t VisualBasicInfo::getTypeLibMinorVersion() const +bool VisualBasicInfo::getTypeLibMinorVersion(std::uint16_t &res) const { - return typeLibMinorVersion; + if (!validTypeLibMinorVersion) + { + return false; + } + res = typeLibMinorVersion; + return true; } /** * Get COM object name * @return COM object name */ -const std::string &VisualBasicInfo::getCOMObjectName() +const std::string &VisualBasicInfo::getCOMObjectName() const { return COMObjectName; } @@ -278,7 +290,7 @@ const std::string &VisualBasicInfo::getCOMObjectName() * Get COM object description * @return COM object description */ -const std::string &VisualBasicInfo::getCOMObjectDescription() +const std::string &VisualBasicInfo::getCOMObjectDescription() const { return COMObjectDescription; } @@ -287,7 +299,7 @@ const std::string &VisualBasicInfo::getCOMObjectDescription() * Get COM object CLSID * @return COM object CLSID */ -const std::string &VisualBasicInfo::getCOMObjectCLSID() +const std::string &VisualBasicInfo::getCOMObjectCLSID() const { return COMObjectCLSID; } @@ -296,7 +308,7 @@ const std::string &VisualBasicInfo::getCOMObjectCLSID() * Get COM object interface CLSID * @return COM object interface CLSID */ -const std::string &VisualBasicInfo::getCOMObjectInterfaceCLSID() +const std::string &VisualBasicInfo::getCOMObjectInterfaceCLSID() const { return COMObjectInterfaceCLSID; } @@ -305,7 +317,7 @@ const std::string &VisualBasicInfo::getCOMObjectInterfaceCLSID() * Get COM object events CLSID * @return COM object events CLSID */ -const std::string &VisualBasicInfo::getCOMObjectEventsCLSID() +const std::string &VisualBasicInfo::getCOMObjectEventsCLSID() const { return COMObjectEventsCLSID; } @@ -314,7 +326,7 @@ const std::string &VisualBasicInfo::getCOMObjectEventsCLSID() * Get COM object type * @return COM object type */ -const std::string &VisualBasicInfo::getCOMObjectType() +const std::string &VisualBasicInfo::getCOMObjectType() const { return COMObjectType; } @@ -537,6 +549,7 @@ void VisualBasicInfo::setObjectTableGUID(const std::uint8_t data[16]) void VisualBasicInfo::setTypeLibMajorVersion(std::uint16_t majVer) { typeLibMajorVersion = majVer; + validTypeLibMajorVersion = true; } /** @@ -546,6 +559,7 @@ void VisualBasicInfo::setTypeLibMajorVersion(std::uint16_t majVer) void VisualBasicInfo::setTypeLibMinorVersion(std::uint16_t minVer) { typeLibMinorVersion = minVer; + validTypeLibMinorVersion = true; } /** diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index b1b003f59..91cc1084a 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -1005,6 +1005,60 @@ std::string FileInformation::getVisualBasicTypeLibLCIDStr() const return visualBasicInfo.getTypeLibLCIDStr(); } +/** + * Get visual basic COM object name + * @return Visual basic COM object name + */ +std::string FileInformation::getVisualBasicCOMObjectName() const +{ + return visualBasicInfo.getCOMObjectName(); +} + +/** + * Get visual basic COM object description + * @return Visual basic COM object description + */ +std::string FileInformation::getVisualBasicCOMObjectDescription() const +{ + return visualBasicInfo.getCOMObjectDescription(); +} + +/** + * Get visual basic COM object CLSID + * @return Visual basic COM object CLSID + */ +std::string FileInformation::getVisualBasicCOMObjectCLSID() const +{ + return visualBasicInfo.getCOMObjectCLSID(); +} + +/** + * Get visual basic COM object interface CLSID + * @return Visual basic COM object interface CLSID + */ +std::string FileInformation::getVisualBasicCOMObjectInterfaceCLSID() const +{ + return visualBasicInfo.getCOMObjectInterfaceCLSID(); +} + +/** + * Get visual basic COM object events CLSID + * @return Visual basic COM object events CLSID + */ +std::string FileInformation::getVisualBasicCOMObjectEventsCLSID() const +{ + return visualBasicInfo.getCOMObjectEventsCLSID(); +} + +/** + * Get visual basic COM object type + * @return Visual basic COM object type + */ +std::string FileInformation::getVisualBasicCOMObjectType() const +{ + return visualBasicInfo.getCOMObjectType(); +} + /** * Get visual basic extern table hash as Crc32 * @return Visual basic extern table hash diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 595221dad..56261e630 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -179,6 +179,12 @@ class FileInformation std::string getVisualBasicTypeLibMajorVersionStr() const; std::string getVisualBasicTypeLibMinorVersionStr() const; std::string getVisualBasicTypeLibLCIDStr() const; + std::string getVisualBasicCOMObjectName() const; + std::string getVisualBasicCOMObjectDescription() const; + std::string getVisualBasicCOMObjectCLSID() const; + std::string getVisualBasicCOMObjectInterfaceCLSID() const; + std::string getVisualBasicCOMObjectEventsCLSID() const; + std::string getVisualBasicCOMObjectType() const; std::string getVisualBasicExternTableHashCrc32() const; std::string getVisualBasicExternTableHashMd5() const; std::string getVisualBasicExternTableHashSha256() const; diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index 81b65fc6d..49ef67bb8 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -230,7 +230,12 @@ std::string VisualBasicInfo::getTypeLibCLSID() const */ std::string VisualBasicInfo::getTypeLibMajorVersionStr() const { - return visualBasicInfo ? getNumberAsString(visualBasicInfo->getTypeLibMajorVersion()) : ""; + std::uint16_t majV; + if (!visualBasicInfo || !visualBasicInfo->getTypeLibMajorVersion(majV)) + { + return ""; + } + return getNumberAsString(majV); } /** @@ -239,7 +244,12 @@ std::string VisualBasicInfo::getTypeLibMajorVersionStr() const */ std::string VisualBasicInfo::getTypeLibMinorVersionStr() const { - return visualBasicInfo ? getNumberAsString(visualBasicInfo->getTypeLibMinorVersion()) : ""; + std::uint16_t minV; + if (!visualBasicInfo || !visualBasicInfo->getTypeLibMinorVersion(minV)) + { + return ""; + } + return getNumberAsString(minV); } /** @@ -256,6 +266,60 @@ std::string VisualBasicInfo::getTypeLibLCIDStr() const return getNumberAsString(lcid); } +/** + * Get COM object name + * @return Visual basic COM object name + */ +std::string VisualBasicInfo::getCOMObjectName() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectName() : ""; +} + +/** + * Get COM object description + * @return Visual basic COM object description + */ +std::string VisualBasicInfo::getCOMObjectDescription() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectDescription() : ""; +} + +/** + * Get COM object CLSID + * @return Visual basic COM object CLSID + */ +std::string VisualBasicInfo::getCOMObjectCLSID() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectCLSID() : ""; +} + +/** + * Get COM object interface CLSID + * @return Visual basic COM object interface CLSID + */ +std::string VisualBasicInfo::getCOMObjectInterfaceCLSID() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectInterfaceCLSID() : ""; +} + +/** + * Get COM object events CLSID + * @return Visual basic COM object events CLSID + */ +std::string VisualBasicInfo::getCOMObjectEventsCLSID() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectEventsCLSID() : ""; +} + +/** + * Get COM object type + * @return Visual basic COM object type + */ +std::string VisualBasicInfo::getCOMObjectType() const +{ + return visualBasicInfo ? visualBasicInfo->getCOMObjectType() : ""; +} + /** * Get extern table hash as CRC32 * @return Extern table hash diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.h b/src/fileinfo/file_information/file_information_types/visual_basic_info.h index 9b31eece9..71d678118 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.h +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.h @@ -49,6 +49,12 @@ class VisualBasicInfo std::string getTypeLibMajorVersionStr() const; std::string getTypeLibMinorVersionStr() const; std::string getTypeLibLCIDStr() const; + std::string getCOMObjectName() const; + std::string getCOMObjectDescription() const; + std::string getCOMObjectCLSID() const; + std::string getCOMObjectInterfaceCLSID() const; + std::string getCOMObjectEventsCLSID() const; + std::string getCOMObjectType() const; std::string getExternTableHashCrc32() const; std::string getExternTableHashMd5() const; std::string getExternTableHashSha256() const; diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp index 4d14f9283..35829bc26 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -54,6 +54,12 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de desc.push_back("TypeLib major version : "); desc.push_back("TypeLib minor version : "); desc.push_back("TypeLib LCID : "); + desc.push_back("COM object name : "); + desc.push_back("COM object description : "); + desc.push_back("COM object CLSID : "); + desc.push_back("COM object interface CLSID : "); + desc.push_back("COM object events CLSID : "); + desc.push_back("COM object type : "); desc.push_back("Is P-Code : "); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectName())); @@ -71,6 +77,13 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMajorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMinorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); + + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectDescription())); + info.push_back(fileinfo.getVisualBasicCOMObjectCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectInterfaceCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectEventsCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectType()); info.push_back((fileinfo.getVisualBasicIsPcode()) ? "Yes" : "No"); return info.size(); From 97c9246d1f60d79dcd116aa5e8b010a40dc8076a Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 9 Feb 2019 21:04:03 +0100 Subject: [PATCH 22/33] COM Registration Info json presentation --- .../simple_getter/visual_basic_json_getter.cpp | 12 ++++++++++++ .../simple_getter/visual_basic_plain_getter.cpp | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp index be9705af1..959883ad1 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_json_getter.cpp @@ -54,6 +54,12 @@ std::size_t VisualBasicJsonGetter::loadInformation(std::vector &des desc.push_back("typeLibMajorVersion"); desc.push_back("typeLibMinorVersion"); desc.push_back("typeLibLCID"); + desc.push_back("comObjectName"); + desc.push_back("comObjectDescription"); + desc.push_back("comObjectCLSID"); + desc.push_back("comObjectInterfaceCLSID"); + desc.push_back("comObjectEventsCLSID"); + desc.push_back("comObjectType"); desc.push_back("isPCode"); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicProjectName())); @@ -71,6 +77,12 @@ std::size_t VisualBasicJsonGetter::loadInformation(std::vector &des info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMajorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMinorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectName())); + info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectDescription())); + info.push_back(fileinfo.getVisualBasicCOMObjectCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectInterfaceCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectEventsCLSID()); + info.push_back(fileinfo.getVisualBasicCOMObjectType()); info.push_back((fileinfo.getVisualBasicIsPcode()) ? "yes" : "no"); return info.size(); diff --git a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp index 35829bc26..de59e3101 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/visual_basic_plain_getter.cpp @@ -77,7 +77,6 @@ std::size_t VisualBasicPlainGetter::loadInformation(std::vector &de info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMajorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibMinorVersionStr())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicTypeLibLCIDStr())); - info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectName())); info.push_back(replaceNonprintableChars(fileinfo.getVisualBasicCOMObjectDescription())); info.push_back(fileinfo.getVisualBasicCOMObjectCLSID()); From 9c2ca132cb5be605f09be4422bbea1adf9355c3a Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Mon, 11 Feb 2019 10:48:55 +0100 Subject: [PATCH 23/33] modification for crawler only --- src/fileformat/file_format/pe/pe_format.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 4890fde3a..bf052b90c 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -754,6 +754,7 @@ void PeFormat::loadVisualBasicHeader() visualBasicInfo.setLanguageDLLPrimaryLCID(vbh.LCID1); visualBasicInfo.setLanguageDLLSecondaryLCID(vbh.LCID2); + if (getOffsetFromAddress(vbProjectInfoOffset, vbh.projectInfoAddr)) { parseVisualBasicProjectInfo(vbProjectInfoOffset); @@ -809,7 +810,8 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) visualBasicInfo.setTypeLibLCID(vbcrd.projTlbLCID); visualBasicInfo.setTypeLibMajorVersion(vbcrd.tlbVerMajor); - visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); + // TODO uncomment + // visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); if (!visualBasicInfo.hasProjectName() && vbcrd.projNameOffset != 0) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), @@ -921,6 +923,9 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, visualBasicInfo.setCOMObjectEventsCLSID(bytes.data()); } + // TODO MUST DELME + visualBasicInfo.setTypeLibMinorVersion(vbcri.isDesignerFlag); + return true; } From 36ebaa14d6af0f3801bbcf27b12269a71af1aa36 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Mon, 11 Feb 2019 16:00:00 +0100 Subject: [PATCH 24/33] ascii parsing fixed and VB presentation fixed --- .../visual_basic/visual_basic_structures.h | 17 +++-- include/retdec/utils/string.h | 4 +- src/fileformat/file_format/pe/pe_format.cpp | 70 ++++++++++++------- .../file_presentation/json_presentation.cpp | 5 +- .../file_presentation/plain_presentation.cpp | 6 +- src/utils/string.cpp | 33 ++++++++- 6 files changed, 94 insertions(+), 41 deletions(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h index 9b1471ba7..de2d72790 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -12,6 +12,9 @@ namespace retdec { namespace fileformat { +constexpr std::size_t VBHEADER_SIGNATURE = 0x21354256; +constexpr std::size_t VB_MAX_STRING_LEN = 100; + enum class VBExternTableEntryType { internal = 0x6, @@ -20,7 +23,7 @@ enum class VBExternTableEntryType struct VBHeader { - std::uint8_t signature[4]; ///< "VB5!" signature + std::uint32_t signature; ///< "VB5!" signature std::uint16_t runtimeBuild; ///< runtime flag std::uint8_t languageDLL[14]; ///< language DLL std::uint8_t backupLanguageDLL[14]; ///< backup language DLL @@ -64,12 +67,12 @@ struct VBHeader void dump(std::ostream &out) { - out << "signature:\t\t"; - for (std::size_t i = 0; i < sizeof(signature); i++) - { - out << signature[i]; - } - out << "\n"; + // out << "signature:\t\t"; + // for (std::size_t i = 0; i < sizeof(signature); i++) + // { + // out << signature[i]; + // } + // out << "\n"; out << "runtimeBuild:\t\t" << runtimeBuild << "\n"; diff --git a/include/retdec/utils/string.h b/include/retdec/utils/string.h index 2b9c35dfb..1432708e9 100644 --- a/include/retdec/utils/string.h +++ b/include/retdec/utils/string.h @@ -52,8 +52,8 @@ std::string toUpper(std::string str); std::string toWide(const std::string &str, std::string::size_type length); std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes); -std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t maxBytes, - std::size_t offset = 0); +std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t bytesLen, + std::size_t offset = 0, std::size_t maxBytes = 0, bool failOnExceed = false); std::string trim(std::string str, const std::string &toTrim = " \t\r\n\v"); diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index bf052b90c..929fe969c 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -668,7 +668,7 @@ void PeFormat::loadVisualBasicHeader() return; } - std::memcpy(&vbh.signature, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.signature)); offset += sizeof(vbh.signature); + vbh.signature = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.signature); vbh.runtimeBuild = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeBuild); std::memcpy(&vbh.languageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); std::memcpy(&vbh.backupLanguageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); @@ -694,6 +694,7 @@ void PeFormat::loadVisualBasicHeader() if (!isLittleEndian()) { + vbh.signature = byteSwap32(vbh.signature); vbh.runtimeBuild = byteSwap16(vbh.runtimeBuild); vbh.runtimeDLLVersion = byteSwap16(vbh.runtimeDLLVersion); vbh.LCID1 = byteSwap32(vbh.LCID1); @@ -716,28 +717,33 @@ void PeFormat::loadVisualBasicHeader() vbh.projNameOffset = byteSwap32(vbh.projNameOffset); } + if (vbh.signature != VBHEADER_SIGNATURE) + { + return; + } + if (vbh.projExeNameOffset != 0) { projExeName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - vbHeaderOffset + vbh.projExeNameOffset); + vbHeaderOffset + vbh.projExeNameOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setProjectExeName(projExeName); } if (vbh.projDescOffset != 0) { projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - vbHeaderOffset + vbh.projDescOffset); + vbHeaderOffset + vbh.projDescOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setProjectDescription(projDesc); } if (vbh.helpFileOffset != 0) { helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - vbHeaderOffset + vbh.helpFileOffset); + vbHeaderOffset + vbh.helpFileOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setProjectHelpFile(helpFile); } if (vbh.projNameOffset != 0) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - vbHeaderOffset + vbh.projNameOffset); + vbHeaderOffset + vbh.projNameOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setProjectName(projName); } @@ -810,22 +816,22 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) visualBasicInfo.setTypeLibLCID(vbcrd.projTlbLCID); visualBasicInfo.setTypeLibMajorVersion(vbcrd.tlbVerMajor); - // TODO uncomment - // visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); + visualBasicInfo.setTypeLibMinorVersion(vbcrd.tlbVerMinor); + if (!visualBasicInfo.hasProjectName() && vbcrd.projNameOffset != 0) { projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.projNameOffset); + structureOffset + vbcrd.projNameOffset, VB_MAX_STRING_LEN, true); } if (!visualBasicInfo.hasProjectHelpFile() && vbcrd.helpFileOffset != 0) { helpFile = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.helpFileOffset); + structureOffset + vbcrd.helpFileOffset, VB_MAX_STRING_LEN, true); } if (!visualBasicInfo.hasProjectDescription() && vbcrd.projDescOffset != 0) { projDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - structureOffset + vbcrd.projDescOffset); + structureOffset + vbcrd.projDescOffset, VB_MAX_STRING_LEN, true); } visualBasicInfo.setTypeLibCLSID(vbcrd.projCLSID); @@ -898,13 +904,13 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, if (vbcri.objNameOffset != 0) { COMObjectName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - comRegDataOffset + vbcri.objNameOffset); + comRegDataOffset + vbcri.objNameOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setCOMObjectName(COMObjectName); } if (vbcri.objDescOffset != 0) { COMObjectDesc = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), - comRegDataOffset + vbcri.objDescOffset); + comRegDataOffset + vbcri.objDescOffset, VB_MAX_STRING_LEN, true); visualBasicInfo.setCOMObjectDescription(COMObjectDesc); } @@ -923,9 +929,6 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, visualBasicInfo.setCOMObjectEventsCLSID(bytes.data()); } - // TODO MUST DELME - visualBasicInfo.setTypeLibMinorVersion(vbcri.isDesignerFlag); - return true; } @@ -1058,19 +1061,24 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz unsigned long long moduleNameOffset; if (getOffsetFromAddress(moduleNameOffset, entryData.moduleNameAddr)) { - moduleName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), moduleNameOffset); + moduleName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + moduleNameOffset, VB_MAX_STRING_LEN, true); } unsigned long long apiNameOffset; if (getOffsetFromAddress(apiNameOffset, entryData.apiNameAddr)) { - apiName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), apiNameOffset); + apiName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), + apiNameOffset, VB_MAX_STRING_LEN, true); } - auto ext = std::make_unique(); - ext->setModuleName(moduleName); - ext->setApiName(apiName); - visualBasicInfo.addExtern(std::move(ext)); + if (!moduleName.empty() || !apiName.empty()) + { + auto ext = std::make_unique(); + ext->setModuleName(moduleName); + ext->setApiName(apiName); + visualBasicInfo.addExtern(std::move(ext)); + } } visualBasicInfo.computeExternTableHashes(); @@ -1148,7 +1156,8 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) if (!visualBasicInfo.hasProjectName() && getOffsetFromAddress(projectNameOffset, vbot.projectNameAddr)) { - projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset); + projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset, + VB_MAX_STRING_LEN, true); visualBasicInfo.setProjectName(projName); } @@ -1219,7 +1228,8 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t continue; } - std::string objectName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), objectNameOffset); + std::string objectName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), objectNameOffset, + VB_MAX_STRING_LEN, true); object = std::make_unique(); object->setName(objectName); @@ -1247,12 +1257,20 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t continue; } - std::string methodName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), methodNameOffset); - object->addMethod(methodName); + std::string methodName = readNullTerminatedAscii(allBytes.data(), allBytes.size(), + methodNameOffset, VB_MAX_STRING_LEN, true); + + if (!methodName.empty()) + { + object->addMethod(methodName); + } } } - visualBasicInfo.addObject(std::move(object)); + if (!objectName.empty() || object->getNumberOfMethods() > 0) + { + visualBasicInfo.addObject(std::move(object)); + } } return true; diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index b9fe05419..2b7698fd2 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -540,7 +540,10 @@ void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const } } - jVBasic["objectTable"] = jObjectTable; + if (!jObjectTable["guid"].empty() || nObjects > 0) + { + jVBasic["objectTable"] = jObjectTable; + } root["visualBasicInfo"] = jVBasic; } diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index 26d3a51e5..a246d1371 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -630,7 +630,8 @@ void PlainPresentation::presentDotnetClasses() const void PlainPresentation::presentVisualBasicObjects() const { auto nObjs = fileinfo.getVisualBasicNumberOfObjects(); - if (!fileinfo.isVisualBasicUsed() || nObjs == 0) + auto guid = fileinfo.getVisualBasicObjectTableGUID(); + if (!fileinfo.isVisualBasicUsed() || (nObjs == 0 && guid.empty())) { return; } @@ -641,8 +642,9 @@ void PlainPresentation::presentVisualBasicObjects() const std::cout << "CRC32 : " << fileinfo.getVisualBasicObjectTableHashCrc32() << "\n"; std::cout << "MD5 : " << fileinfo.getVisualBasicObjectTableHashMd5() << "\n"; std::cout << "SHA256 : " << fileinfo.getVisualBasicObjectTableHashSha256() << "\n"; - std::cout << "GUID : " << fileinfo.getVisualBasicObjectTableGUID() << "\n"; + std::cout << "GUID : " << guid << "\n"; std::cout << "\n"; + std::size_t cnt = 0; for (std::size_t i = 0; i < nObjs; i++) { diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 822b0c514..03a010f83 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -451,23 +451,50 @@ std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) * @brief Read up to @a maxBytes bytes as ASCII string. * * @param[in] bytes Bytes to read from. -* @param[in] maxBytes Maximum bytes to read. +* @param[in] bytesLen Length of @a bytes * @param[in] offset Offset in bytes. +* @param[in] maxBytes Maximum of bytes to read. Zero indicates as much as possible. +* @param[in] failOnExceed If string isn't null terminated until @a maxBytes, an empty string is returned * * @return Converted string in ASCII. */ -std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t maxBytes, std::size_t offset) +std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t bytesLen, std::size_t offset, + std::size_t maxBytes, bool failOnExceed) { std::string result; if (!bytes) { return ""; } - for (std::size_t i = offset; i < maxBytes && bytes[i]; i++) + + if (maxBytes == 0) + { + maxBytes = bytesLen; + } + else if (offset + maxBytes > bytesLen) + { + maxBytes = bytesLen; + } + else + { + maxBytes += offset; + } + + std::size_t i; + for (i = offset; i < maxBytes; i++) { + if (bytes[i] == '\0') + { + break; + } result.push_back(bytes[i]); } + if (i == maxBytes && failOnExceed) + { + return ""; + } + return replaceNonprintableChars(result); } From 87ad687340fe45ab1fbcab0a706f525e1641a20c Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Mon, 11 Feb 2019 16:04:39 +0100 Subject: [PATCH 25/33] relicts removed --- .../types/resource_table/bitmap_image.h | 5 - .../visual_basic/visual_basic_structures.h | 160 ------------------ 2 files changed, 165 deletions(-) diff --git a/include/retdec/fileformat/types/resource_table/bitmap_image.h b/include/retdec/fileformat/types/resource_table/bitmap_image.h index 315b96e15..8dfe67d3c 100644 --- a/include/retdec/fileformat/types/resource_table/bitmap_image.h +++ b/include/retdec/fileformat/types/resource_table/bitmap_image.h @@ -77,11 +77,6 @@ class BitmapImage const std::vector> &getImage() const; /// @} - /// @name Setters - /// @{ - // TODO - /// @} - /// @name Other methods /// @{ bool parseDibFormat(const ResourceIcon &icon); diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h index de2d72790..b3ab76729 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -64,61 +64,6 @@ struct VBHeader sizeof(COMRegisterDataAddr) + sizeof(projExeNameOffset) + sizeof(projDescOffset) + sizeof(helpFileOffset) + sizeof(projNameOffset); } - - void dump(std::ostream &out) - { - // out << "signature:\t\t"; - // for (std::size_t i = 0; i < sizeof(signature); i++) - // { - // out << signature[i]; - // } - // out << "\n"; - - out << "runtimeBuild:\t\t" << runtimeBuild << "\n"; - - out << "languageDLL:\t\t"; - for (std::size_t i = 0; i < sizeof(languageDLL); i++) - { - if (!languageDLL[i]) - { - break; - } - out << languageDLL[i]; - } - out << "\n"; - - out << "backupLanguageDLL:\t"; - for (std::size_t i = 0; i < sizeof(backupLanguageDLL); i++) - { - if (!backupLanguageDLL[i]) - { - break; - } - out << backupLanguageDLL[i]; - } - out << "\n"; - - out << "runtimeDLLVersion:\t" << runtimeDLLVersion << "\n"; - out << "LCID1:\t\t" << LCID1 << "\n"; - out << "LCID2:\t" << LCID2 << "\n"; - out << "subMainAddr:\t\t" << std::hex << subMainAddr << "\n"; - out << "projectInfoAddr:\t\t" << projectInfoAddr << std::dec << "\n"; - out << "MDLIntObjsFlags:\t\t" << MDLIntObjsFlags << "\n"; - out << "MDLIntObjsFlags2:\t\t" << MDLIntObjsFlags2 << "\n"; - out << "threadFlags:\t\t" << threadFlags << "\n"; - out << "nThreads:\t\t" << nThreads << "\n"; - out << "nForms:\t\t" << nForms << "\n"; - out << "nExternals:\t" << nExternals << "\n"; - out << "nThunks:\t\t" << nThunks << "\n"; - out << "GUITableAddr:\t\t" << std::hex << GUITableAddr << "\n"; - out << "externalTableAddr:" << externalTableAddr << "\n"; - out << "COMRegisterDataAddr:\t" << COMRegisterDataAddr << "\n"; - out << "projExeNameOffset:\t" << projExeNameOffset << "\n"; - out << "projDescOffset:\t\t" << projDescOffset << "\n"; - out << "helpFileOffset:\t\t" << helpFileOffset << "\n"; - out << "projNameOffset:\t\t" << projNameOffset << std::dec << "\n"; - out << "\n"; - } }; struct VBProjInfo @@ -149,22 +94,6 @@ struct VBProjInfo + sizeof(threadSpaceAddr) + sizeof(exHandlerAddr) + sizeof(nativeCodeAddr) + sizeof(pathInformation) + sizeof(externalTableAddr) + sizeof(nExternals); } - - void dump(std::ostream &out) - { - out << "version:\t\t" << version << "\n"; - out << "objectTableAddr:\t\t" << objectTableAddr << "\n"; - out << "null:\t\t\t" << null << "\n"; - out << "codeStartAddr:\t\t" << codeStartAddr << "\n"; - out << "codeEndAddr:\t\t" << codeEndAddr << "\n"; - out << "dataSize:\t\t" << dataSize << "\n"; - out << "threadSpaceAddr:\t\t" << threadSpaceAddr << "\n"; - out << "exHandlerAddr:\t\t" << exHandlerAddr << "\n"; - out << "nativeCodeAddr:\t\t" << nativeCodeAddr << "\n"; - out << "externalTableAddr:\t" << externalTableAddr << "\n"; - out << "nExternals:\t" << nExternals << "\n"; - out << "\n"; - } }; struct VBObjectTable @@ -205,30 +134,6 @@ struct VBObjectTable sizeof(projectNameAddr) + sizeof(LCID1) + sizeof(LCID2) + sizeof(IDE4) + sizeof(templateVesion); } - - void dump(std::ostream &out) - { - out << "null1:\t\t\t" << null1 << "\n"; - out << "execCOMAddr:\t\t" << execCOMAddr << "\n"; - out << "projecInfo2Addr:\t" << projecInfo2Addr << "\n"; - out << "reserved:\t\t" << reserved << "\n"; - out << "null2:\t\t\t" << null2 << "\n"; - out << "projectObjectAddr:\t" << projectObjectAddr << "\n"; - // out << "objectGUID:\t\t" << objectGUID << "\n"; // TODO - out << "flagsCompileState:\t\t" << flagsCompileState << "\n"; - out << "nObjects:\t\t" << nObjects << "\n"; - out << "nCompiledObjects:\t" << nCompiledObjects << "\n"; - out << "nUsedObjects:\t\t" << nUsedObjects << "\n"; - out << "objectDescriptorsAddr:\t" << objectDescriptorsAddr << "\n"; - out << "IDE1:\t\t\t" << IDE1 << "\n"; - out << "IDE2:\t\t\t" << IDE2 << "\n"; - out << "IDE3:\t\t\t" << IDE3 << "\n"; - out << "projectNameAddr:\t" << projectNameAddr << "\n"; - out << "LCID1:\t\t\t" << LCID1 << "\n"; - out << "LCID2:\t\t\t" << LCID2 << "\n"; - out << "IDE4:\t\t\t" << IDE4 << "\n"; - out << "templateVesion:\t\t" << templateVesion << "\n"; - } }; struct VBPublicObjectDescriptor @@ -259,22 +164,6 @@ struct VBPublicObjectDescriptor sizeof(objectNameAddr) + sizeof(nMethods) + sizeof(methodNamesAddr) + sizeof(staticVarsCopyAddr) + sizeof(objectType) + sizeof(null); } - - void dump(std::ostream &out) - { - out << "objectInfoAddr:\t\t" << objectInfoAddr << "\n"; - out << "reserved:\t\t" << reserved << "\n"; - out << "publicBytesAddr:\t" << publicBytesAddr << "\n"; - out << "staticBytesAddr:\t" << staticBytesAddr << "\n"; - out << "modulePublicAddr:\t" << modulePublicAddr << "\n"; - out << "moduleStaticAddr:\t" << moduleStaticAddr << "\n"; - out << "objectNameAddr:\t\t" << objectNameAddr << "\n"; - out << "nMethods:\t\t" << nMethods << "\n"; - out << "methodNamesAddr:\t" << methodNamesAddr << "\n"; - out << "staticVarsCopyAddr:\t" << staticVarsCopyAddr << "\n"; - out << "objectType:\t\t" << objectType << "\n"; - out << "null:\t\t\t" << null << "\n"; - } }; struct VBExternTableEntry @@ -291,13 +180,6 @@ struct VBExternTableEntry { return sizeof(type) + sizeof(importDataAddr); } - - void dump(std::ostream &out) - { - out << "type:\t\t" << type << "\n"; - out << "importDataAddr:\t\t" << importDataAddr << "\n"; - out << "\n"; - } }; struct VBExternTableEntryData @@ -314,13 +196,6 @@ struct VBExternTableEntryData { return sizeof(moduleNameAddr) + sizeof(apiNameAddr); } - - void dump(std::ostream &out) - { - out << "moduleNameAddr:\t" << moduleNameAddr << "\n"; - out << "apiNameAddr:\t" << apiNameAddr << "\n"; - out << "\n"; - } }; struct VBCOMRData @@ -347,20 +222,6 @@ struct VBCOMRData sizeof(projDescOffset) + sizeof(projCLSID) + sizeof(projTlbLCID) + sizeof(unknown) + sizeof(tlbVerMajor) + sizeof(tlbVerMinor); } - - void dump(std::ostream &out) - { - out << std::hex; - out << "regInfoOffset\t:" << regInfoOffset << "\n"; - out << "projNameOffset\t:" << projNameOffset << "\n"; - out << "helpFileOffset\t:" << helpFileOffset << "\n"; - out << "projDescOffset\t:" << projDescOffset << "\n"; - out << "projTlbLCID\t:" << projTlbLCID << "\n"; - out << "unknown\t\t:" << unknown << "\n"; - out << "tlbVerMajor\t:" << tlbVerMajor << "\n"; - out << "tlbVerMinor\t:" << tlbVerMinor << "\n"; - out << std::dec; - } }; struct VBCOMRInfo @@ -398,27 +259,6 @@ struct VBCOMRInfo sizeof(toolboxBitmap32) + sizeof(defaultIcon) + sizeof(isDesignerFlag) + sizeof(designerDataOffset); } - - void dump(std::ostream &out) - { - out << std::hex; - out << "ifInfoOffset:\t\t" << ifInfoOffset << "\n"; - out << "objNameOffset:\t\t" << objNameOffset << "\n"; - out << "objDescOffset:\t\t" << objDescOffset << "\n"; - out << "instancing:\t\t" << instancing << "\n"; - out << "objID:\t\t" << objID << "\n"; - out << "isInterfaceFlag:\t\t" << isInterfaceFlag << "\n"; - out << "ifCLSIDOffset:\t\t" << ifCLSIDOffset << "\n"; - out << "eventCLSIDOffset:\t\t" << eventCLSIDOffset << "\n"; - out << "hasEvents:\t\t" << hasEvents << "\n"; - out << "olemicsFlags:\t\t" << olemicsFlags << "\n"; - out << "classType:\t\t" << static_cast(classType) << "\n"; - out << "objectType:\t\t" << static_cast(objectType) << "\n"; - out << "toolboxBitmap32:\t\t" << toolboxBitmap32 << "\n"; - out << "defaultIcon:\t\t" << defaultIcon << "\n"; - out << "isDesignerFlag:\t\t" << isDesignerFlag << "\n"; - out << "designerDataOffset:\t\t" << designerDataOffset << "\n"; - } }; } // namespace fileformat From c788ed1f604a87b637e39e2508de774e85fa9085 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Tue, 12 Feb 2019 10:27:29 +0100 Subject: [PATCH 26/33] empty object table presentation fixed --- src/fileinfo/file_presentation/json_presentation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index 2b7698fd2..95c204165 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -515,7 +515,12 @@ void JsonPresentation::presentVisualBasicInfo(Json::Value &root) const } Value jObjectTable; - jObjectTable["guid"] = fileinfo.getVisualBasicObjectTableGUID(); + auto guid = fileinfo.getVisualBasicObjectTableGUID(); + + if (!guid.empty()) + { + jObjectTable["guid"] = guid; + } auto nObjects = fileinfo.getVisualBasicNumberOfObjects(); if (nObjects) From ae6882afdccf048b3cc6615558dad282a9ae506a Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 16 Feb 2019 10:19:07 +0100 Subject: [PATCH 27/33] support of LCID to string added --- include/retdec/fileformat/utils/other.h | 1 + src/fileformat/utils/other.cpp | 207 ++++++++++++++++++ .../visual_basic_info.cpp | 12 +- 3 files changed, 215 insertions(+), 5 deletions(-) diff --git a/include/retdec/fileformat/utils/other.h b/include/retdec/fileformat/utils/other.h index e803db130..f10c298cf 100644 --- a/include/retdec/fileformat/utils/other.h +++ b/include/retdec/fileformat/utils/other.h @@ -19,6 +19,7 @@ std::size_t getRealSizeInRegion(std::size_t offset, std::size_t requestedSize, s std::string getFileFormatNameFromEnum(Format format); std::vector getSupportedFileFormats(); std::vector getSupportedArchitectures(); +std::string lcidToStr(std::size_t lcid); } // namespace fileformat } // namespace retdec diff --git a/src/fileformat/utils/other.cpp b/src/fileformat/utils/other.cpp index 21fb82dfd..3d831f52f 100644 --- a/src/fileformat/utils/other.cpp +++ b/src/fileformat/utils/other.cpp @@ -5,8 +5,10 @@ */ #include +#include #include "retdec/utils/container.h" +#include "retdec/utils/conversion.h" #include "retdec/fileformat/utils/other.h" using namespace retdec::utils; @@ -36,6 +38,196 @@ const std::map> architectureMap = {Architecture::MIPS, {"MIPS", "PIC32"}} }; +const std::unordered_map lcids = +{ + {1078, "Afrikaans"}, + {1052, "Albanian"}, + {1118, "Amharic"}, + {5121, "Arabic - Algeria"}, + {15361, "Arabic - Bahrain"}, + {3073, "Arabic - Egypt"}, + {2049, "Arabic - Iraq"}, + {11265, "Arabic - Jordan"}, + {13313, "Arabic - Kuwait"}, + {12289, "Arabic - Lebanon"}, + {4097, "Arabic - Libya"}, + {6145, "Arabic - Morocco"}, + {8193, "Arabic - Oman"}, + {16385, "Arabic - Qatar"}, + {1025, "Arabic - Saudi Arabia"}, + {10241, "Arabic - Syria"}, + {7169, "Arabic - Tunisia"}, + {14337, "Arabic - United Arab Emirates"}, + {9217, "Arabic - Yemen"}, + {1067, "Armenian"}, + {1101, "Assamese"}, + {2092, "Azeri - Cyrillic"}, + {1068, "Azeri - Latin"}, + {1069, "Basque"}, + {1059, "Belarusian"}, + {2117, "Bengali - Bangladesh"}, + {1093, "Bengali - India"}, + {5146, "Bosnian"}, + {1026, "Bulgarian"}, + {1109, "Burmese"}, + {1027, "Catalan"}, + {2052, "Chinese - China"}, + {3076, "Chinese - Hong Kong SAR"}, + {5124, "Chinese - Macau SAR"}, + {4100, "Chinese - Singapore"}, + {1028, "Chinese - Taiwan"}, + {1050, "Croatian"}, + {1029, "Czech"}, + {1030, "Danish"}, + {2067, "Dutch - Belgium"}, + {1043, "Dutch - Netherlands"}, + {1126, "Edo"}, + {3081, "English - Australia"}, + {10249, "English - Belize"}, + {4105, "English - Canada"}, + {9225, "English - Caribbean"}, + {2057, "English - Great Britain"}, + {16393, "English - India"}, + {6153, "English - Ireland"}, + {8201, "English - Jamaica"}, + {5129, "English - New Zealand"}, + {13321, "English - Phillippines"}, + {7177, "English - Southern Africa"}, + {11273, "English - Trinidad"}, + {1033, "English - United States"}, + {12297, "English - Zimbabwe"}, + {1061, "Estonian"}, + {1071, "FYRO Macedonia"}, + {1080, "Faroese"}, + {1065, "Farsi - Persian"}, + {1124, "Filipino"}, + {1035, "Finnish"}, + {2060, "French - Belgium"}, + {11276, "French - Cameroon"}, + {3084, "French - Canada"}, + {9228, "French - Congo"}, + {12300, "French - Cote d'Ivoire"}, + {1036, "French - France"}, + {5132, "French - Luxembourg"}, + {13324, "French - Mali"}, + {6156, "French - Monaco"}, + {14348, "French - Morocco"}, + {10252, "French - Senegal"}, + {4108, "French - Switzerland"}, + {7180, "French - West Indies"}, + {1122, "Frisian - Netherlands"}, + {2108, "Gaelic - Ireland"}, + {1084, "Gaelic - Scotland"}, + {1110, "Galician"}, + {1079, "Georgian"}, + {3079, "German - Austria"}, + {1031, "German - Germany"}, + {5127, "German - Liechtenstein"}, + {4103, "German - Luxembourg"}, + {2055, "German - Switzerland"}, + {1032, "Greek"}, + {1140, "Guarani - Paraguay"}, + {1095, "Gujarati"}, + {1279, "Human Interface Device"}, + {1037, "Hebrew"}, + {1081, "Hindi"}, + {1038, "Hungarian"}, + {1039, "Icelandic"}, + {1136, "Igbo - Nigeria"}, + {1057, "Indonesian"}, + {1040, "Italian - Italy"}, + {2064, "Italian - Switzerland"}, + {1041, "Japanese"}, + {1099, "Kannada"}, + {1120, "Kashmiri"}, + {1087, "Kazakh"}, + {1107, "Khmer"}, + {1111, "Konkani"}, + {1042, "Korean"}, + {1088, "Kyrgyz - Cyrillic"}, + {1108, "Lao"}, + {1142, "Latin"}, + {1062, "Latvian"}, + {1063, "Lithuanian"}, + {2110, "Malay - Brunei"}, + {1086, "Malay - Malaysia"}, + {1100, "Malayalam"}, + {1082, "Maltese"}, + {1112, "Manipuri"}, + {1153, "Maori"}, + {1102, "Marathi"}, + {2128, "Mongolian"}, + {1104, "Mongolian"}, + {1121, "Nepali"}, + {1044, "Norwegian - Bokml"}, + {2068, "Norwegian - Nynorsk"}, + {1096, "Oriya"}, + {1045, "Polish"}, + {1046, "Portuguese - Brazil"}, + {2070, "Portuguese - Portugal"}, + {1094, "Punjabi"}, + {1047, "Raeto-Romance"}, + {2072, "Romanian - Moldova"}, + {1048, "Romanian - Romania"}, + {1049, "Russian"}, + {2073, "Russian - Moldova"}, + {1083, "Sami Lappish"}, + {1103, "Sanskrit"}, + {3098, "Serbian - Cyrillic"}, + {2074, "Serbian - Latin"}, + {1072, "Sesotho"}, + {1074, "Setsuana"}, + {1113, "Sindhi"}, + {1115, "Sinhala"}, + {1051, "Slovak"}, + {1060, "Slovenian"}, + {1143, "Somali"}, + {1070, "Sorbian"}, + {11274, "Spanish - Argentina"}, + {16394, "Spanish - Bolivia"}, + {13322, "Spanish - Chile"}, + {9226, "Spanish - Colombia"}, + {5130, "Spanish - Costa Rica"}, + {7178, "Spanish - Dominican Republic"}, + {12298, "Spanish - Ecuador"}, + {17418, "Spanish - El Salvador"}, + {4106, "Spanish - Guatemala"}, + {18442, "Spanish - Honduras"}, + {2058, "Spanish - Mexico"}, + {19466, "Spanish - Nicaragua"}, + {6154, "Spanish - Panama"}, + {15370, "Spanish - Paraguay"}, + {10250, "Spanish - Peru"}, + {20490, "Spanish - Puerto Rico"}, + {1034, "Spanish - Spain (Traditional)"}, + {14346, "Spanish - Uruguay"}, + {8202, "Spanish - Venezuela"}, + {1089, "Swahili"}, + {2077, "Swedish - Finland"}, + {1053, "Swedish - Sweden"}, + {1114, "Syriac"}, + {1064, "Tajik"}, + {1097, "Tamil"}, + {1092, "Tatar"}, + {1098, "Telugu"}, + {1054, "Thai"}, + {1105, "Tibetan"}, + {1073, "Tsonga"}, + {1055, "Turkish"}, + {1090, "Turkmen"}, + {1058, "Ukrainian"}, + {0, "Unicode"}, + {1056, "Urdu"}, + {2115, "Uzbek - Cyrillic"}, + {1091, "Uzbek - Latin"}, + {1075, "Venda"}, + {1066, "Vietnamese"}, + {1106, "Welsh"}, + {1076, "Xhosa"}, + {1085, "Yiddish"}, + {1077, "Zulu"} +}; + } // anonymous namespace /** @@ -99,5 +291,20 @@ std::vector getSupportedArchitectures() return result; } +/** + * Get string representation of language code id + * @param lcid Language code id + * @return String representation of @a lcid + */ +std::string lcidToStr(std::size_t lcid) +{ + auto l = lcids.find(lcid); + if (l == lcids.end()) + { + return numToStr(lcid, std::dec); + } + return l->second; +} + } // namespace fileformat } // namespace retdec diff --git a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp index 49ef67bb8..4034e8c18 100644 --- a/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp +++ b/src/fileinfo/file_information/file_information_types/visual_basic_info.cpp @@ -4,9 +4,11 @@ * @copyright (c) 2017 Avast Software, licensed under the MIT license */ +#include "retdec/fileformat/utils/other.h" #include "fileinfo/file_information/file_information_types/visual_basic_info.h" #include "fileinfo/file_information/file_information_types/type_conversions.h" +using namespace retdec::utils; using namespace retdec::fileformat; namespace fileinfo { @@ -92,7 +94,7 @@ std::string VisualBasicInfo::getLanguageDLLPrimaryLCIDStr() const { return ""; } - return getNumberAsString(lcid); + return lcidToStr(lcid); } /** @@ -106,7 +108,7 @@ std::string VisualBasicInfo::getLanguageDLLSecondaryLCIDStr() const { return ""; } - return getNumberAsString(lcid); + return lcidToStr(lcid); } /** @@ -129,7 +131,7 @@ std::string VisualBasicInfo::getProjectPrimaryLCIDStr() const { return ""; } - return getNumberAsString(lcid); + return lcidToStr(lcid); } /** @@ -143,7 +145,7 @@ std::string VisualBasicInfo::getProjectSecondaryLCIDStr() const { return ""; } - return getNumberAsString(lcid); + return lcidToStr(lcid); } /** @@ -263,7 +265,7 @@ std::string VisualBasicInfo::getTypeLibLCIDStr() const { return ""; } - return getNumberAsString(lcid); + return lcidToStr(lcid); } /** From 4e1ae53c29349774ece9c2a06eed03fbec8c58d3 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Thu, 21 Feb 2019 13:07:53 +0100 Subject: [PATCH 28/33] reference instead of copying --- src/fileformat/file_format/pe/pe_format.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 929fe969c..96f4e45bb 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -630,7 +630,7 @@ void PeFormat::loadRichHeader() */ void PeFormat::loadVisualBasicHeader() { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; unsigned long long version = 0; unsigned long long vbHeaderAddress = 0; @@ -779,7 +779,7 @@ void PeFormat::loadVisualBasicHeader() */ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; std::size_t offset = 0; struct VBCOMRData vbcrd; @@ -853,7 +853,7 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, std::size_t comRegDataOffset) { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; std::size_t offset = 0; struct VBCOMRInfo vbcri; @@ -1004,7 +1004,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset) */ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::size_t nEntries) { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; struct VBExternTableEntry entry; struct VBExternTableEntryData entryData; @@ -1093,7 +1093,7 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz */ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; std::size_t offset = 0; unsigned long long projectNameOffset = 0; @@ -1178,7 +1178,7 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) */ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t nObjects) { - auto allBytes = getBytes(); + const auto &allBytes = getBytes(); std::vector bytes; struct VBPublicObjectDescriptor vbpod; std::size_t offset = 0; From c41801fc411a1084c34aedfa242e921de594a22b Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 22 Feb 2019 14:52:27 +0100 Subject: [PATCH 29/33] DynamicBuffer moved --- .../visual_basic/visual_basic_structures.h | 16 +++--- .../unpacker/decompression/compressed_data.h | 4 +- .../unpacker/decompression/nrv/bit_parsers.h | 4 +- include/retdec/unpacker/signature.h | 4 +- include/retdec/unpacker/unpacking_stub.h | 2 +- include/retdec/utils/conversion.h | 1 - .../{unpacker => utils}/dynamic_buffer.h | 10 ++-- src/fileformat/file_format/pe/pe_format.cpp | 4 +- .../file_information/file_information.cpp | 4 -- src/unpacker/CMakeLists.txt | 1 - src/unpackertool/plugins/mpress/mpress.cpp | 5 +- src/unpackertool/plugins/mpress/mpress.h | 22 ++++---- .../plugins/upx/decompressors/decompressor.h | 28 +++++------ .../decompressors/decompressor_direct_jump.h | 6 ++- .../upx/decompressors/decompressor_lzma.h | 22 ++++---- .../upx/decompressors/decompressor_nrv.cpp | 3 +- .../upx/decompressors/decompressor_nrv.h | 24 +++++---- .../decompressors/decompressor_scrambler.h | 18 ++++--- .../upx/decompressors/decompressor_upxshit.h | 6 ++- .../plugins/upx/elf/elf_upx_stub.cpp | 7 +-- .../plugins/upx/elf/elf_upx_stub.h | 16 +++--- .../plugins/upx/macho/macho_upx_stub.cpp | 5 +- .../plugins/upx/macho/macho_upx_stub.h | 14 +++--- .../plugins/upx/pe/pe_upx_stub.cpp | 12 ++--- src/unpackertool/plugins/upx/pe/pe_upx_stub.h | 50 ++++++++++--------- src/unpackertool/plugins/upx/unfilter.cpp | 2 +- src/unpackertool/plugins/upx/unfilter.h | 22 ++++---- src/unpackertool/plugins/upx/upx_stub.cpp | 13 ++--- src/unpackertool/plugins/upx/upx_stub.h | 18 ++++--- .../plugins/upx/upx_stub_signatures.cpp | 1 + .../plugins/upx/upx_stub_signatures.h | 6 ++- src/utils/CMakeLists.txt | 1 + src/utils/conversion.cpp | 19 ------- src/{unpacker => utils}/dynamic_buffer.cpp | 4 +- src/utils/string.cpp | 10 ++-- 35 files changed, 199 insertions(+), 185 deletions(-) rename include/retdec/{unpacker => utils}/dynamic_buffer.h (95%) rename src/{unpacker => utils}/dynamic_buffer.cpp (99%) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h index b3ab76729..6089c0c3c 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -52,7 +52,7 @@ struct VBHeader } - std::size_t headerSize() + static std::size_t structureSize() { return sizeof(signature) + sizeof(runtimeBuild) + sizeof(languageDLL) + @@ -86,7 +86,7 @@ struct VBProjInfo } - std::size_t headerSize() + static std::size_t structureSize() { return sizeof(version) + sizeof(objectTableAddr) + sizeof(null) @@ -124,7 +124,7 @@ struct VBObjectTable } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(null1) + sizeof(execCOMAddr) + sizeof(projecInfo2Addr) + sizeof(reserved) + @@ -156,7 +156,7 @@ struct VBPublicObjectDescriptor } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(objectInfoAddr) + sizeof(reserved) + sizeof(publicBytesAddr) + @@ -176,7 +176,7 @@ struct VBExternTableEntry } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(type) + sizeof(importDataAddr); } @@ -192,7 +192,7 @@ struct VBExternTableEntryData } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(moduleNameAddr) + sizeof(apiNameAddr); } @@ -215,7 +215,7 @@ struct VBCOMRData } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(regInfoOffset) + sizeof(projNameOffset) + sizeof(helpFileOffset) + @@ -249,7 +249,7 @@ struct VBCOMRInfo } - std::size_t structureSize() + static std::size_t structureSize() { return sizeof(ifInfoOffset) + sizeof(objNameOffset) + sizeof(objDescOffset) + diff --git a/include/retdec/unpacker/decompression/compressed_data.h b/include/retdec/unpacker/decompression/compressed_data.h index 46606555c..b2635df9f 100644 --- a/include/retdec/unpacker/decompression/compressed_data.h +++ b/include/retdec/unpacker/decompression/compressed_data.h @@ -10,7 +10,9 @@ #include #include -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; namespace retdec { namespace unpacker { diff --git a/include/retdec/unpacker/decompression/nrv/bit_parsers.h b/include/retdec/unpacker/decompression/nrv/bit_parsers.h index 7e777325e..1f1405ff2 100644 --- a/include/retdec/unpacker/decompression/nrv/bit_parsers.h +++ b/include/retdec/unpacker/decompression/nrv/bit_parsers.h @@ -8,7 +8,9 @@ #define RETDEC_UNPACKER_DECOMPRESSION_NRV_BIT_PARSERS_H #include "retdec/fileformat/fftypes.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; namespace retdec { namespace unpacker { diff --git a/include/retdec/unpacker/signature.h b/include/retdec/unpacker/signature.h index aa6fee992..337e9596a 100644 --- a/include/retdec/unpacker/signature.h +++ b/include/retdec/unpacker/signature.h @@ -12,7 +12,9 @@ #include #include "retdec/loader/loader.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; namespace retdec { namespace unpacker { diff --git a/include/retdec/unpacker/unpacking_stub.h b/include/retdec/unpacker/unpacking_stub.h index 3027579c6..1a115ae58 100644 --- a/include/retdec/unpacker/unpacking_stub.h +++ b/include/retdec/unpacker/unpacking_stub.h @@ -13,7 +13,7 @@ namespace retdec { // Forward declarations namespace loader { class Image; } -namespace unpacker { class DynamicBuffer; } +namespace utils { class DynamicBuffer; } namespace unpacker { diff --git a/include/retdec/utils/conversion.h b/include/retdec/utils/conversion.h index f1129ec07..8c2109586 100644 --- a/include/retdec/utils/conversion.h +++ b/include/retdec/utils/conversion.h @@ -300,7 +300,6 @@ void double10ToDouble8(std::vector &dest, unsigned short byteSwap16(unsigned short val); unsigned int byteSwap32(unsigned int val); -unsigned long byteSwap64(unsigned long val); std::string byteSwap16(const std::string &val); std::string byteSwap32(const std::string &val); diff --git a/include/retdec/unpacker/dynamic_buffer.h b/include/retdec/utils/dynamic_buffer.h similarity index 95% rename from include/retdec/unpacker/dynamic_buffer.h rename to include/retdec/utils/dynamic_buffer.h index 9ad6cef78..1acb3227d 100644 --- a/include/retdec/unpacker/dynamic_buffer.h +++ b/include/retdec/utils/dynamic_buffer.h @@ -12,10 +12,10 @@ #include #include -#include "retdec/fileformat/fileformat.h" +#include "retdec/utils/byte_value_storage.h" namespace retdec { -namespace unpacker { +namespace utils { /** * @brief The class for dynamic buffered data manipulation taking the endianness of the data in account. @@ -70,7 +70,7 @@ class DynamicBuffer */ template T read(uint32_t pos, retdec::utils::Endianness endianness = retdec::utils::Endianness::UNKNOWN) const { - static_assert(std::is_integral::value, "retdec::unpacker::DynamicBuffer::read can only accept integral types"); + static_assert(std::is_integral::value, "retdec::utils::DynamicBuffer::read can only accept integral types"); // In case of non-specified endianness, use the default one assigned to DynamicBuffer itself if (endianness == retdec::utils::Endianness::UNKNOWN) @@ -94,7 +94,7 @@ class DynamicBuffer */ template void write(const T& data, uint32_t pos, retdec::utils::Endianness endianness = retdec::utils::Endianness::UNKNOWN) { - static_assert(std::is_integral::value, "retdec::unpacker::DynamicBuffer::write can only accept integral types"); + static_assert(std::is_integral::value, "retdec::utils::DynamicBuffer::write can only accept integral types"); // In case of non-specified endianness, use the default one assigned to DynamicBuffer itself if (endianness == retdec::utils::Endianness::UNKNOWN) @@ -182,7 +182,7 @@ class DynamicBuffer uint32_t _capacity; }; -} // namespace unpacker +} // namespace utils } // namespace retdec #endif diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 96f4e45bb..374688939 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -663,7 +663,7 @@ void PeFormat::loadVisualBasicHeader() return; } - if (!getBytes(bytes, vbHeaderOffset, vbh.headerSize()) || bytes.size() != vbh.headerSize()) + if (!getBytes(bytes, vbHeaderOffset, vbh.structureSize()) || bytes.size() != vbh.structureSize()) { return; } @@ -946,7 +946,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset) std::size_t offset = 0; struct VBProjInfo vbpi; - if (!getBytes(bytes, structureOffset, vbpi.headerSize()) || bytes.size() != vbpi.headerSize()) + if (!getBytes(bytes, structureOffset, vbpi.structureSize()) || bytes.size() != vbpi.structureSize()) { return false; } diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index 91cc1084a..828c5e5e2 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -781,10 +781,6 @@ bool FileInformation::hasRichHeaderRecords() const return richHeader.hasRecords(); } - - - - /** * Check whether visual basic informations are used. * @return @c true if it is used, otherwise @c false/ diff --git a/src/unpacker/CMakeLists.txt b/src/unpacker/CMakeLists.txt index 3bad97af8..972f6816d 100644 --- a/src/unpacker/CMakeLists.txt +++ b/src/unpacker/CMakeLists.txt @@ -5,7 +5,6 @@ set(UNPACKER_SOURCES decompression/nrv/nrv2e_data.cpp decompression/lzmat/lzmat_data.cpp signature.cpp - dynamic_buffer.cpp ) add_library(retdec-unpacker STATIC ${UNPACKER_SOURCES}) diff --git a/src/unpackertool/plugins/mpress/mpress.cpp b/src/unpackertool/plugins/mpress/mpress.cpp index 14aafe821..373d28782 100644 --- a/src/unpackertool/plugins/mpress/mpress.cpp +++ b/src/unpackertool/plugins/mpress/mpress.cpp @@ -8,8 +8,6 @@ #include #include -#include - #include "retdec/loader/loader.h" #include "retdec/unpacker/plugin.h" #include "retdec/unpacker/decompression/lzma/lzma_data.h" @@ -19,6 +17,9 @@ #include "unpackertool/plugins/mpress/mpress.h" #include "unpackertool/plugins/mpress/mpress_exceptions.h" +#include "retdec/fileformat/fileformat.h" + +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { diff --git a/src/unpackertool/plugins/mpress/mpress.h b/src/unpackertool/plugins/mpress/mpress.h index 3523de86b..b26706bba 100644 --- a/src/unpackertool/plugins/mpress/mpress.h +++ b/src/unpackertool/plugins/mpress/mpress.h @@ -7,12 +7,16 @@ #ifndef UNPACKERTOOL_PLUGINS_MPRESS_MPRESS_H #define UNPACKERTOOL_PLUGINS_MPRESS_MPRESS_H +#include + #include "retdec/loader/loader.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" #include "retdec/unpacker/plugin.h" #define mpress_plugin plugin(retdec::unpackertool::mpress::MpressPlugin) +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace mpress { @@ -72,17 +76,17 @@ class MpressPlugin : public Plugin virtual void cleanup() override; private: - bool decompressData(unpacker::DynamicBuffer& compressedContent, unpacker::DynamicBuffer& decompressedContent); - void decodeLzmaProperties(unpacker::DynamicBuffer& compressedContent, std::uint8_t& pb, std::uint8_t& lp, std::uint8_t& lc); + bool decompressData(DynamicBuffer& compressedContent, DynamicBuffer& decompressedContent); + void decodeLzmaProperties(DynamicBuffer& compressedContent, std::uint8_t& pb, std::uint8_t& lp, std::uint8_t& lc); std::uint32_t getFixStub(); - void fixJumpsAndCalls(unpacker::DynamicBuffer& buffer); - void fixImportsAndEp(unpacker::DynamicBuffer& buffer); - void offsetAnalysis(const unpacker::DynamicBuffer& buffer); - void trailingBytesAnalysis(const unpacker::DynamicBuffer& buffer); + void fixJumpsAndCalls(DynamicBuffer& buffer); + void fixImportsAndEp(DynamicBuffer& buffer); + void offsetAnalysis(const DynamicBuffer& buffer); + void trailingBytesAnalysis(const DynamicBuffer& buffer); void fixRelocations(); MpressUnpackerStub detectUnpackerStubVersion(); - MpressFixStub detectFixStubVersion(unpacker::DynamicBuffer& unpackedContent); - void saveFile(const std::string& fileName, unpacker::DynamicBuffer& content); + MpressFixStub detectFixStubVersion(DynamicBuffer& unpackedContent); + void saveFile(const std::string& fileName, DynamicBuffer& content); void copySectionFromOriginalFile(std::uint32_t origSectIndex, const std::string& newFileName, std::uint32_t newSectIndex); std::unique_ptr _file; diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor.h b/src/unpackertool/plugins/upx/decompressors/decompressor.h index 068bbdd5e..c2f9c9d88 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor.h @@ -12,11 +12,9 @@ #include "retdec/unpacker/decompression/compressed_data.h" -namespace retdec { +using namespace retdec::utils; -namespace unpacker { - class DynamicBuffer; -} // namespace unpacker +namespace retdec { namespace unpackertool { namespace upx { @@ -35,29 +33,29 @@ class Decompressor virtual ~Decompressor(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(ElfUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) = 0; + virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(ElfUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) = 0; + virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(MachOUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) = 0; + virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(MachOUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) = 0; + virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) = 0; - virtual void readPackedData(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) = 0; - virtual void decompress(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) = 0; + virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) = 0; + virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) = 0; + virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) = 0; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) = 0; - virtual void readPackedData(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) = 0; - virtual void decompress(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) = 0; + virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) = 0; + virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) = 0; + virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) = 0; protected: - void performDecompression(const std::weak_ptr& compressedDataWptr, retdec::unpacker::DynamicBuffer& unpackedData); + void performDecompression(const std::weak_ptr& compressedDataWptr, DynamicBuffer& unpackedData); }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h index b0321c28c..afb673fc5 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h @@ -8,6 +8,8 @@ #include "unpackertool/plugins/upx/decompressors/decompressor_scrambler.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -21,9 +23,9 @@ class DecompressorDirectJump : public DecompressorScrambler DecompressorDirectJump(); virtual ~DecompressorDirectJump(); - virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h index 05b3eb9c1..6d29652cb 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h @@ -8,6 +8,8 @@ #include "unpackertool/plugins/upx/decompressors/decompressor.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -22,26 +24,26 @@ class DecompressorLzma : public Decompressor virtual ~DecompressorLzma(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.cpp b/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.cpp index 018c2eded..fd83331de 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.cpp +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.cpp @@ -16,6 +16,7 @@ #include "retdec/unpacker/decompression/nrv/nrv2d_data.h" #include "retdec/unpacker/decompression/nrv/nrv2e_data.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { @@ -379,7 +380,7 @@ void DecompressorNrv::setupPackingMethod(std::uint8_t packingMethod) } } -void DecompressorNrv::decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) +void DecompressorNrv::decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData) { if (_bitParser == nullptr) throw FatalException("Unpacking NRV packed data without bit parser. Report this incident please."); diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.h b/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.h index cd0e53f14..5245928a2 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_nrv.h @@ -9,6 +9,8 @@ #include "unpackertool/plugins/upx/decompressors/decompressor.h" #include "retdec/unpacker/decompression/nrv/bit_parsers.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -23,30 +25,30 @@ class DecompressorNrv : public Decompressor virtual ~DecompressorNrv(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; protected: void setupPackingMethod(std::uint8_t packingMethod); - void decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData); + void decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData); private: char _nrvVersion; diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_scrambler.h b/src/unpackertool/plugins/upx/decompressors/decompressor_scrambler.h index 3a8cd6482..47d399093 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_scrambler.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_scrambler.h @@ -8,6 +8,8 @@ #include "unpackertool/plugins/upx/decompressors/decompressor.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -24,24 +26,24 @@ class DecompressorScrambler : public Decompressor virtual ~DecompressorScrambler(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void readPackedData(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void readPackedData(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; protected: std::shared_ptr _scrambledStub; ///< The unpacking stub packed by this scrambler. diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_upxshit.h b/src/unpackertool/plugins/upx/decompressors/decompressor_upxshit.h index 2ab324255..29859b8f1 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_upxshit.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_upxshit.h @@ -8,6 +8,8 @@ #include "unpackertool/plugins/upx/decompressors/decompressor_scrambler.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -21,9 +23,9 @@ class DecompressorUpxshit : public DecompressorScrambler DecompressorUpxshit(); virtual ~DecompressorUpxshit(); - virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::unpacker::DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/elf/elf_upx_stub.cpp b/src/unpackertool/plugins/upx/elf/elf_upx_stub.cpp index e887609e7..55a1de714 100644 --- a/src/unpackertool/plugins/upx/elf/elf_upx_stub.cpp +++ b/src/unpackertool/plugins/upx/elf/elf_upx_stub.cpp @@ -18,8 +18,9 @@ #include "unpackertool/plugins/upx/upx.h" #include "unpackertool/plugins/upx/upx_exceptions.h" #include "unpackertool/plugins/upx/upx_stub_signatures.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { @@ -256,7 +257,7 @@ template void ElfUpxStub::setupPackingMethod(std::uint8_t packi * @param packedData The packed data. * @param unpackedData Buffer where to unpack the data. */ -template void ElfUpxStub::decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) +template void ElfUpxStub::decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData) { _decompressor->decompress(this, packedData, unpackedData); } @@ -370,7 +371,7 @@ template void ElfUpxStub::unpackBlock(DynamicBuffer& unpackedDa } /** - * Unpacks the packed block that is stored in the @ref retdec::unpacker::DynamicBuffer. + * Unpacks the packed block that is stored in the @ref retdec::utils::DynamicBuffer. * * @tparam bits Number of bits of the architecture. * diff --git a/src/unpackertool/plugins/upx/elf/elf_upx_stub.h b/src/unpackertool/plugins/upx/elf/elf_upx_stub.h index dd84fba0b..ecc150672 100644 --- a/src/unpackertool/plugins/upx/elf/elf_upx_stub.h +++ b/src/unpackertool/plugins/upx/elf/elf_upx_stub.h @@ -11,7 +11,9 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "retdec/unpacker/decompression/nrv/bit_parsers.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; // Foroward declarations namespace ELFIO { @@ -81,7 +83,7 @@ template class ElfUpxStub : public UpxStub using ElfHeaderType = typename ElfUpxStubTraits::ElfHeaderType; using ProgHeaderType = typename ElfUpxStubTraits::ProgHeaderType; - ElfUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const retdec::unpacker::DynamicBuffer& stubCapturedData, + ElfUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const DynamicBuffer& stubCapturedData, std::unique_ptr decompressor, const UpxMetadata& metadata); virtual ~ElfUpxStub() override; @@ -90,15 +92,15 @@ template class ElfUpxStub : public UpxStub virtual void cleanup() override; void setupPackingMethod(std::uint8_t packingMethod); - void decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData); + void decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData); private: std::uint32_t getFirstBlockOffset(); - bool validBlock(const retdec::unpacker::DynamicBuffer& block); - void unpackBlock(retdec::unpacker::DynamicBuffer& unpackedData, AddressType fileOffset, AddressType& readFromBuffer, std::uint32_t sizeHint = 0); - void unpackBlock(retdec::unpacker::DynamicBuffer& unpackedData, retdec::unpacker::DynamicBuffer& packedBlock, AddressType& readFromBuffer, std::uint32_t sizeHint = 0); + bool validBlock(const DynamicBuffer& block); + void unpackBlock(DynamicBuffer& unpackedData, AddressType fileOffset, AddressType& readFromBuffer, std::uint32_t sizeHint = 0); + void unpackBlock(DynamicBuffer& unpackedData, DynamicBuffer& packedBlock, AddressType& readFromBuffer, std::uint32_t sizeHint = 0); AddressType nextLoadSegmentGap(const std::vector& phdrs, std::uint32_t currentLoadSegmentIndex); - void unfilterBlock(const retdec::unpacker::DynamicBuffer& packedBlock, retdec::unpacker::DynamicBuffer& unpackedData); + void unfilterBlock(const DynamicBuffer& packedBlock, DynamicBuffer& unpackedData); retdec::unpacker::BitParser* _bitParser; ///< Associated NRV bit parser. }; diff --git a/src/unpackertool/plugins/upx/macho/macho_upx_stub.cpp b/src/unpackertool/plugins/upx/macho/macho_upx_stub.cpp index ad3916fee..c8c3ec329 100644 --- a/src/unpackertool/plugins/upx/macho/macho_upx_stub.cpp +++ b/src/unpackertool/plugins/upx/macho/macho_upx_stub.cpp @@ -14,8 +14,9 @@ #include "unpackertool/plugins/upx/unfilter.h" #include "unpackertool/plugins/upx/upx.h" #include "unpackertool/plugins/upx/upx_exceptions.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { @@ -170,7 +171,7 @@ template void MachOUpxStub::setupPackingMethod(std::uint8_t pac _decompressor->setupPackingMethod(this, packingMethod); } -template void MachOUpxStub::decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData) +template void MachOUpxStub::decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData) { _decompressor->decompress(this, packedData, unpackedData); } diff --git a/src/unpackertool/plugins/upx/macho/macho_upx_stub.h b/src/unpackertool/plugins/upx/macho/macho_upx_stub.h index 5cdca23cd..64871da21 100644 --- a/src/unpackertool/plugins/upx/macho/macho_upx_stub.h +++ b/src/unpackertool/plugins/upx/macho/macho_upx_stub.h @@ -11,7 +11,9 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "retdec/unpacker/decompression/nrv/bit_parsers.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; namespace retdec { namespace unpackertool { @@ -67,7 +69,7 @@ template class MachOUpxStub : public UpxStub using MachOHeaderType = typename MachOUpxStubTraits::MachOHeaderType; using MachOSegmentCommandType = typename MachOUpxStubTraits::MachOSegmentCommandType; - MachOUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const retdec::unpacker::DynamicBuffer& stubCapturedData, + MachOUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const DynamicBuffer& stubCapturedData, std::unique_ptr decompressor, const UpxMetadata& metadata); virtual ~MachOUpxStub() override; @@ -76,15 +78,15 @@ template class MachOUpxStub : public UpxStub virtual void cleanup() override; void setupPackingMethod(std::uint8_t packingMethod); - void decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData); + void decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData); void unpack(std::ifstream& inputFile, std::ofstream& outputFile, std::uint64_t baseInputOffset, std::uint64_t baseOutputOffset); protected: std::uint32_t getFirstBlockOffset(std::ifstream& inputFile) const; - retdec::unpacker::DynamicBuffer readNextBlock(std::ifstream& inputFile); - retdec::unpacker::DynamicBuffer unpackBlock(retdec::unpacker::DynamicBuffer& packedBlock); - void unfilterBlock(const retdec::unpacker::DynamicBuffer& packedBlock, retdec::unpacker::DynamicBuffer& unpackedData); + DynamicBuffer readNextBlock(std::ifstream& inputFile); + DynamicBuffer unpackBlock(DynamicBuffer& packedBlock); + void unfilterBlock(const DynamicBuffer& packedBlock, DynamicBuffer& unpackedData); private: std::uint64_t _readPos; diff --git a/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp b/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp index 5f0786c8a..22dd0b7fa 100644 --- a/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp +++ b/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp @@ -271,7 +271,7 @@ template void PeUpxStub::setupPackingMethod(std::uint8_t packin } /** - * Reads the unpacking stub (from EP up to the end of the EP section) and stores it into @ref retdec::unpacker::DynamicBuffer. + * Reads the unpacking stub (from EP up to the end of the EP section) and stores it into @ref retdec::utils::DynamicBuffer. * * @param unpackingStub Buffer where to store unpacking stub. */ @@ -292,7 +292,7 @@ template void PeUpxStub::readPackedData(DynamicBuffer& packedDa } /** - * Decompresses the packed data and stores result in @ref retdec::unpacker::DynamicBuffer. + * Decompresses the packed data and stores result in @ref retdec::utils::DynamicBuffer. * * @param packedData Data to decompress. * @param unpackedData Buffer where to store the result. @@ -427,7 +427,7 @@ template void PeUpxStub::unpackData(DynamicBuffer& unpackedData } /** - * Reads the ILT (Import Lookup Table) of the packed file and stores it into @ref retdec::unpacker::DynamicBuffer. + * Reads the ILT (Import Lookup Table) of the packed file and stores it into @ref retdec::utils::DynamicBuffer. * * @param ilt Buffer where to store ILT. */ @@ -510,7 +510,7 @@ template void PeUpxStub::fixSizeOfSections(const DynamicBuffer& * * @return @ref UpxExtraData structure. */ -template UpxExtraData PeUpxStub::parseExtraData(retdec::unpacker::DynamicBuffer& unpackedData, retdec::unpacker::DynamicBuffer& originalHeader) +template UpxExtraData PeUpxStub::parseExtraData(DynamicBuffer& unpackedData, DynamicBuffer& originalHeader) { // First we need to find original PE header. If we have metadata, we can easily find it using unpacked data size. // However, if we don't have, we need to use heuristic that looks in the last 1024 bytes (should be more than enough) @@ -828,7 +828,7 @@ template void PeUpxStub::fixOep(const DynamicBuffer& originalHe * * @param originalHeader The original PE header. */ -template void PeUpxStub::fixExports(const retdec::unpacker::DynamicBuffer& originalHeader) +template void PeUpxStub::fixExports(const DynamicBuffer& originalHeader) { // Assumption is that exports are compressed _exportsCompressed = true; @@ -1171,7 +1171,7 @@ template void PeUpxStub::fixCertificates() * @param unpackedData The unpacked data. * @param extraData @ref UpxExtraData structure. */ -template void PeUpxStub::cutHintsData(retdec::unpacker::DynamicBuffer& unpackedData, const UpxExtraData& extraData) +template void PeUpxStub::cutHintsData(DynamicBuffer& unpackedData, const UpxExtraData& extraData) { // We need to find lowest possible address where we can cut the unpacked data and remove hints. // We always know the address of original PE header, we need to check whether import hints or reloc hints are at lower address. diff --git a/src/unpackertool/plugins/upx/pe/pe_upx_stub.h b/src/unpackertool/plugins/upx/pe/pe_upx_stub.h index 4e2885e8e..56cf99f2f 100644 --- a/src/unpackertool/plugins/upx/pe/pe_upx_stub.h +++ b/src/unpackertool/plugins/upx/pe/pe_upx_stub.h @@ -9,10 +9,14 @@ #include +#include + #include "unpackertool/plugins/upx/upx_stub.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" #include "retdec/unpacker/signature.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -109,16 +113,16 @@ template class PeUpxStub : public UpxStub using PeLibFileType = typename PeUpxStubTraits::PeLibFileType; public: - PeUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const retdec::unpacker::DynamicBuffer& stubCapturedData, + PeUpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const DynamicBuffer& stubCapturedData, std::unique_ptr decompressor, const UpxMetadata& metadata); virtual ~PeUpxStub() override; virtual void unpack(const std::string& ouputFile) override; virtual void setupPackingMethod(std::uint8_t packingMethod); - virtual void readUnpackingStub(retdec::unpacker::DynamicBuffer& unpackingStub); - virtual void readPackedData(retdec::unpacker::DynamicBuffer& packedData, bool trustMetadata); - virtual void decompress(retdec::unpacker::DynamicBuffer& packedData, retdec::unpacker::DynamicBuffer& unpackedData, bool trustMetadata); + virtual void readUnpackingStub(DynamicBuffer& unpackingStub); + virtual void readPackedData(DynamicBuffer& packedData, bool trustMetadata); + virtual void decompress(DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata); virtual void cleanup() override; virtual std::uint32_t getRealEpAddress() const override; @@ -130,28 +134,28 @@ template class PeUpxStub : public UpxStub private: void prepare(); - void detectUnfilter(const retdec::unpacker::DynamicBuffer& unpackingStub); - void unpackData(retdec::unpacker::DynamicBuffer& unpackedData); - void readPackedFileILT(retdec::unpacker::DynamicBuffer& ilt); - void fixSizeOfSections(const retdec::unpacker::DynamicBuffer& unpackedData); - UpxExtraData parseExtraData(retdec::unpacker::DynamicBuffer& unpackedData, retdec::unpacker::DynamicBuffer& originalHeader); - void fixPeHeader(const retdec::unpacker::DynamicBuffer& originalHeader); - void unfilterData(retdec::unpacker::DynamicBuffer& unpackedData); - void fixImports(const retdec::unpacker::DynamicBuffer& unpackedData, const UpxExtraData& extraData, const retdec::unpacker::DynamicBuffer& ilt); - void fixRelocations(retdec::unpacker::DynamicBuffer& unpackedData, const UpxExtraData& extraData); - void fixTls(const retdec::unpacker::DynamicBuffer& originalHeader); - void fixOep(const retdec::unpacker::DynamicBuffer& originalHeader); - void fixExports(const retdec::unpacker::DynamicBuffer& originalHeader); - void fixLoadConfiguration(const retdec::unpacker::DynamicBuffer& originalHeader); - void fixResources(const retdec::unpacker::DynamicBuffer& unpackedData, const retdec::unpacker::DynamicBuffer& originalHeader); - void fixSectionHeaders(const retdec::unpacker::DynamicBuffer& originalHeader); + void detectUnfilter(const DynamicBuffer& unpackingStub); + void unpackData(DynamicBuffer& unpackedData); + void readPackedFileILT(DynamicBuffer& ilt); + void fixSizeOfSections(const DynamicBuffer& unpackedData); + UpxExtraData parseExtraData(DynamicBuffer& unpackedData, DynamicBuffer& originalHeader); + void fixPeHeader(const DynamicBuffer& originalHeader); + void unfilterData(DynamicBuffer& unpackedData); + void fixImports(const DynamicBuffer& unpackedData, const UpxExtraData& extraData, const DynamicBuffer& ilt); + void fixRelocations(DynamicBuffer& unpackedData, const UpxExtraData& extraData); + void fixTls(const DynamicBuffer& originalHeader); + void fixOep(const DynamicBuffer& originalHeader); + void fixExports(const DynamicBuffer& originalHeader); + void fixLoadConfiguration(const DynamicBuffer& originalHeader); + void fixResources(const DynamicBuffer& unpackedData, const DynamicBuffer& originalHeader); + void fixSectionHeaders(const DynamicBuffer& originalHeader); void fixCoffSymbolTable(); void fixCertificates(); - void cutHintsData(retdec::unpacker::DynamicBuffer& unpackedData, const UpxExtraData& extraData); - void saveFile(const std::string& outputFile, retdec::unpacker::DynamicBuffer& unpackedData); + void cutHintsData(DynamicBuffer& unpackedData, const UpxExtraData& extraData); + void saveFile(const std::string& outputFile, DynamicBuffer& unpackedData); void loadResources(PeLib::ResourceNode* rootNode, std::uint32_t offset, std::uint32_t uncompressedRsrcRva, std::uint32_t compressedRsrcRva, - const retdec::unpacker::DynamicBuffer& uncompressedRsrcs, const retdec::unpacker::DynamicBuffer& unpackedData, std::unordered_set& visitedNodes); + const DynamicBuffer& uncompressedRsrcs, const DynamicBuffer& unpackedData, std::unordered_set& visitedNodes); std::uint8_t getPackingMethod(bool trustMetadata) const; PeLibFileType* _newPeFile; ///< Unpacked output file. diff --git a/src/unpackertool/plugins/upx/unfilter.cpp b/src/unpackertool/plugins/upx/unfilter.cpp index c221114e6..1a37b0eb5 100644 --- a/src/unpackertool/plugins/upx/unfilter.cpp +++ b/src/unpackertool/plugins/upx/unfilter.cpp @@ -8,7 +8,7 @@ #include "unpackertool/plugins/upx/unfilter.h" -using namespace retdec::unpacker; +using namespace retdec::utils; namespace retdec { namespace unpackertool { diff --git a/src/unpackertool/plugins/upx/unfilter.h b/src/unpackertool/plugins/upx/unfilter.h index 2da08769f..8c87389ca 100644 --- a/src/unpackertool/plugins/upx/unfilter.h +++ b/src/unpackertool/plugins/upx/unfilter.h @@ -7,7 +7,9 @@ #ifndef UNPACKERTOOL_PLUGINS_UPX_UNFILTER_H #define UNPACKERTOOL_PLUGINS_UPX_UNFILTER_H -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" + +using namespace retdec::utils; namespace retdec { namespace unpackertool { @@ -37,9 +39,9 @@ struct Unfilter { virtual ~Unfilter() {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) = 0; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) = 0; - static bool run(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterId, std::uint32_t filterParam, std::uint32_t filterCount = 0, std::uint32_t startOffset = 0, std::uint32_t size = 0); + static bool run(DynamicBuffer& unpackedData, std::uint32_t filterId, std::uint32_t filterParam, std::uint32_t filterCount = 0, std::uint32_t startOffset = 0, std::uint32_t size = 0); }; /** @@ -49,7 +51,7 @@ struct Unfilter11 : public Unfilter { virtual ~Unfilter11() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -59,7 +61,7 @@ struct Unfilter16 : public Unfilter { virtual ~Unfilter16() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -69,7 +71,7 @@ struct Unfilter24 : public Unfilter { virtual ~Unfilter24() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -79,7 +81,7 @@ struct Unfilter26_46 : public Unfilter { virtual ~Unfilter26_46() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -89,7 +91,7 @@ struct Unfilter49 : public Unfilter { virtual ~Unfilter49() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -99,7 +101,7 @@ struct Unfilter50 : public Unfilter { virtual ~Unfilter50() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; /** @@ -109,7 +111,7 @@ struct UnfilterD0 : public Unfilter { virtual ~UnfilterD0() override {} - virtual void perform(retdec::unpacker::DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; + virtual void perform(DynamicBuffer& unpackedData, std::uint32_t filterParam, std::uint32_t filterCount, std::uint32_t startOffset, std::uint32_t size) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/upx_stub.cpp b/src/unpackertool/plugins/upx/upx_stub.cpp index cdd50ceac..aabde4fc0 100644 --- a/src/unpackertool/plugins/upx/upx_stub.cpp +++ b/src/unpackertool/plugins/upx/upx_stub.cpp @@ -14,8 +14,9 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "unpackertool/plugins/upx/upx_stub_signatures.h" #include "retdec/unpacker/decompression/compressed_data.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { @@ -72,7 +73,7 @@ UpxMetadata UpxMetadata::read(retdec::loader::Image* file) } inputFile.read(reinterpret_cast(&dataBuffer[0]), 1024); - retdec::unpacker::DynamicBuffer data(dataBuffer, file->getFileFormat()->getEndianness()); + DynamicBuffer data(dataBuffer, file->getFileFormat()->getEndianness()); std::string pattern = "UPX!"; for (size_t i = 0; i < 1024 - pattern.length(); ++i) @@ -81,7 +82,7 @@ UpxMetadata UpxMetadata::read(retdec::loader::Image* file) if (needle == pattern) { std::uint32_t metadataSize = UpxMetadata::getSizeOfVersion(data.read(static_cast(i) + 4)); - retdec::unpacker::DynamicBuffer metadataBuffer(data, static_cast(i), metadataSize); + DynamicBuffer metadataBuffer(data, static_cast(i), metadataSize); // Check whether calculated checksum and checksum in header matches // This is the only way how we can validate the metadata @@ -105,7 +106,7 @@ UpxMetadata UpxMetadata::read(retdec::loader::Image* file) return metadata; } -uint8_t UpxMetadata::calcChecksum(const retdec::unpacker::DynamicBuffer& data) +uint8_t UpxMetadata::calcChecksum(const DynamicBuffer& data) { std::uint32_t sum = 0; for (std::uint32_t i = 4; i < data.getRealDataSize() - 1; ++i) @@ -181,7 +182,7 @@ std::shared_ptr UpxStub::createStub(retdec::loader::Image* file, const return _createStubImpl(file, &stubBytes); } -std::shared_ptr UpxStub::_createStubImpl(retdec::loader::Image* file, const retdec::unpacker::DynamicBuffer* stubBytes) +std::shared_ptr UpxStub::_createStubImpl(retdec::loader::Image* file, const DynamicBuffer* stubBytes) { UpxMetadata metadata = UpxMetadata::read(file); @@ -377,7 +378,7 @@ void UpxStub::setStubData(const UpxStubData* stubData) _stubData = stubData; } -void UpxStub::setStubCapturedData(const retdec::unpacker::DynamicBuffer& stubCapturedData) +void UpxStub::setStubCapturedData(const DynamicBuffer& stubCapturedData) { _stubCapturedData = stubCapturedData; } diff --git a/src/unpackertool/plugins/upx/upx_stub.h b/src/unpackertool/plugins/upx/upx_stub.h index 199d887c4..47a25418e 100644 --- a/src/unpackertool/plugins/upx/upx_stub.h +++ b/src/unpackertool/plugins/upx/upx_stub.h @@ -11,9 +11,11 @@ #include "retdec/loader/loader.h" #include "retdec/unpacker/plugin.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" #include "retdec/unpacker/unpacking_stub.h" +using namespace retdec::utils; + namespace retdec { // Forward declaration @@ -64,7 +66,7 @@ class UpxMetadata UpxMetadata(const UpxMetadata& metadata); static UpxMetadata read(retdec::loader::Image* file); - static std::uint8_t calcChecksum(const retdec::unpacker::DynamicBuffer& data); + static std::uint8_t calcChecksum(const DynamicBuffer& data); static std::uint32_t getSizeOfVersion(std::uint8_t version); UpxStubVersion getStubVersion() const; @@ -108,34 +110,34 @@ class UpxMetadata class UpxStub : public retdec::unpacker::UnpackingStub { public: - UpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const retdec::unpacker::DynamicBuffer& stubCapturedData, + UpxStub(retdec::loader::Image* inputFile, const UpxStubData* stubData, const DynamicBuffer& stubCapturedData, std::unique_ptr decompressor, const UpxMetadata& metadata); virtual ~UpxStub() override; static std::shared_ptr createStub(retdec::loader::Image* file); - static std::shared_ptr createStub(retdec::loader::Image* file, const retdec::unpacker::DynamicBuffer& stubBytes); + static std::shared_ptr createStub(retdec::loader::Image* file, const DynamicBuffer& stubBytes); UpxStubVersion getVersion() const; const UpxStubData* getStubData() const; - const retdec::unpacker::DynamicBuffer* getStubCapturedData() const; + const DynamicBuffer* getStubCapturedData() const; Decompressor* getDecompressor() const; const UpxMetadata* getUpxMetadata() const; virtual std::uint32_t getRealEpAddress() const; void setStubData(const UpxStubData* stubData); - void setStubCapturedData(const retdec::unpacker::DynamicBuffer& stubCapturedData); + void setStubCapturedData(const DynamicBuffer& stubCapturedData); protected: std::unique_ptr decodePackingMethod(std::uint8_t packingMethod) const; const UpxStubData* _stubData; ///< Additional stub information. - retdec::unpacker::DynamicBuffer _stubCapturedData; ///< Data captured while matching signature of this stub. + DynamicBuffer _stubCapturedData; ///< Data captured while matching signature of this stub. std::unique_ptr _decompressor; ///< Decompressor associated with stub. UpxMetadata _metadata; ///< UPX metadata aka packheader. private: - static std::shared_ptr _createStubImpl(retdec::loader::Image* file, const retdec::unpacker::DynamicBuffer* stubBytes); + static std::shared_ptr _createStubImpl(retdec::loader::Image* file, const DynamicBuffer* stubBytes); }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/upx_stub_signatures.cpp b/src/unpackertool/plugins/upx/upx_stub_signatures.cpp index d2699acae..b0889653b 100644 --- a/src/unpackertool/plugins/upx/upx_stub_signatures.cpp +++ b/src/unpackertool/plugins/upx/upx_stub_signatures.cpp @@ -8,6 +8,7 @@ using namespace retdec::fileformat; using namespace retdec::loader; +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { diff --git a/src/unpackertool/plugins/upx/upx_stub_signatures.h b/src/unpackertool/plugins/upx/upx_stub_signatures.h index c0a1759f5..a7dc16215 100644 --- a/src/unpackertool/plugins/upx/upx_stub_signatures.h +++ b/src/unpackertool/plugins/upx/upx_stub_signatures.h @@ -12,6 +12,8 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "retdec/unpacker/signature.h" +using namespace retdec::utils; + namespace retdec { namespace unpackertool { namespace upx { @@ -54,8 +56,8 @@ class UpxStubSignatures UpxStubSignatures(const UpxStubSignatures&) = delete; ~UpxStubSignatures(); - static const UpxStubData* matchSignatures(retdec::loader::Image* file, retdec::unpacker::DynamicBuffer& captureData); - static const UpxStubData* matchSignatures(const retdec::unpacker::DynamicBuffer& data, retdec::unpacker::DynamicBuffer& captureData, + static const UpxStubData* matchSignatures(retdec::loader::Image* file, DynamicBuffer& captureData); + static const UpxStubData* matchSignatures(const DynamicBuffer& data, DynamicBuffer& captureData, retdec::fileformat::Architecture architecture = retdec::fileformat::Architecture::UNKNOWN, retdec::fileformat::Format format = retdec::fileformat::Format::UNKNOWN); private: diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index c76985d81..1fc3a010c 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -4,6 +4,7 @@ set(RETDEC_UTILS_SOURCES byte_value_storage.cpp binary_path.cpp conversion.cpp + dynamic_buffer.cpp file_io.cpp filesystem_path.cpp math.cpp diff --git a/src/utils/conversion.cpp b/src/utils/conversion.cpp index 16331b40d..1526574b2 100644 --- a/src/utils/conversion.cpp +++ b/src/utils/conversion.cpp @@ -184,25 +184,6 @@ unsigned int byteSwap32(unsigned int val) { (0xFF & val) << 24; } -/** -* @brief Swap bytes for Intel x86 64-bit little-endian immediate. -* -* @param val Original value. -* -* @return Value with swapped bytes -*/ -unsigned long byteSwap64(unsigned long val) { - return (0xFF00000000000000 & val) >> 56 | - (0xFF000000000000 & val) >> 40 | - (0xFF0000000000 & val) >> 24 | - (0xFF00000000 & val) >> 8 | - (0xFF000000 & val) << 8 | - (0xFF0000 & val) << 24 | - (0xFF00 & val) << 40 | - (0xFF & val) << 56; -} - - /** * @brief Swap bytes for Intel x86 16-bit little-endian immediate. * diff --git a/src/unpacker/dynamic_buffer.cpp b/src/utils/dynamic_buffer.cpp similarity index 99% rename from src/unpacker/dynamic_buffer.cpp rename to src/utils/dynamic_buffer.cpp index 1e8c78dc1..5ba756107 100644 --- a/src/unpacker/dynamic_buffer.cpp +++ b/src/utils/dynamic_buffer.cpp @@ -4,12 +4,12 @@ * @copyright (c) 2017 Avast Software, licensed under the MIT license */ -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" using namespace retdec::utils; namespace retdec { -namespace unpacker { +namespace utils { /** * Creates the empty DynamicBuffer object with no capacity and specified endianness. diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 03a010f83..e0e468a88 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -49,7 +49,7 @@ bool isNonasciiChar(unsigned char c) { */ std::string replaceChars(const std::string &str, bool (* predicate)(unsigned char)) { std::stringstream result; - const std::size_t maxC = std::pow(2, sizeof(std::string::value_type) * CHAR_BIT) - 1; + const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; for (const auto &c : str) { if (predicate(c)) { const auto val = numToStr(c & maxC, std::hex); @@ -417,7 +417,7 @@ std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) std::stringstream result; if (!bytes || !nBytes) { - return ""; + return {}; } if (nBytes & 1) { @@ -436,7 +436,7 @@ std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) } else { - const std::size_t maxC = std::pow(2, sizeof(std::string::value_type) * CHAR_BIT) - 1; + const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; const auto val1 = numToStr(bytes[i] & maxC, std::hex); const auto val2 = numToStr(bytes[i + 1] & maxC, std::hex); result << "\\x" << std::setw(2) << std::setfill('0') << val1; @@ -464,7 +464,7 @@ std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t bytes std::string result; if (!bytes) { - return ""; + return {}; } if (maxBytes == 0) @@ -492,7 +492,7 @@ std::string readNullTerminatedAscii(const std::uint8_t *bytes, std::size_t bytes if (i == maxBytes && failOnExceed) { - return ""; + return {}; } return replaceNonprintableChars(result); From 3338273c739b9a0ebf48714251098137b584b6e6 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Fri, 22 Feb 2019 17:02:33 +0100 Subject: [PATCH 30/33] pow fixed --- src/utils/string.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/string.cpp b/src/utils/string.cpp index e0e468a88..227f832b4 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -49,7 +49,7 @@ bool isNonasciiChar(unsigned char c) { */ std::string replaceChars(const std::string &str, bool (* predicate)(unsigned char)) { std::stringstream result; - const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; + const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT - 1)) - 1; for (const auto &c : str) { if (predicate(c)) { const auto val = numToStr(c & maxC, std::hex); @@ -436,7 +436,7 @@ std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) } else { - const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; + const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT - 1)) - 1; const auto val1 = numToStr(bytes[i] & maxC, std::hex); const auto val2 = numToStr(bytes[i + 1] & maxC, std::hex); result << "\\x" << std::setw(2) << std::setfill('0') << val1; From 9da9543104d95c14de0fb5168db58bd66537dab1 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 23 Feb 2019 13:24:05 +0100 Subject: [PATCH 31/33] doxygen fixed --- include/retdec/utils/dynamic_buffer.h | 2 +- src/utils/dynamic_buffer.cpp | 2 +- tests/unpacker/dynamic_buffer_tests.cpp | 2 +- tests/unpacker/signature_tests.cpp | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/retdec/utils/dynamic_buffer.h b/include/retdec/utils/dynamic_buffer.h index 1acb3227d..e791c4ad1 100644 --- a/include/retdec/utils/dynamic_buffer.h +++ b/include/retdec/utils/dynamic_buffer.h @@ -1,5 +1,5 @@ /** - * @file include/retdec/unpacker/dynamic_buffer.h + * @file include/retdec/utils/dynamic_buffer.h * @brief Declaration of class for buffered data mainpulation. * @copyright (c) 2017 Avast Software, licensed under the MIT license */ diff --git a/src/utils/dynamic_buffer.cpp b/src/utils/dynamic_buffer.cpp index 5ba756107..550ac4cf1 100644 --- a/src/utils/dynamic_buffer.cpp +++ b/src/utils/dynamic_buffer.cpp @@ -1,5 +1,5 @@ /** - * @file src/unpacker/dynamic_buffer.cpp + * @file src/utils/dynamic_buffer.cpp * @brief Implementation of class for buffered data mainpulation. * @copyright (c) 2017 Avast Software, licensed under the MIT license */ diff --git a/tests/unpacker/dynamic_buffer_tests.cpp b/tests/unpacker/dynamic_buffer_tests.cpp index da57cbc42..1e4bebeae 100644 --- a/tests/unpacker/dynamic_buffer_tests.cpp +++ b/tests/unpacker/dynamic_buffer_tests.cpp @@ -9,7 +9,7 @@ #include #include "retdec/fileformat/fftypes.h" -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" using namespace ::testing; using namespace retdec::utils; diff --git a/tests/unpacker/signature_tests.cpp b/tests/unpacker/signature_tests.cpp index 0a2b7e64e..5d538635b 100644 --- a/tests/unpacker/signature_tests.cpp +++ b/tests/unpacker/signature_tests.cpp @@ -6,10 +6,11 @@ #include -#include "retdec/unpacker/dynamic_buffer.h" +#include "retdec/utils/dynamic_buffer.h" #include "retdec/unpacker/signature.h" using namespace ::testing; +using namespace retdec::utils; namespace retdec { namespace unpacker { From 1ec713ce02d0f11abbe036112392592cd4b68d7d Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Sat, 23 Feb 2019 21:30:31 +0100 Subject: [PATCH 32/33] DynamicBuffer used for VB parsing --- .../visual_basic/visual_basic_structures.h | 40 --- src/fileformat/file_format/pe/pe_format.cpp | 316 ++++++------------ 2 files changed, 102 insertions(+), 254 deletions(-) diff --git a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h index 6089c0c3c..56e70ff68 100644 --- a/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h +++ b/include/retdec/fileformat/types/visual_basic/visual_basic_structures.h @@ -47,11 +47,6 @@ struct VBHeader std::uint32_t helpFileOffset; ///< offset to the string containing name of the Help file std::uint32_t projNameOffset; ///< offset to the string containing project's name - VBHeader() - { - - } - static std::size_t structureSize() { return @@ -81,11 +76,6 @@ struct VBProjInfo std::uint32_t externalTableAddr; ///< External table address std::uint32_t nExternals; ///< number of external OCX components - VBProjInfo() - { - - } - static std::size_t structureSize() { return @@ -119,11 +109,6 @@ struct VBObjectTable std::uint32_t IDE4; ///< IDE4 internals std::uint32_t templateVesion; ///< template version - VBObjectTable() - { - - } - static std::size_t structureSize() { return @@ -151,11 +136,6 @@ struct VBPublicObjectDescriptor std::uint32_t objectType; ///< object type flags std::uint32_t null; ///< null - VBPublicObjectDescriptor() - { - - } - static std::size_t structureSize() { return @@ -171,11 +151,6 @@ struct VBExternTableEntry std::uint32_t type; ///< import type std::uint32_t importDataAddr; ///< import data address - VBExternTableEntry() - { - - } - static std::size_t structureSize() { return sizeof(type) + sizeof(importDataAddr); @@ -187,11 +162,6 @@ struct VBExternTableEntryData std::uint32_t moduleNameAddr; ///< mode name address std::uint32_t apiNameAddr; ///< api name address - VBExternTableEntryData() - { - - } - static std::size_t structureSize() { return sizeof(moduleNameAddr) + sizeof(apiNameAddr); @@ -209,11 +179,6 @@ struct VBCOMRData std::uint16_t unknown; ///< unknown std::uint16_t tlbVerMajor; ///< TypeLib major version std::uint16_t tlbVerMinor; ///< TypeLib minor version - - VBCOMRData() - { - - } static std::size_t structureSize() { @@ -243,11 +208,6 @@ struct VBCOMRInfo std::uint16_t defaultIcon; ///< Minimized icon of control window std::uint16_t isDesignerFlag; ///< Specifies whether Designed Data offset is valid std::uint32_t designerDataOffset; ///< Offset to Designed Data - - VBCOMRInfo() - { - - } static std::size_t structureSize() { diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 374688939..3f94b1a25 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -18,6 +18,7 @@ #include "retdec/utils/conversion.h" #include "retdec/utils/scope_exit.h" #include "retdec/utils/string.h" +#include "retdec/utils/dynamic_buffer.h" #include "retdec/fileformat/file_format/pe/pe_format.h" #include "retdec/fileformat/file_format/pe/pe_format_parser/pe_format_parser32.h" #include "retdec/fileformat/file_format/pe/pe_format_parser/pe_format_parser64.h" @@ -668,54 +669,30 @@ void PeFormat::loadVisualBasicHeader() return; } - vbh.signature = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.signature); - vbh.runtimeBuild = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeBuild); - std::memcpy(&vbh.languageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); - std::memcpy(&vbh.backupLanguageDLL, reinterpret_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); - vbh.runtimeDLLVersion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.runtimeDLLVersion); - vbh.LCID1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.LCID1); - vbh.LCID2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.LCID2); - vbh.subMainAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.subMainAddr); - vbh.projectInfoAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projectInfoAddr); - vbh.MDLIntObjsFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.MDLIntObjsFlags); - vbh.MDLIntObjsFlags2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.MDLIntObjsFlags2); - vbh.threadFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.threadFlags); - vbh.nThreads = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nThreads); - vbh.nForms = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nForms); - vbh.nExternals = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nExternals); - vbh.nThunks = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.nThunks); - vbh.GUITableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.GUITableAddr); - vbh.externalTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.externalTableAddr); - vbh.COMRegisterDataAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.COMRegisterDataAddr); - vbh.projExeNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projExeNameOffset); - vbh.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projDescOffset); - vbh.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.helpFileOffset); - vbh.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbh.projNameOffset); - - if (!isLittleEndian()) - { - vbh.signature = byteSwap32(vbh.signature); - vbh.runtimeBuild = byteSwap16(vbh.runtimeBuild); - vbh.runtimeDLLVersion = byteSwap16(vbh.runtimeDLLVersion); - vbh.LCID1 = byteSwap32(vbh.LCID1); - vbh.LCID2 = byteSwap32(vbh.LCID2); - vbh.subMainAddr = byteSwap32(vbh.subMainAddr); - vbh.projectInfoAddr = byteSwap32(vbh.projectInfoAddr); - vbh.MDLIntObjsFlags = byteSwap32(vbh.MDLIntObjsFlags); - vbh.MDLIntObjsFlags2 = byteSwap32(vbh.MDLIntObjsFlags2); - vbh.threadFlags = byteSwap32(vbh.threadFlags); - vbh.nThreads = byteSwap32(vbh.nThreads); - vbh.nForms = byteSwap16(vbh.nForms); - vbh.nExternals = byteSwap16(vbh.nExternals); - vbh.nThunks = byteSwap32(vbh.nThunks); - vbh.GUITableAddr = byteSwap32(vbh.GUITableAddr); - vbh.externalTableAddr = byteSwap32(vbh.externalTableAddr); - vbh.COMRegisterDataAddr = byteSwap32(vbh.COMRegisterDataAddr); - vbh.projExeNameOffset = byteSwap32(vbh.projExeNameOffset); - vbh.projDescOffset = byteSwap32(vbh.projDescOffset); - vbh.helpFileOffset = byteSwap32(vbh.helpFileOffset); - vbh.projNameOffset = byteSwap32(vbh.projNameOffset); - } + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbh.signature = structContent.read(offset); offset += sizeof(vbh.signature); + vbh.runtimeBuild = structContent.read(offset); offset += sizeof(vbh.runtimeBuild); + std::memcpy(&vbh.languageDLL, static_cast(&bytes.data()[offset]), sizeof(vbh.languageDLL)); offset += sizeof(vbh.languageDLL); + std::memcpy(&vbh.backupLanguageDLL, static_cast(&bytes.data()[offset]), sizeof(vbh.backupLanguageDLL)); offset += sizeof(vbh.backupLanguageDLL); + vbh.runtimeDLLVersion = structContent.read(offset); offset += sizeof(vbh.runtimeDLLVersion); + vbh.LCID1 = structContent.read(offset); offset += sizeof(vbh.LCID1); + vbh.LCID2 = structContent.read(offset); offset += sizeof(vbh.LCID2); + vbh.subMainAddr = structContent.read(offset); offset += sizeof(vbh.subMainAddr); + vbh.projectInfoAddr = structContent.read(offset); offset += sizeof(vbh.projectInfoAddr); + vbh.MDLIntObjsFlags = structContent.read(offset); offset += sizeof(vbh.MDLIntObjsFlags); + vbh.MDLIntObjsFlags2 = structContent.read(offset); offset += sizeof(vbh.MDLIntObjsFlags2); + vbh.threadFlags = structContent.read(offset); offset += sizeof(vbh.threadFlags); + vbh.nThreads = structContent.read(offset); offset += sizeof(vbh.nThreads); + vbh.nForms = structContent.read(offset); offset += sizeof(vbh.nForms); + vbh.nExternals = structContent.read(offset); offset += sizeof(vbh.nExternals); + vbh.nThunks = structContent.read(offset); offset += sizeof(vbh.nThunks); + vbh.GUITableAddr = structContent.read(offset); offset += sizeof(vbh.GUITableAddr); + vbh.externalTableAddr = structContent.read(offset); offset += sizeof(vbh.externalTableAddr); + vbh.COMRegisterDataAddr = structContent.read(offset); offset += sizeof(vbh.COMRegisterDataAddr); + vbh.projExeNameOffset = structContent.read(offset); offset += sizeof(vbh.projExeNameOffset); + vbh.projDescOffset = structContent.read(offset); offset += sizeof(vbh.projDescOffset); + vbh.helpFileOffset = structContent.read(offset); offset += sizeof(vbh.helpFileOffset); + vbh.projNameOffset = structContent.read(offset); offset += sizeof(vbh.projNameOffset); if (vbh.signature != VBHEADER_SIGNATURE) { @@ -792,27 +769,16 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) return false; } - vbcrd.regInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.regInfoOffset); - vbcrd.projNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projNameOffset); - vbcrd.helpFileOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.helpFileOffset); - vbcrd.projDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projDescOffset); + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbcrd.regInfoOffset = structContent.read(offset); offset += sizeof(vbcrd.regInfoOffset); + vbcrd.projNameOffset = structContent.read(offset); offset += sizeof(vbcrd.projNameOffset); + vbcrd.helpFileOffset = structContent.read(offset); offset += sizeof(vbcrd.helpFileOffset); + vbcrd.projDescOffset = structContent.read(offset); offset += sizeof(vbcrd.projDescOffset); std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); - vbcrd.projTlbLCID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.projTlbLCID); - vbcrd.unknown = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.unknown); - vbcrd.tlbVerMajor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMajor); - vbcrd.tlbVerMinor = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcrd.tlbVerMinor); - - if (!isLittleEndian()) - { - vbcrd.regInfoOffset = byteSwap32(vbcrd.regInfoOffset); - vbcrd.projNameOffset = byteSwap32(vbcrd.projNameOffset); - vbcrd.helpFileOffset = byteSwap32(vbcrd.helpFileOffset); - vbcrd.projDescOffset = byteSwap32(vbcrd.projDescOffset); - vbcrd.projTlbLCID = byteSwap32(vbcrd.projTlbLCID); - vbcrd.unknown = byteSwap32(vbcrd.unknown); - vbcrd.tlbVerMajor = byteSwap32(vbcrd.tlbVerMajor); - vbcrd.tlbVerMinor = byteSwap32(vbcrd.tlbVerMinor); - } + vbcrd.projTlbLCID = structContent.read(offset); offset += sizeof(vbcrd.projTlbLCID); + vbcrd.unknown = structContent.read(offset); offset += sizeof(vbcrd.unknown); + vbcrd.tlbVerMajor = structContent.read(offset); offset += sizeof(vbcrd.tlbVerMajor); + vbcrd.tlbVerMinor = structContent.read(offset); offset += sizeof(vbcrd.tlbVerMinor); visualBasicInfo.setTypeLibLCID(vbcrd.projTlbLCID); visualBasicInfo.setTypeLibMajorVersion(vbcrd.tlbVerMajor); @@ -865,41 +831,24 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, return false; } - vbcri.ifInfoOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.ifInfoOffset); - vbcri.objNameOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objNameOffset); - vbcri.objDescOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objDescOffset); - vbcri.instancing = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.instancing); - vbcri.objID = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objID); + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbcri.ifInfoOffset = structContent.read(offset); offset += sizeof(vbcri.ifInfoOffset); + vbcri.objNameOffset = structContent.read(offset); offset += sizeof(vbcri.objNameOffset); + vbcri.objDescOffset = structContent.read(offset); offset += sizeof(vbcri.objDescOffset); + vbcri.instancing = structContent.read(offset); offset += sizeof(vbcri.instancing); + vbcri.objID = structContent.read(offset); offset += sizeof(vbcri.objID); std::memcpy(&vbcri.objCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcri.objCLSID)); offset += sizeof(vbcri.objCLSID); - vbcri.isInterfaceFlag = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.isInterfaceFlag); - vbcri.ifCLSIDOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.ifCLSIDOffset); - vbcri.eventCLSIDOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.eventCLSIDOffset); - vbcri.hasEvents = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.hasEvents); - vbcri.olemicsFlags = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.olemicsFlags); - vbcri.classType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.classType); - vbcri.objectType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.objectType); - vbcri.toolboxBitmap32 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.toolboxBitmap32); - vbcri.defaultIcon = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.defaultIcon); - vbcri.isDesignerFlag = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.isDesignerFlag); - vbcri.designerDataOffset = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbcri.designerDataOffset); - - if (!isLittleEndian()) - { - vbcri.ifInfoOffset = byteSwap32(vbcri.ifInfoOffset); - vbcri.objNameOffset = byteSwap32(vbcri.objNameOffset); - vbcri.objDescOffset = byteSwap32(vbcri.objDescOffset); - vbcri.instancing = byteSwap32(vbcri.instancing); - vbcri.objID = byteSwap32(vbcri.objID); - vbcri.isInterfaceFlag = byteSwap32(vbcri.isInterfaceFlag); - vbcri.ifCLSIDOffset = byteSwap32(vbcri.ifCLSIDOffset); - vbcri.eventCLSIDOffset = byteSwap32(vbcri.eventCLSIDOffset); - vbcri.hasEvents = byteSwap32(vbcri.hasEvents); - vbcri.olemicsFlags = byteSwap32(vbcri.olemicsFlags); - vbcri.toolboxBitmap32 = byteSwap16(vbcri.toolboxBitmap32); - vbcri.defaultIcon = byteSwap16(vbcri.defaultIcon); - vbcri.isDesignerFlag = byteSwap16(vbcri.isDesignerFlag); - vbcri.designerDataOffset = byteSwap32(vbcri.designerDataOffset); - } + vbcri.isInterfaceFlag = structContent.read(offset); offset += sizeof(vbcri.isInterfaceFlag); + vbcri.ifCLSIDOffset = structContent.read(offset); offset += sizeof(vbcri.ifCLSIDOffset); + vbcri.eventCLSIDOffset = structContent.read(offset); offset += sizeof(vbcri.eventCLSIDOffset); + vbcri.hasEvents = structContent.read(offset); offset += sizeof(vbcri.hasEvents); + vbcri.olemicsFlags = structContent.read(offset); offset += sizeof(vbcri.olemicsFlags); + vbcri.classType = structContent.read(offset); offset += sizeof(vbcri.classType); + vbcri.objectType = structContent.read(offset); offset += sizeof(vbcri.objectType); + vbcri.toolboxBitmap32 = structContent.read(offset); offset += sizeof(vbcri.toolboxBitmap32); + vbcri.defaultIcon = structContent.read(offset); offset += sizeof(vbcri.defaultIcon); + vbcri.isDesignerFlag = structContent.read(offset); offset += sizeof(vbcri.isDesignerFlag); + vbcri.designerDataOffset = structContent.read(offset); offset += sizeof(vbcri.designerDataOffset); if (vbcri.objNameOffset != 0) { @@ -951,33 +900,19 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset) return false; } - vbpi.version = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.version); - vbpi.objectTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.objectTableAddr); - vbpi.null = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.null); - vbpi.codeStartAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.codeStartAddr); - vbpi.codeEndAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.codeEndAddr); - vbpi.dataSize = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.dataSize); - vbpi.threadSpaceAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.threadSpaceAddr); - vbpi.exHandlerAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.exHandlerAddr); - vbpi.nativeCodeAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.nativeCodeAddr); + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbpi.version = structContent.read(offset); offset += sizeof(vbpi.version); + vbpi.objectTableAddr = structContent.read(offset); offset += sizeof(vbpi.objectTableAddr); + vbpi.null = structContent.read(offset); offset += sizeof(vbpi.null); + vbpi.codeStartAddr = structContent.read(offset); offset += sizeof(vbpi.codeStartAddr); + vbpi.codeEndAddr = structContent.read(offset); offset += sizeof(vbpi.codeEndAddr); + vbpi.dataSize = structContent.read(offset); offset += sizeof(vbpi.dataSize); + vbpi.threadSpaceAddr = structContent.read(offset); offset += sizeof(vbpi.threadSpaceAddr); + vbpi.exHandlerAddr = structContent.read(offset); offset += sizeof(vbpi.exHandlerAddr); + vbpi.nativeCodeAddr = structContent.read(offset); offset += sizeof(vbpi.nativeCodeAddr); std::memcpy(&vbpi.pathInformation, reinterpret_cast(&bytes.data()[offset]), sizeof(vbpi.pathInformation)); offset += sizeof(vbpi.pathInformation); - vbpi.externalTableAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.externalTableAddr); - vbpi.nExternals = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpi.nExternals); - - if (!isLittleEndian()) - { - vbpi.version = byteSwap32(vbpi.version); - vbpi.objectTableAddr = byteSwap32(vbpi.objectTableAddr); - vbpi.null = byteSwap32(vbpi.null); - vbpi.codeStartAddr = byteSwap32(vbpi.codeStartAddr); - vbpi.codeEndAddr = byteSwap32(vbpi.codeEndAddr); - vbpi.dataSize = byteSwap32(vbpi.dataSize); - vbpi.threadSpaceAddr = byteSwap32(vbpi.threadSpaceAddr); - vbpi.exHandlerAddr = byteSwap32(vbpi.exHandlerAddr); - vbpi.nativeCodeAddr = byteSwap32(vbpi.nativeCodeAddr); - vbpi.externalTableAddr = byteSwap32(vbpi.externalTableAddr); - vbpi.nExternals = byteSwap32(vbpi.nExternals); - } + vbpi.externalTableAddr = structContent.read(offset); offset += sizeof(vbpi.externalTableAddr); + vbpi.nExternals = structContent.read(offset); offset += sizeof(vbpi.nExternals); projPath = retdec::utils::unicodeToAscii(vbpi.pathInformation, sizeof(vbpi.pathInformation)); visualBasicInfo.setProjectPath(projPath); @@ -1023,14 +958,9 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz } offset = 0; - entry.type = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entry.type); - entry.importDataAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entry.importDataAddr); - - if (!isLittleEndian()) - { - entry.type = byteSwap32(entry.type); - entry.importDataAddr = byteSwap32(entry.importDataAddr); - } + DynamicBuffer entryContent(bytes, retdec::utils::Endianness::LITTLE); + entry.type = entryContent.read(offset); offset += sizeof(entry.type); + entry.importDataAddr = entryContent.read(offset); offset += sizeof(entry.importDataAddr); if (entry.type != static_cast(VBExternTableEntryType::external)) { @@ -1049,14 +979,9 @@ bool PeFormat::parseVisualBasicExternTable(std::size_t structureOffset, std::siz } offset = 0; - entryData.moduleNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entryData.moduleNameAddr); - entryData.apiNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(entryData.apiNameAddr); - - if (!isLittleEndian()) - { - entryData.moduleNameAddr = byteSwap32(entryData.moduleNameAddr); - entryData.apiNameAddr = byteSwap32(entryData.apiNameAddr); - } + DynamicBuffer entryDataContent(bytes, retdec::utils::Endianness::LITTLE); + entryData.moduleNameAddr = entryDataContent.read(offset); offset += sizeof(entryData.moduleNameAddr); + entryData.apiNameAddr = entryDataContent.read(offset); offset += sizeof(entryData.apiNameAddr); unsigned long long moduleNameOffset; if (getOffsetFromAddress(moduleNameOffset, entryData.moduleNameAddr)) @@ -1106,49 +1031,27 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) return false; } - vbot.null1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.null1); - vbot.execCOMAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.execCOMAddr); - vbot.projecInfo2Addr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projecInfo2Addr); - vbot.reserved = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.reserved); - vbot.null2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.null2); - vbot.projectObjectAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projectObjectAddr); + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbot.null1 = structContent.read(offset); offset += sizeof(vbot.null1); + vbot.execCOMAddr = structContent.read(offset); offset += sizeof(vbot.execCOMAddr); + vbot.projecInfo2Addr = structContent.read(offset); offset += sizeof(vbot.projecInfo2Addr); + vbot.reserved = structContent.read(offset); offset += sizeof(vbot.reserved); + vbot.null2 = structContent.read(offset); offset += sizeof(vbot.null2); + vbot.projectObjectAddr = structContent.read(offset); offset += sizeof(vbot.projectObjectAddr); std::memcpy(&vbot.objectGUID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbot.objectGUID)); offset += sizeof(vbot.objectGUID); - vbot.flagsCompileState = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.flagsCompileState); - vbot.nObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nObjects); - vbot.nCompiledObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nCompiledObjects); - vbot.nUsedObjects = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.nUsedObjects); - vbot.objectDescriptorsAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.objectDescriptorsAddr); - vbot.IDE1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE1); - vbot.IDE2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE2); - vbot.IDE3 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE3); - vbot.projectNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.projectNameAddr); - vbot.LCID1 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.LCID1); - vbot.LCID2 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.LCID2); - vbot.IDE4 = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.IDE4); - vbot.templateVesion = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbot.templateVesion); - - if (!isLittleEndian()) - { - vbot.null1 = byteSwap32(vbot.null1); - vbot.execCOMAddr = byteSwap32(vbot.execCOMAddr); - vbot.projecInfo2Addr = byteSwap32(vbot.projecInfo2Addr); - vbot.reserved = byteSwap32(vbot.reserved); - vbot.null2 = byteSwap32(vbot.null2); - vbot.projectObjectAddr = byteSwap32(vbot.projectObjectAddr); - vbot.flagsCompileState = byteSwap16(vbot.flagsCompileState); - vbot.nObjects = byteSwap16(vbot.nObjects); - vbot.nCompiledObjects = byteSwap16(vbot.nCompiledObjects); - vbot.nUsedObjects = byteSwap16(vbot.nUsedObjects); - vbot.objectDescriptorsAddr = byteSwap32(vbot.objectDescriptorsAddr); - vbot.IDE1 = byteSwap32(vbot.IDE1); - vbot.IDE2 = byteSwap32(vbot.IDE2); - vbot.IDE3 = byteSwap32(vbot.IDE3); - vbot.projectNameAddr = byteSwap32(vbot.projectNameAddr); - vbot.LCID1 = byteSwap32(vbot.LCID1); - vbot.LCID2 = byteSwap32(vbot.LCID2); - vbot.IDE4 = byteSwap32(vbot.IDE4); - vbot.templateVesion = byteSwap32(vbot.templateVesion); - } + vbot.flagsCompileState = structContent.read(offset); offset += sizeof(vbot.flagsCompileState); + vbot.nObjects = structContent.read(offset); offset += sizeof(vbot.nObjects); + vbot.nCompiledObjects = structContent.read(offset); offset += sizeof(vbot.nCompiledObjects); + vbot.nUsedObjects = structContent.read(offset); offset += sizeof(vbot.nUsedObjects); + vbot.objectDescriptorsAddr = structContent.read(offset); offset += sizeof(vbot.objectDescriptorsAddr); + vbot.IDE1 = structContent.read(offset); offset += sizeof(vbot.IDE1); + vbot.IDE2 = structContent.read(offset); offset += sizeof(vbot.IDE2); + vbot.IDE3 = structContent.read(offset); offset += sizeof(vbot.IDE3); + vbot.projectNameAddr = structContent.read(offset); offset += sizeof(vbot.projectNameAddr); + vbot.LCID1 = structContent.read(offset); offset += sizeof(vbot.LCID1); + vbot.LCID2 = structContent.read(offset); offset += sizeof(vbot.LCID2); + vbot.IDE4 = structContent.read(offset); offset += sizeof(vbot.IDE4); + vbot.templateVesion = structContent.read(offset); offset += sizeof(vbot.templateVesion); visualBasicInfo.setProjectPrimaryLCID(vbot.LCID1); visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); @@ -1193,34 +1096,19 @@ bool PeFormat::parseVisualBasicObjects(std::size_t structureOffset, std::size_t } offset = 0; - vbpod.objectInfoAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectInfoAddr); - vbpod.reserved = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.reserved); - vbpod.publicBytesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.publicBytesAddr); - vbpod.staticBytesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.staticBytesAddr); - vbpod.modulePublicAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.modulePublicAddr); - vbpod.moduleStaticAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.moduleStaticAddr); - vbpod.objectNameAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectNameAddr); - vbpod.nMethods = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.nMethods); - vbpod.methodNamesAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.methodNamesAddr); - vbpod.staticVarsCopyAddr = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.staticVarsCopyAddr); - vbpod.objectType = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.objectType); - vbpod.null = *reinterpret_cast(&bytes.data()[offset]); offset += sizeof(vbpod.null); - - if (!isLittleEndian()) - { - vbpod.objectInfoAddr = byteSwap32(vbpod.objectInfoAddr); - vbpod.reserved = byteSwap32(vbpod.reserved); - vbpod.publicBytesAddr = byteSwap32(vbpod.publicBytesAddr); - vbpod.staticBytesAddr = byteSwap32(vbpod.staticBytesAddr); - vbpod.modulePublicAddr = byteSwap32(vbpod.modulePublicAddr); - vbpod.moduleStaticAddr = byteSwap32(vbpod.moduleStaticAddr); - vbpod.objectNameAddr = byteSwap32(vbpod.objectNameAddr); - vbpod.nMethods = byteSwap32(vbpod.nMethods); - vbpod.methodNamesAddr = byteSwap32(vbpod.methodNamesAddr); - vbpod.staticVarsCopyAddr = byteSwap32(vbpod.staticVarsCopyAddr); - vbpod.objectType = byteSwap32(vbpod.objectType); - vbpod.null = byteSwap32(vbpod.null); - } + DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); + vbpod.objectInfoAddr = structContent.read(offset); offset += sizeof(vbpod.objectInfoAddr); + vbpod.reserved = structContent.read(offset); offset += sizeof(vbpod.reserved); + vbpod.publicBytesAddr = structContent.read(offset); offset += sizeof(vbpod.publicBytesAddr); + vbpod.staticBytesAddr = structContent.read(offset); offset += sizeof(vbpod.staticBytesAddr); + vbpod.modulePublicAddr = structContent.read(offset); offset += sizeof(vbpod.modulePublicAddr); + vbpod.moduleStaticAddr = structContent.read(offset); offset += sizeof(vbpod.moduleStaticAddr); + vbpod.objectNameAddr = structContent.read(offset); offset += sizeof(vbpod.objectNameAddr); + vbpod.nMethods = structContent.read(offset); offset += sizeof(vbpod.nMethods); + vbpod.methodNamesAddr = structContent.read(offset); offset += sizeof(vbpod.methodNamesAddr); + vbpod.staticVarsCopyAddr = structContent.read(offset); offset += sizeof(vbpod.staticVarsCopyAddr); + vbpod.objectType = structContent.read(offset); offset += sizeof(vbpod.objectType); + vbpod.null = structContent.read(offset); offset += sizeof(vbpod.null); unsigned long long objectNameOffset; if (!getOffsetFromAddress(objectNameOffset, vbpod.objectNameAddr)) From a266aa73a2abee822a19bec04152025f3d72ea80 Mon Sep 17 00:00:00 2001 From: Jakub Pruzinec Date: Tue, 26 Feb 2019 10:23:49 +0100 Subject: [PATCH 33/33] header problems fixed --- include/retdec/unpacker/signature.h | 13 ++++---- src/fileformat/file_format/pe/pe_format.cpp | 8 ++--- src/unpacker/signature.cpp | 2 ++ src/unpackertool/plugins/mpress/mpress.h | 20 ++++++------ .../upx/decompressors/decompressor.cpp | 1 + .../plugins/upx/decompressors/decompressor.h | 31 +++++++++++-------- .../decompressor_direct_jump.cpp | 1 + .../decompressors/decompressor_direct_jump.h | 6 ++-- .../upx/decompressors/decompressor_lzma.cpp | 1 + .../upx/decompressors/decompressor_lzma.h | 27 +++++++++------- src/unpackertool/plugins/upx/unfilter.cpp | 1 + src/utils/string.cpp | 4 +-- 12 files changed, 64 insertions(+), 51 deletions(-) diff --git a/include/retdec/unpacker/signature.h b/include/retdec/unpacker/signature.h index 337e9596a..6be6f5c16 100644 --- a/include/retdec/unpacker/signature.h +++ b/include/retdec/unpacker/signature.h @@ -14,8 +14,6 @@ #include "retdec/loader/loader.h" #include "retdec/utils/dynamic_buffer.h" -using namespace retdec::utils; - namespace retdec { namespace unpacker { @@ -155,17 +153,18 @@ class Signature uint64_t getCaptureSize() const; bool match(const MatchSettings& settings, retdec::loader::Image* file) const; - bool match(const MatchSettings& settings, const DynamicBuffer& data) const; - bool match(const MatchSettings& settings, retdec::loader::Image* file, DynamicBuffer& captures) const; - bool match(const MatchSettings& settings, const DynamicBuffer& data, DynamicBuffer& captures) const; + bool match(const MatchSettings& settings, const retdec::utils::DynamicBuffer& data) const; + bool match(const MatchSettings& settings, retdec::loader::Image* file, retdec::utils::DynamicBuffer& capturedData) const; + bool match(const MatchSettings& settings, const retdec::utils::DynamicBuffer& data, + retdec::utils::DynamicBuffer& capturedData) const; Signature& operator =(const std::initializer_list& initList); private: Signature& operator =(const Signature&); - bool searchMatchImpl(const std::vector& bytesToMatch, uint64_t offset, uint64_t maxSearchDist, DynamicBuffer* captureBuffer) const; - int64_t matchImpl(const std::vector& bytesToMatch, uint64_t offset, DynamicBuffer* captureBuffer) const; + bool searchMatchImpl(const std::vector& bytesToMatch, uint64_t offset, uint64_t maxSearchDist, retdec::utils::DynamicBuffer* captureBuffer) const; + int64_t matchImpl(const std::vector& bytesToMatch, uint64_t offset, retdec::utils::DynamicBuffer* captureBuffer) const; std::vector _buffer; ///< Signature bytes buffer. }; diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 3f94b1a25..aa896415f 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -774,7 +774,7 @@ bool PeFormat::parseVisualBasicComRegistrationData(std::size_t structureOffset) vbcrd.projNameOffset = structContent.read(offset); offset += sizeof(vbcrd.projNameOffset); vbcrd.helpFileOffset = structContent.read(offset); offset += sizeof(vbcrd.helpFileOffset); vbcrd.projDescOffset = structContent.read(offset); offset += sizeof(vbcrd.projDescOffset); - std::memcpy(&vbcrd.projCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); + std::memcpy(&vbcrd.projCLSID, static_cast(&bytes.data()[offset]), sizeof(vbcrd.projCLSID)); offset += sizeof(vbcrd.projCLSID); vbcrd.projTlbLCID = structContent.read(offset); offset += sizeof(vbcrd.projTlbLCID); vbcrd.unknown = structContent.read(offset); offset += sizeof(vbcrd.unknown); vbcrd.tlbVerMajor = structContent.read(offset); offset += sizeof(vbcrd.tlbVerMajor); @@ -837,7 +837,7 @@ bool PeFormat::parseVisualBasicComRegistrationInfo(std::size_t structureOffset, vbcri.objDescOffset = structContent.read(offset); offset += sizeof(vbcri.objDescOffset); vbcri.instancing = structContent.read(offset); offset += sizeof(vbcri.instancing); vbcri.objID = structContent.read(offset); offset += sizeof(vbcri.objID); - std::memcpy(&vbcri.objCLSID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbcri.objCLSID)); offset += sizeof(vbcri.objCLSID); + std::memcpy(&vbcri.objCLSID, static_cast(&bytes.data()[offset]), sizeof(vbcri.objCLSID)); offset += sizeof(vbcri.objCLSID); vbcri.isInterfaceFlag = structContent.read(offset); offset += sizeof(vbcri.isInterfaceFlag); vbcri.ifCLSIDOffset = structContent.read(offset); offset += sizeof(vbcri.ifCLSIDOffset); vbcri.eventCLSIDOffset = structContent.read(offset); offset += sizeof(vbcri.eventCLSIDOffset); @@ -910,7 +910,7 @@ bool PeFormat::parseVisualBasicProjectInfo(std::size_t structureOffset) vbpi.threadSpaceAddr = structContent.read(offset); offset += sizeof(vbpi.threadSpaceAddr); vbpi.exHandlerAddr = structContent.read(offset); offset += sizeof(vbpi.exHandlerAddr); vbpi.nativeCodeAddr = structContent.read(offset); offset += sizeof(vbpi.nativeCodeAddr); - std::memcpy(&vbpi.pathInformation, reinterpret_cast(&bytes.data()[offset]), sizeof(vbpi.pathInformation)); offset += sizeof(vbpi.pathInformation); + std::memcpy(&vbpi.pathInformation, static_cast(&bytes.data()[offset]), sizeof(vbpi.pathInformation)); offset += sizeof(vbpi.pathInformation); vbpi.externalTableAddr = structContent.read(offset); offset += sizeof(vbpi.externalTableAddr); vbpi.nExternals = structContent.read(offset); offset += sizeof(vbpi.nExternals); @@ -1038,7 +1038,7 @@ bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) vbot.reserved = structContent.read(offset); offset += sizeof(vbot.reserved); vbot.null2 = structContent.read(offset); offset += sizeof(vbot.null2); vbot.projectObjectAddr = structContent.read(offset); offset += sizeof(vbot.projectObjectAddr); - std::memcpy(&vbot.objectGUID, reinterpret_cast(&bytes.data()[offset]), sizeof(vbot.objectGUID)); offset += sizeof(vbot.objectGUID); + std::memcpy(&vbot.objectGUID, static_cast(&bytes.data()[offset]), sizeof(vbot.objectGUID)); offset += sizeof(vbot.objectGUID); vbot.flagsCompileState = structContent.read(offset); offset += sizeof(vbot.flagsCompileState); vbot.nObjects = structContent.read(offset); offset += sizeof(vbot.nObjects); vbot.nCompiledObjects = structContent.read(offset); offset += sizeof(vbot.nCompiledObjects); diff --git a/src/unpacker/signature.cpp b/src/unpacker/signature.cpp index 17a1e0093..c2a7bd542 100644 --- a/src/unpacker/signature.cpp +++ b/src/unpacker/signature.cpp @@ -8,6 +8,8 @@ #include "retdec/unpacker/signature.h" +using namespace retdec::utils; + namespace retdec { namespace unpacker { diff --git a/src/unpackertool/plugins/mpress/mpress.h b/src/unpackertool/plugins/mpress/mpress.h index b26706bba..cbbe9767f 100644 --- a/src/unpackertool/plugins/mpress/mpress.h +++ b/src/unpackertool/plugins/mpress/mpress.h @@ -15,8 +15,6 @@ #define mpress_plugin plugin(retdec::unpackertool::mpress::MpressPlugin) -using namespace retdec::utils; - namespace retdec { namespace unpackertool { namespace mpress { @@ -76,17 +74,19 @@ class MpressPlugin : public Plugin virtual void cleanup() override; private: - bool decompressData(DynamicBuffer& compressedContent, DynamicBuffer& decompressedContent); - void decodeLzmaProperties(DynamicBuffer& compressedContent, std::uint8_t& pb, std::uint8_t& lp, std::uint8_t& lc); + bool decompressData(retdec::utils::DynamicBuffer& compressedContent, + retdec::utils::DynamicBuffer& decompressedContent); + void decodeLzmaProperties(retdec::utils::DynamicBuffer& compressedContent, std::uint8_t& pb, + std::uint8_t& lp, std::uint8_t& lc); std::uint32_t getFixStub(); - void fixJumpsAndCalls(DynamicBuffer& buffer); - void fixImportsAndEp(DynamicBuffer& buffer); - void offsetAnalysis(const DynamicBuffer& buffer); - void trailingBytesAnalysis(const DynamicBuffer& buffer); + void fixJumpsAndCalls(retdec::utils::DynamicBuffer& buffer); + void fixImportsAndEp(retdec::utils::DynamicBuffer& buffer); + void offsetAnalysis(const retdec::utils::DynamicBuffer& buffer); + void trailingBytesAnalysis(const retdec::utils::DynamicBuffer& buffer); void fixRelocations(); MpressUnpackerStub detectUnpackerStubVersion(); - MpressFixStub detectFixStubVersion(DynamicBuffer& unpackedContent); - void saveFile(const std::string& fileName, DynamicBuffer& content); + MpressFixStub detectFixStubVersion(retdec::utils::DynamicBuffer& unpackedContent); + void saveFile(const std::string& fileName, retdec::utils::DynamicBuffer& content); void copySectionFromOriginalFile(std::uint32_t origSectIndex, const std::string& newFileName, std::uint32_t newSectIndex); std::unique_ptr _file; diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor.cpp b/src/unpackertool/plugins/upx/decompressors/decompressor.cpp index 3207a68d9..edcc5cd02 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor.cpp +++ b/src/unpackertool/plugins/upx/decompressors/decompressor.cpp @@ -8,6 +8,7 @@ #include "unpackertool/plugins/upx/upx.h" #include "unpackertool/plugins/upx/upx_exceptions.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor.h b/src/unpackertool/plugins/upx/decompressors/decompressor.h index c2f9c9d88..dda247f8e 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor.h @@ -12,8 +12,6 @@ #include "retdec/unpacker/decompression/compressed_data.h" -using namespace retdec::utils; - namespace retdec { namespace unpackertool { @@ -33,29 +31,36 @@ class Decompressor virtual ~Decompressor(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; + virtual void decompress(ElfUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; + virtual void decompress(ElfUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; + virtual void decompress(MachOUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) = 0; + virtual void decompress(MachOUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) = 0; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) = 0; - virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) = 0; - virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) = 0; - virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) = 0; + virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& unpackingStub) = 0; + virtual void readPackedData(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, bool trustMetadata) = 0; + virtual void decompress(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData, bool trustMetadata) = 0; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) = 0; - virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) = 0; - virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) = 0; - virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) = 0; + virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& unpackingStub) = 0; + virtual void readPackedData(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, bool trustMetadata) = 0; + virtual void decompress(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData, bool trustMetadata) = 0; protected: - void performDecompression(const std::weak_ptr& compressedDataWptr, DynamicBuffer& unpackedData); + void performDecompression(const std::weak_ptr& compressedDataWptr, + retdec::utils::DynamicBuffer& unpackedData); }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.cpp b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.cpp index a4c864ce2..d71cdae97 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.cpp +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.cpp @@ -14,6 +14,7 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "unpackertool/plugins/upx/upx_stub_signatures.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h index afb673fc5..50374160e 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_direct_jump.h @@ -8,8 +8,6 @@ #include "unpackertool/plugins/upx/decompressors/decompressor_scrambler.h" -using namespace retdec::utils; - namespace retdec { namespace unpackertool { namespace upx { @@ -23,9 +21,9 @@ class DecompressorDirectJump : public DecompressorScrambler DecompressorDirectJump(); virtual ~DecompressorDirectJump(); - virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& unpackingStub) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& unpackingStub) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.cpp b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.cpp index 4a95248bb..05dfedf25 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.cpp +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.cpp @@ -14,6 +14,7 @@ #include "unpackertool/plugins/upx/upx_stub.h" #include "retdec/unpacker/decompression/lzma/lzma_data.h" +using namespace retdec::utils; using namespace retdec::unpacker; namespace retdec { diff --git a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h index 6d29652cb..38635fe64 100644 --- a/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h +++ b/src/unpackertool/plugins/upx/decompressors/decompressor_lzma.h @@ -8,7 +8,6 @@ #include "unpackertool/plugins/upx/decompressors/decompressor.h" -using namespace retdec::utils; namespace retdec { namespace unpackertool { @@ -24,26 +23,32 @@ class DecompressorLzma : public Decompressor virtual ~DecompressorLzma(); virtual void setupPackingMethod(ElfUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(ElfUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(ElfUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; + virtual void decompress(ElfUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(MachOUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void decompress(MachOUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData) override; + virtual void decompress(MachOUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData) override; virtual void setupPackingMethod(PeUpxStub<32>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<32>* stub, DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<32>* stub, DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<32>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<32>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData, bool trustMetadata) override; virtual void setupPackingMethod(PeUpxStub<64>* stub, std::uint8_t packingMethod) override; - virtual void readUnpackingStub(PeUpxStub<64>* stub, DynamicBuffer& unpackingStub) override; - virtual void readPackedData(PeUpxStub<64>* stub, DynamicBuffer& packedData, bool trustMetadata) override; - virtual void decompress(PeUpxStub<64>* stub, DynamicBuffer& packedData, DynamicBuffer& unpackedData, bool trustMetadata) override; + virtual void readUnpackingStub(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& unpackingStub) override; + virtual void readPackedData(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, bool trustMetadata) override; + virtual void decompress(PeUpxStub<64>* stub, retdec::utils::DynamicBuffer& packedData, + retdec::utils::DynamicBuffer& unpackedData, bool trustMetadata) override; }; } // namespace upx diff --git a/src/unpackertool/plugins/upx/unfilter.cpp b/src/unpackertool/plugins/upx/unfilter.cpp index 1a37b0eb5..15515176d 100644 --- a/src/unpackertool/plugins/upx/unfilter.cpp +++ b/src/unpackertool/plugins/upx/unfilter.cpp @@ -5,6 +5,7 @@ */ #include +#include #include "unpackertool/plugins/upx/unfilter.h" diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 227f832b4..eb5d5c9ce 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -49,7 +49,7 @@ bool isNonasciiChar(unsigned char c) { */ std::string replaceChars(const std::string &str, bool (* predicate)(unsigned char)) { std::stringstream result; - const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT - 1)) - 1; + const std::size_t maxC = (1 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; for (const auto &c : str) { if (predicate(c)) { const auto val = numToStr(c & maxC, std::hex); @@ -436,7 +436,7 @@ std::string unicodeToAscii(const std::uint8_t *bytes, std::size_t nBytes) } else { - const std::size_t maxC = (2 << (sizeof(std::string::value_type) * CHAR_BIT - 1)) - 1; + const std::size_t maxC = (1 << (sizeof(std::string::value_type) * CHAR_BIT)) - 1; const auto val1 = numToStr(bytes[i] & maxC, std::hex); const auto val2 = numToStr(bytes[i + 1] & maxC, std::hex); result << "\\x" << std::setw(2) << std::setfill('0') << val1;