summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/SCsub1
-rw-r--r--tools/pe_bliss/README84
-rw-r--r--tools/pe_bliss/SCsub5
-rw-r--r--tools/pe_bliss/entropy.cpp111
-rw-r--r--tools/pe_bliss/entropy.h51
-rw-r--r--tools/pe_bliss/file_version_info.cpp440
-rw-r--r--tools/pe_bliss/file_version_info.h199
-rw-r--r--tools/pe_bliss/message_table.cpp81
-rw-r--r--tools/pe_bliss/message_table.h56
-rw-r--r--tools/pe_bliss/pe_base.cpp1680
-rw-r--r--tools/pe_bliss/pe_base.h544
-rw-r--r--tools/pe_bliss/pe_bliss.h39
-rw-r--r--tools/pe_bliss/pe_bliss_godot.cpp118
-rw-r--r--tools/pe_bliss/pe_bliss_godot.h7
-rw-r--r--tools/pe_bliss/pe_bliss_resources.h36
-rw-r--r--tools/pe_bliss/pe_bound_import.cpp311
-rw-r--r--tools/pe_bliss/pe_bound_import.h108
-rw-r--r--tools/pe_bliss/pe_checksum.cpp103
-rw-r--r--tools/pe_bliss/pe_checksum.h30
-rw-r--r--tools/pe_bliss/pe_debug.cpp865
-rw-r--r--tools/pe_bliss/pe_debug.h324
-rw-r--r--tools/pe_bliss/pe_directory.cpp59
-rw-r--r--tools/pe_bliss/pe_directory.h50
-rw-r--r--tools/pe_bliss/pe_dotnet.cpp186
-rw-r--r--tools/pe_bliss/pe_dotnet.h97
-rw-r--r--tools/pe_bliss/pe_exception.cpp40
-rw-r--r--tools/pe_bliss/pe_exception.h130
-rw-r--r--tools/pe_bliss/pe_exception_directory.cpp177
-rw-r--r--tools/pe_bliss/pe_exception_directory.h88
-rw-r--r--tools/pe_bliss/pe_exports.cpp700
-rw-r--r--tools/pe_bliss/pe_exports.h184
-rw-r--r--tools/pe_bliss/pe_factory.cpp43
-rw-r--r--tools/pe_bliss/pe_factory.h39
-rw-r--r--tools/pe_bliss/pe_imports.cpp777
-rw-r--r--tools/pe_bliss/pe_imports.h208
-rw-r--r--tools/pe_bliss/pe_load_config.cpp557
-rw-r--r--tools/pe_bliss/pe_load_config.h184
-rw-r--r--tools/pe_bliss/pe_properties.cpp41
-rw-r--r--tools/pe_bliss/pe_properties.h236
-rw-r--r--tools/pe_bliss/pe_properties_generic.cpp645
-rw-r--r--tools/pe_bliss/pe_properties_generic.h277
-rw-r--r--tools/pe_bliss/pe_rebuilder.cpp214
-rw-r--r--tools/pe_bliss/pe_rebuilder.h40
-rw-r--r--tools/pe_bliss/pe_relocations.cpp320
-rw-r--r--tools/pe_bliss/pe_relocations.h122
-rw-r--r--tools/pe_bliss/pe_resource_manager.cpp286
-rw-r--r--tools/pe_bliss/pe_resource_manager.h113
-rw-r--r--tools/pe_bliss/pe_resource_viewer.cpp382
-rw-r--r--tools/pe_bliss/pe_resource_viewer.h153
-rw-r--r--tools/pe_bliss/pe_resources.cpp726
-rw-r--r--tools/pe_bliss/pe_resources.h245
-rw-r--r--tools/pe_bliss/pe_rich_data.cpp152
-rw-r--r--tools/pe_bliss/pe_rich_data.h58
-rw-r--r--tools/pe_bliss/pe_section.cpp303
-rw-r--r--tools/pe_bliss/pe_section.h158
-rw-r--r--tools/pe_bliss/pe_structures.h1028
-rw-r--r--tools/pe_bliss/pe_tls.cpp396
-rw-r--r--tools/pe_bliss/pe_tls.h122
-rw-r--r--tools/pe_bliss/resource_bitmap_reader.cpp86
-rw-r--r--tools/pe_bliss/resource_bitmap_reader.h50
-rw-r--r--tools/pe_bliss/resource_bitmap_writer.cpp75
-rw-r--r--tools/pe_bliss/resource_bitmap_writer.h47
-rw-r--r--tools/pe_bliss/resource_cursor_icon_reader.cpp521
-rw-r--r--tools/pe_bliss/resource_cursor_icon_reader.h84
-rw-r--r--tools/pe_bliss/resource_cursor_icon_writer.cpp447
-rw-r--r--tools/pe_bliss/resource_cursor_icon_writer.h94
-rw-r--r--tools/pe_bliss/resource_data_info.cpp48
-rw-r--r--tools/pe_bliss/resource_data_info.h48
-rw-r--r--tools/pe_bliss/resource_internal.h34
-rw-r--r--tools/pe_bliss/resource_message_list_reader.cpp131
-rw-r--r--tools/pe_bliss/resource_message_list_reader.h49
-rw-r--r--tools/pe_bliss/resource_string_table_reader.cpp109
-rw-r--r--tools/pe_bliss/resource_string_table_reader.h57
-rw-r--r--tools/pe_bliss/resource_version_info_reader.cpp311
-rw-r--r--tools/pe_bliss/resource_version_info_reader.h67
-rw-r--r--tools/pe_bliss/resource_version_info_writer.cpp283
-rw-r--r--tools/pe_bliss/resource_version_info_writer.h52
-rw-r--r--tools/pe_bliss/stdint_defs.h45
-rw-r--r--tools/pe_bliss/utils.cpp85
-rw-r--r--tools/pe_bliss/utils.h105
-rw-r--r--tools/pe_bliss/version_info_editor.cpp184
-rw-r--r--tools/pe_bliss/version_info_editor.h79
-rw-r--r--tools/pe_bliss/version_info_types.h38
-rw-r--r--tools/pe_bliss/version_info_viewer.cpp180
-rw-r--r--tools/pe_bliss/version_info_viewer.h89
85 files changed, 0 insertions, 18127 deletions
diff --git a/tools/SCsub b/tools/SCsub
index f046e9ad08..5613d8a6c9 100644
--- a/tools/SCsub
+++ b/tools/SCsub
@@ -11,7 +11,6 @@ if (env["tools"]!="no"):
SConscript('collada/SCsub');
SConscript('docdump/SCsub');
SConscript('freetype/SCsub');
- SConscript('pe_bliss/SCsub');
SConscript('doc/SCsub')
SConscript('pck/SCsub')
diff --git a/tools/pe_bliss/README b/tools/pe_bliss/README
deleted file mode 100644
index d5d1355444..0000000000
--- a/tools/pe_bliss/README
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-
-Открытая бесплатная библиотека для работы с PE-файлами PE Bliss.
-Бесплатна к использованию, модификации и распространению.
-Автор: DX
-(c) DX 2011-2012, kaimi.ru
-
-Совместимость: Windows, Linux
-
-Возможности:
-[+] Создание PE или PE+ файла с нуля
-[+] Чтение 32-разрядных и 64-разрядных PE-файлов (PE, PE+) и единообразная работа с ними
-[+] Пересборка 32-разрядных и 64-разрядных PE-файлов
-[+] Работа с директориями и заголовками
-[+] Конвертирование адресов
-[+] Чтение и редактирование секций PE-файла
-[+] Чтение и редактирование таблицы импортов
-[+] Чтение и редактирование таблицы экспортов
-[+] Чтение и редактирование таблиц релокаций
-[+] Чтение и редактирование ресурсов
-[+] Чтение и редактирование TLS
-[+] Чтение и редактирование конфигурации образа (image config)
-[+] Чтение базовой информации .NET
-[+] Чтение и редактирование информации о привязанном импорте
-[+] Чтение директории исключений (только PE+)
-[+] Чтение отладочной директории с расширенной информацией
-[+] Вычисление энтропии
-[+] Изменение файлового выравнивания
-[+] Изменение базового адреса загрузки
-[+] Работа с DOS Stub'ом и Rich overlay
-[+] Высокоуровневое чтение ресурсов: картинки, иконки, курсоры, информация о версии, строковые таблицы, таблицы сообщений
-[+] Высокоуровневое редактирование ресурсов: картинки, иконки, курсоры, информация о версии
-
-[English]
-Open a free library for working with PE-file PE Bliss.
-Free to use, modify, and distribute.
-Author: DX
-(c) DX 2011-2012, kaimi.ru
-Compatibility: Windows, Linux
-
-### Capabilities:
-[+] Creation of PE or PE + file from scratch
-[+] Reading the 32-bit and 64-bit PE-file (PE, PE +) and uniform working with them
-[+] Rebuild 32-bit and 64-bit PE-files
-[+] Working with the directors and titles
-[+] Converting addresses
-[+] Reading and editing sections of PE-file
-[+] Reading and editing the import table
-[+] Reading and editing tables exports
-[+] Reading and editing tables relocations
-[+] Reading and editing resources
-[+] Reading and editing TLS
-[+] Reading and editing the configuration of the image (image config)
-[+] Reading data base .NET
-[+] Reading and editing information about tethered import
-[+] Read the directory exceptions (only PE +)
-[+] Read debug directories with extended information
-[+] The calculation of entropy
-[+] Changing file alignment
-[+] Change the base load address
-[+] Support of DOS Stub'om and Rich overlay
-[+] High-level reading resources: images, icons, cursors, version information, string tables, message table
-[+] High-level editing resources: images, icons, cursors, version information \ No newline at end of file
diff --git a/tools/pe_bliss/SCsub b/tools/pe_bliss/SCsub
deleted file mode 100644
index 34524f10ef..0000000000
--- a/tools/pe_bliss/SCsub
+++ /dev/null
@@ -1,5 +0,0 @@
-Import('env')
-
-env.add_source_files(env.tool_sources,"*.cpp")
-
-Export('env')
diff --git a/tools/pe_bliss/entropy.cpp b/tools/pe_bliss/entropy.cpp
deleted file mode 100644
index acefa63e83..0000000000
--- a/tools/pe_bliss/entropy.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <cmath>
-#include "entropy.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Calculates entropy for PE image section
-double entropy_calculator::calculate_entropy(const section& s)
-{
- if(s.get_raw_data().empty()) //Don't count entropy for empty sections
- throw pe_exception("Section is empty", pe_exception::section_is_empty);
-
- return calculate_entropy(s.get_raw_data().data(), s.get_raw_data().length());
-}
-
-//Calculates entropy for istream (from current position of stream)
-double entropy_calculator::calculate_entropy(std::istream& file)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- if(file.bad())
- throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
- std::streamoff pos = file.tellg();
-
- std::streamoff length = pe_utils::get_file_size(file);
- length -= file.tellg();
-
- if(!length) //Don't calculate entropy for empty buffers
- throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
- //Count bytes
- for(std::streamoff i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(file.get())];
-
- file.seekg(pos);
-
- return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for data block
-double entropy_calculator::calculate_entropy(const char* data, size_t length)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- if(!length) //Don't calculate entropy for empty buffers
- throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
- //Count bytes
- for(size_t i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(data[i])];
-
- return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for this PE file (only section data)
-double entropy_calculator::calculate_entropy(const pe_base& pe)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- size_t total_data_length = 0;
-
- //Count bytes for each section
- for(section_list::const_iterator it = pe.get_image_sections().begin(); it != pe.get_image_sections().end(); ++it)
- {
- const std::string& data = (*it).get_raw_data();
- size_t length = data.length();
- total_data_length += length;
- for(size_t i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(data[i])];
- }
-
- return calculate_entropy(byte_count, total_data_length);
-}
-
-//Calculates entropy from bytes count
-double entropy_calculator::calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length)
-{
- double entropy = 0.; //Entropy result value
- //Calculate entropy
- for(uint32_t i = 0; i < 256; ++i)
- {
- double temp = static_cast<double>(byte_count[i]) / total_length;
- if(temp > 0.)
- entropy += std::abs(temp * (std::log(temp) * pe_utils::log_2));
- }
-
- return entropy;
-}
-}
diff --git a/tools/pe_bliss/entropy.h b/tools/pe_bliss/entropy.h
deleted file mode 100644
index 7d225a3e32..0000000000
--- a/tools/pe_bliss/entropy.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class entropy_calculator
-{
-public:
- //Calculates entropy for PE image section
- static double calculate_entropy(const section& s);
-
- //Calculates entropy for istream (from current position of stream)
- static double calculate_entropy(std::istream& file);
-
- //Calculates entropy for data block
- static double calculate_entropy(const char* data, size_t length);
-
- //Calculates entropy for this PE file (only section data)
- static double calculate_entropy(const pe_base& pe);
-
-private:
- entropy_calculator();
- entropy_calculator(const entropy_calculator&);
- entropy_calculator& operator=(const entropy_calculator&);
-
- //Calculates entropy from bytes count
- static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length);
-};
-}
diff --git a/tools/pe_bliss/file_version_info.cpp b/tools/pe_bliss/file_version_info.cpp
deleted file mode 100644
index 3f2ba454b4..0000000000
--- a/tools/pe_bliss/file_version_info.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "file_version_info.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Default constructor
-file_version_info::file_version_info()
- :file_version_ms_(0), file_version_ls_(0),
- product_version_ms_(0), product_version_ls_(0),
- file_flags_(0),
- file_os_(0),
- file_type_(0), file_subtype_(0),
- file_date_ms_(0), file_date_ls_(0)
-{}
-
-//Constructor from Windows fixed version info structure
-file_version_info::file_version_info(const vs_fixedfileinfo& info)
- :file_version_ms_(info.dwFileVersionMS), file_version_ls_(info.dwFileVersionLS),
- product_version_ms_(info.dwProductVersionMS), product_version_ls_(info.dwProductVersionLS),
- file_flags_(info.dwFileFlags),
- file_os_(info.dwFileOS),
- file_type_(info.dwFileType), file_subtype_(info.dwFileSubtype),
- file_date_ms_(info.dwFileDateMS), file_date_ls_(info.dwFileDateLS)
-{}
-
-//Returns true if file is debug-built
-bool file_version_info::is_debug() const
-{
- return file_flags_ & vs_ff_debug ? true : false;
-}
-
-//Returns true if file is release-built
-bool file_version_info::is_prerelease() const
-{
- return file_flags_ & vs_ff_prerelease ? true : false;
-}
-
-//Returns true if file is patched
-bool file_version_info::is_patched() const
-{
- return file_flags_ & vs_ff_patched ? true : false;
-}
-
-//Returns true if private build
-bool file_version_info::is_private_build() const
-{
- return file_flags_ & vs_ff_privatebuild ? true : false;
-}
-
-//Returns true if special build
-bool file_version_info::is_special_build() const
-{
- return file_flags_ & vs_ff_specialbuild ? true : false;
-}
-
-//Returns true if info inferred
-bool file_version_info::is_info_inferred() const
-{
- return file_flags_ & vs_ff_infoinferred ? true : false;
-}
-
-//Retuens file flags (raw DWORD)
-uint32_t file_version_info::get_file_flags() const
-{
- return file_flags_;
-}
-
-//Returns file version most significant DWORD
-uint32_t file_version_info::get_file_version_ms() const
-{
- return file_version_ms_;
-}
-
-//Returns file version least significant DWORD
-uint32_t file_version_info::get_file_version_ls() const
-{
- return file_version_ls_;
-}
-
-//Returns product version most significant DWORD
-uint32_t file_version_info::get_product_version_ms() const
-{
- return product_version_ms_;
-}
-
-//Returns product version least significant DWORD
-uint32_t file_version_info::get_product_version_ls() const
-{
- return product_version_ls_;
-}
-
-//Returns file OS type (raw DWORD)
-uint32_t file_version_info::get_file_os_raw() const
-{
- return file_os_;
-}
-
-//Returns file OS type
-file_version_info::file_os_type file_version_info::get_file_os() const
-{
- //Determine file operation system type
- switch(file_os_)
- {
- case vos_dos:
- return file_os_dos;
-
- case vos_os216:
- return file_os_os216;
-
- case vos_os232:
- return file_os_os232;
-
- case vos_nt:
- return file_os_nt;
-
- case vos_wince:
- return file_os_wince;
-
- case vos__windows16:
- return file_os_win16;
-
- case vos__pm16:
- return file_os_pm16;
-
- case vos__pm32:
- return file_os_pm32;
-
- case vos__windows32:
- return file_os_win32;
-
- case vos_dos_windows16:
- return file_os_dos_win16;
-
- case vos_dos_windows32:
- return file_os_dos_win32;
-
- case vos_os216_pm16:
- return file_os_os216_pm16;
-
- case vos_os232_pm32:
- return file_os_os232_pm32;
-
- case vos_nt_windows32:
- return file_os_nt_win32;
- }
-
- return file_os_unknown;
-}
-
-//Returns file type (raw DWORD)
-uint32_t file_version_info::get_file_type_raw() const
-{
- return file_type_;
-}
-
-//Returns file type
-file_version_info::file_type file_version_info::get_file_type() const
-{
- //Determine file type
- switch(file_type_)
- {
- case vft_app:
- return file_type_application;
-
- case vft_dll:
- return file_type_dll;
-
- case vft_drv:
- return file_type_driver;
-
- case vft_font:
- return file_type_font;
-
- case vft_vxd:
- return file_type_vxd;
-
- case vft_static_lib:
- return file_type_static_lib;
- }
-
- return file_type_unknown;
-}
-
-//Returns file subtype (usually non-zero for drivers and fonts)
-uint32_t file_version_info::get_file_subtype() const
-{
- return file_subtype_;
-}
-
-//Returns file date most significant DWORD
-uint32_t file_version_info::get_file_date_ms() const
-{
- return file_date_ms_;
-}
-
-//Returns file date least significant DWORD
-uint32_t file_version_info::get_file_date_ls() const
-{
- return file_date_ls_;
-}
-
-//Helper to set file flag
-void file_version_info::set_file_flag(uint32_t flag)
-{
- file_flags_ |= flag;
-}
-
-//Helper to clear file flag
-void file_version_info::clear_file_flag(uint32_t flag)
-{
- file_flags_ &= ~flag;
-}
-
-//Helper to set or clear file flag
-void file_version_info::set_file_flag(uint32_t flag, bool set_flag)
-{
- set_flag ? set_file_flag(flag) : clear_file_flag(flag);
-}
-
-//Sets if file is debug-built
-void file_version_info::set_debug(bool debug)
-{
- set_file_flag(vs_ff_debug, debug);
-}
-
-//Sets if file is prerelease
-void file_version_info::set_prerelease(bool prerelease)
-{
- set_file_flag(vs_ff_prerelease, prerelease);
-}
-
-//Sets if file is patched
-void file_version_info::set_patched(bool patched)
-{
- set_file_flag(vs_ff_patched, patched);
-}
-
-//Sets if private build
-void file_version_info::set_private_build(bool private_build)
-{
- set_file_flag(vs_ff_privatebuild, private_build);
-}
-
-//Sets if special build
-void file_version_info::set_special_build(bool special_build)
-{
- set_file_flag(vs_ff_specialbuild, special_build);
-}
-
-//Sets if info inferred
-void file_version_info::set_info_inferred(bool info_inferred)
-{
- set_file_flag(vs_ff_infoinferred, info_inferred);
-}
-
-//Sets flags (raw DWORD)
-void file_version_info::set_file_flags(uint32_t file_flags)
-{
- file_flags_ = file_flags;
-}
-
-//Sets file version most significant DWORD
-void file_version_info::set_file_version_ms(uint32_t file_version_ms)
-{
- file_version_ms_ = file_version_ms;
-}
-
-//Sets file version least significant DWORD
-void file_version_info::set_file_version_ls(uint32_t file_version_ls)
-{
- file_version_ls_ = file_version_ls;
-}
-
-//Sets product version most significant DWORD
-void file_version_info::set_product_version_ms(uint32_t product_version_ms)
-{
- product_version_ms_ = product_version_ms;
-}
-
-//Sets product version least significant DWORD
-void file_version_info::set_product_version_ls(uint32_t product_version_ls)
-{
- product_version_ls_ = product_version_ls;
-}
-
-//Sets file OS type (raw DWORD)
-void file_version_info::set_file_os_raw(uint32_t file_os)
-{
- file_os_ = file_os;
-}
-
-//Sets file OS type
-void file_version_info::set_file_os(file_os_type file_os)
-{
- //Determine file operation system type
- switch(file_os)
- {
- case file_os_dos:
- file_os_ = vos_dos;
- return;
-
- case file_os_os216:
- file_os_ = vos_os216;
- return;
-
- case file_os_os232:
- file_os_ = vos_os232;
- return;
-
- case file_os_nt:
- file_os_ = vos_nt;
- return;
-
- case file_os_wince:
- file_os_ = vos_wince;
- return;
-
- case file_os_win16:
- file_os_ = vos__windows16;
- return;
-
- case file_os_pm16:
- file_os_ = vos__pm16;
- return;
-
- case file_os_pm32:
- file_os_ = vos__pm32;
- return;
-
- case file_os_win32:
- file_os_ = vos__windows32;
- return;
-
- case file_os_dos_win16:
- file_os_ = vos_dos_windows16;
- return;
-
- case file_os_dos_win32:
- file_os_ = vos_dos_windows32;
- return;
-
- case file_os_os216_pm16:
- file_os_ = vos_os216_pm16;
- return;
-
- case file_os_os232_pm32:
- file_os_ = vos_os232_pm32;
- return;
-
- case file_os_nt_win32:
- file_os_ = vos_nt_windows32;
- return;
-
- default:
- return;
- }
-}
-
-//Sets file type (raw DWORD)
-void file_version_info::set_file_type_raw(uint32_t file_type)
-{
- file_type_ = file_type;
-}
-
-//Sets file type
-void file_version_info::set_file_type(file_type file_type)
-{
- //Determine file type
- switch(file_type)
- {
- case file_type_application:
- file_type_ = vft_app;
- return;
-
- case file_type_dll:
- file_type_ = vft_dll;
- return;
-
- case file_type_driver:
- file_type_ = vft_drv;
- return;
-
- case file_type_font:
- file_type_ = vft_font;
- return;
-
- case file_type_vxd:
- file_type_ = vft_vxd;
- return;
-
- case file_type_static_lib:
- file_type_ = vft_static_lib;
- return;
-
- default:
- return;
- }
-}
-
-//Sets file subtype (usually non-zero for drivers and fonts)
-void file_version_info::set_file_subtype(uint32_t file_subtype)
-{
- file_subtype_ = file_subtype;
-}
-
-//Sets file date most significant DWORD
-void file_version_info::set_file_date_ms(uint32_t file_date_ms)
-{
- file_date_ms_ = file_date_ms;
-}
-
-//Sets file date least significant DWORD
-void file_version_info::set_file_date_ls(uint32_t file_date_ls)
-{
- file_date_ls_ = file_date_ls;
-}
-}
diff --git a/tools/pe_bliss/file_version_info.h b/tools/pe_bliss/file_version_info.h
deleted file mode 100644
index d898351ba1..0000000000
--- a/tools/pe_bliss/file_version_info.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Structure representing fixed file version info
-class file_version_info
-{
-public:
- //Enumeration of file operating system types
- enum file_os_type
- {
- file_os_unknown,
- file_os_dos,
- file_os_os216,
- file_os_os232,
- file_os_nt,
- file_os_wince,
- file_os_win16,
- file_os_pm16,
- file_os_pm32,
- file_os_win32,
- file_os_dos_win16,
- file_os_dos_win32,
- file_os_os216_pm16,
- file_os_os232_pm32,
- file_os_nt_win32
- };
-
- //Enumeration of file types
- enum file_type
- {
- file_type_unknown,
- file_type_application,
- file_type_dll,
- file_type_driver,
- file_type_font,
- file_type_vxd,
- file_type_static_lib
- };
-
-public:
- //Default constructor
- file_version_info();
- //Constructor from Windows fixed version info structure
- explicit file_version_info(const pe_win::vs_fixedfileinfo& info);
-
-public: //Getters
- //Returns true if file is debug-built
- bool is_debug() const;
- //Returns true if file is prerelease
- bool is_prerelease() const;
- //Returns true if file is patched
- bool is_patched() const;
- //Returns true if private build
- bool is_private_build() const;
- //Returns true if special build
- bool is_special_build() const;
- //Returns true if info inferred
- bool is_info_inferred() const;
- //Retuens file flags (raw DWORD)
- uint32_t get_file_flags() const;
-
- //Returns file version most significant DWORD
- uint32_t get_file_version_ms() const;
- //Returns file version least significant DWORD
- uint32_t get_file_version_ls() const;
- //Returns product version most significant DWORD
- uint32_t get_product_version_ms() const;
- //Returns product version least significant DWORD
- uint32_t get_product_version_ls() const;
-
- //Returns file OS type (raw DWORD)
- uint32_t get_file_os_raw() const;
- //Returns file OS type
- file_os_type get_file_os() const;
-
- //Returns file type (raw DWORD)
- uint32_t get_file_type_raw() const;
- //Returns file type
- file_type get_file_type() const;
-
- //Returns file subtype (usually non-zero for drivers and fonts)
- uint32_t get_file_subtype() const;
-
- //Returns file date most significant DWORD
- uint32_t get_file_date_ms() const;
- //Returns file date least significant DWORD
- uint32_t get_file_date_ls() const;
-
- //Returns file version string
- template<typename T>
- const std::basic_string<T> get_file_version_string() const
- {
- return get_version_string<T>(file_version_ms_, file_version_ls_);
- }
-
- //Returns product version string
- template<typename T>
- const std::basic_string<T> get_product_version_string() const
- {
- return get_version_string<T>(product_version_ms_, product_version_ls_);
- }
-
-public: //Setters
- //Sets if file is debug-built
- void set_debug(bool debug);
- //Sets if file is prerelease
- void set_prerelease(bool prerelease);
- //Sets if file is patched
- void set_patched(bool patched);
- //Sets if private build
- void set_private_build(bool private_build);
- //Sets if special build
- void set_special_build(bool special_build);
- //Sets if info inferred
- void set_info_inferred(bool info_inferred);
- //Sets flags (raw DWORD)
- void set_file_flags(uint32_t file_flags);
-
- //Sets file version most significant DWORD
- void set_file_version_ms(uint32_t file_version_ms);
- //Sets file version least significant DWORD
- void set_file_version_ls(uint32_t file_version_ls);
- //Sets product version most significant DWORD
- void set_product_version_ms(uint32_t product_version_ms);
- //Sets product version least significant DWORD
- void set_product_version_ls(uint32_t product_version_ls);
-
- //Sets file OS type (raw DWORD)
- void set_file_os_raw(uint32_t file_os);
- //Sets file OS type
- void set_file_os(file_os_type file_os);
-
- //Sets file type (raw DWORD)
- void set_file_type_raw(uint32_t file_type);
- //Sets file type
- void set_file_type(file_type file_type);
-
- //Sets file subtype (usually non-zero for drivers and fonts)
- void set_file_subtype(uint32_t file_subtype);
-
- //Sets file date most significant DWORD
- void set_file_date_ms(uint32_t file_date_ms);
- //Sets file date least significant DWORD
- void set_file_date_ls(uint32_t file_date_ls);
-
-private:
- //Helper to convert version DWORDs to string
- template<typename T>
- static const std::basic_string<T> get_version_string(uint32_t ms, uint32_t ls)
- {
- std::basic_stringstream<T> ss;
- ss << (ms >> 16) << static_cast<T>(L'.')
- << (ms & 0xFFFF) << static_cast<T>(L'.')
- << (ls >> 16) << static_cast<T>(L'.')
- << (ls & 0xFFFF);
- return ss.str();
- }
-
- //Helper to set file flag
- void set_file_flag(uint32_t flag);
- //Helper to clear file flag
- void clear_file_flag(uint32_t flag);
- //Helper to set or clear file flag
- void set_file_flag(uint32_t flag, bool set_flag);
-
- uint32_t file_version_ms_, file_version_ls_,
- product_version_ms_, product_version_ls_;
- uint32_t file_flags_;
- uint32_t file_os_;
- uint32_t file_type_, file_subtype_;
- uint32_t file_date_ms_, file_date_ls_;
-};
-}
diff --git a/tools/pe_bliss/message_table.cpp b/tools/pe_bliss/message_table.cpp
deleted file mode 100644
index 909be5d494..0000000000
--- a/tools/pe_bliss/message_table.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "message_table.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Default constructor
-message_table_item::message_table_item()
- :unicode_(false)
-{}
-
-//Constructor from ANSI string
-message_table_item::message_table_item(const std::string& str)
- :unicode_(false), ansi_str_(str)
-{
- pe_utils::strip_nullbytes(ansi_str_);
-}
-
-//Constructor from UNICODE string
-message_table_item::message_table_item(const std::wstring& str)
- :unicode_(true), unicode_str_(str)
-{
- pe_utils::strip_nullbytes(unicode_str_);
-}
-
-//Returns true if contained string is unicode
-bool message_table_item::is_unicode() const
-{
- return unicode_;
-}
-
-//Returns ANSI string
-const std::string& message_table_item::get_ansi_string() const
-{
- return ansi_str_;
-}
-
-//Returns UNICODE string
-const std::wstring& message_table_item::get_unicode_string() const
-{
- return unicode_str_;
-}
-
-//Sets ANSI string (clears UNICODE one)
-void message_table_item::set_string(const std::string& str)
-{
- ansi_str_ = str;
- pe_utils::strip_nullbytes(ansi_str_);
- unicode_str_.clear();
- unicode_ = false;
-}
-
-//Sets UNICODE string (clears ANSI one)
-void message_table_item::set_string(const std::wstring& str)
-{
- unicode_str_ = str;
- pe_utils::strip_nullbytes(unicode_str_);
- ansi_str_.clear();
- unicode_ = true;
-}
-}
diff --git a/tools/pe_bliss/message_table.h b/tools/pe_bliss/message_table.h
deleted file mode 100644
index 5a3feb32c1..0000000000
--- a/tools/pe_bliss/message_table.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Structure representing message table string
-class message_table_item
-{
-public:
- //Default constructor
- message_table_item();
- //Constructors from ANSI and UNICODE strings
- explicit message_table_item(const std::string& str);
- explicit message_table_item(const std::wstring& str);
-
- //Returns true if string is UNICODE
- bool is_unicode() const;
- //Returns ANSI string
- const std::string& get_ansi_string() const;
- //Returns UNICODE string
- const std::wstring& get_unicode_string() const;
-
-public:
- //Sets ANSI or UNICODE string
- void set_string(const std::string& str);
- void set_string(const std::wstring& str);
-
-private:
- bool unicode_;
- std::string ansi_str_;
- std::wstring unicode_str_;
-};
-}
diff --git a/tools/pe_bliss/pe_base.cpp b/tools/pe_bliss/pe_base.cpp
deleted file mode 100644
index 97baa17cb3..0000000000
--- a/tools/pe_bliss/pe_base.cpp
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <algorithm>
-#include <cmath>
-#include <set>
-#include <string.h>
-#include "pe_exception.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor
-pe_base::pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data)
-{
- props_ = props.duplicate().release();
-
- //Save istream state
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
-
- try
- {
- file.exceptions(std::ios::goodbit);
- //Read DOS header, PE headers and section data
- read_dos_header(file);
- read_pe(file, read_debug_raw_data);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.seekg(old_offset);
- file.exceptions(state);
- file.clear();
- //Rethrow
- throw;
- }
-
- //Restore istream state
- file.seekg(old_offset);
- file.exceptions(state);
- file.clear();
-}
-
-pe_base::pe_base(const pe_properties& props, uint32_t section_alignment, bool dll, uint16_t subsystem)
-{
- props_ = props.duplicate().release();
- props_->create_pe(section_alignment, subsystem);
-
- has_overlay_ = false;
- memset(&dos_header_, 0, sizeof(dos_header_));
-
- dos_header_.e_magic = 0x5A4D; //"MZ"
- //Magic numbers from MSVC++ build
- dos_header_.e_maxalloc = 0xFFFF;
- dos_header_.e_cblp = 0x90;
- dos_header_.e_cp = 3;
- dos_header_.e_cparhdr = 4;
- dos_header_.e_sp = 0xB8;
- dos_header_.e_lfarlc = 64;
-
- set_characteristics(image_file_executable_image | image_file_relocs_stripped);
-
- if(get_pe_type() == pe_type_32)
- set_characteristics_flags(image_file_32bit_machine);
-
- if(dll)
- set_characteristics_flags(image_file_dll);
-
- set_subsystem_version(5, 1); //WinXP
- set_os_version(5, 1); //WinXP
-}
-
-pe_base::pe_base(const pe_base& pe)
- :dos_header_(pe.dos_header_),
- rich_overlay_(pe.rich_overlay_),
- sections_(pe.sections_),
- has_overlay_(pe.has_overlay_),
- full_headers_data_(pe.full_headers_data_),
- debug_data_(pe.debug_data_),
- props_(0)
-{
- props_ = pe.props_->duplicate().release();
-}
-
-pe_base& pe_base::operator=(const pe_base& pe)
-{
- dos_header_ = pe.dos_header_;
- rich_overlay_ = pe.rich_overlay_;
- sections_ = pe.sections_;
- has_overlay_ = pe.has_overlay_;
- full_headers_data_ = pe.full_headers_data_;
- debug_data_ = pe.debug_data_;
- delete props_;
- props_ = 0;
- props_ = pe.props_->duplicate().release();
-
- return *this;
-}
-
-pe_base::~pe_base()
-{
- delete props_;
-}
-
-//Returns dos header
-const image_dos_header& pe_base::get_dos_header() const
-{
- return dos_header_;
-}
-
-//Returns dos header
-image_dos_header& pe_base::get_dos_header()
-{
- return dos_header_;
-}
-
-//Returns PE headers start position (e_lfanew)
-int32_t pe_base::get_pe_header_start() const
-{
- return dos_header_.e_lfanew;
-}
-
-//Strips MSVC stub overlay
-void pe_base::strip_stub_overlay()
-{
- rich_overlay_.clear();
-}
-
-//Fills MSVC stub overlay with character c
-void pe_base::fill_stub_overlay(char c)
-{
- if(rich_overlay_.length())
- rich_overlay_.assign(rich_overlay_.length(), c);
-}
-
-//Sets stub MSVS overlay
-void pe_base::set_stub_overlay(const std::string& data)
-{
- rich_overlay_ = data;
-}
-
-//Returns stub overlay
-const std::string& pe_base::get_stub_overlay() const
-{
- return rich_overlay_;
-}
-
-//Realigns all sections
-void pe_base::realign_all_sections()
-{
- for(unsigned int i = 0; i < sections_.size(); i++)
- realign_section(i);
-}
-
-//Returns number of sections from PE header
-uint16_t pe_base::get_number_of_sections() const
-{
- return props_->get_number_of_sections();
-}
-
-//Updates number of sections in PE header
-uint16_t pe_base::update_number_of_sections()
-{
- uint16_t new_number = static_cast<uint16_t>(sections_.size());
- props_->set_number_of_sections(new_number);
- return new_number;
-}
-
-//Returns section alignment
-uint32_t pe_base::get_section_alignment() const
-{
- return props_->get_section_alignment();
-}
-
-//Returns image sections list
-section_list& pe_base::get_image_sections()
-{
- return sections_;
-}
-
-//Returns image sections list
-const section_list& pe_base::get_image_sections() const
-{
- return sections_;
-}
-
-//Realigns section by index
-void pe_base::realign_section(uint32_t index)
-{
- //Check index
- if(sections_.size() <= index)
- throw pe_exception("Section not found", pe_exception::section_not_found);
-
- //Get section iterator
- section_list::iterator it = sections_.begin() + index;
- section& s = *it;
-
- //Calculate, how many null bytes we have in the end of raw section data
- std::size_t strip = 0;
- for(std::size_t i = (*it).get_raw_data().length(); i >= 1; --i)
- {
- if(s.get_raw_data()[i - 1] == 0)
- strip++;
- else
- break;
- }
-
- if(it == sections_.end() - 1) //If we're realigning the last section
- {
- //We can strip ending null bytes
- s.set_size_of_raw_data(static_cast<uint32_t>(s.get_raw_data().length() - strip));
- s.get_raw_data().resize(s.get_raw_data().length() - strip, 0);
- }
- else
- {
- //Else just set size of raw data
- uint32_t raw_size_aligned = s.get_aligned_raw_size(get_file_alignment());
- s.set_size_of_raw_data(raw_size_aligned);
- s.get_raw_data().resize(raw_size_aligned, 0);
- }
-}
-
-//Returns file alignment
-uint32_t pe_base::get_file_alignment() const
-{
- return props_->get_file_alignment();
-}
-
-//Sets file alignment
-void pe_base::set_file_alignment(uint32_t alignment)
-{
- //Check alignment
- if(alignment < minimum_file_alignment)
- throw pe_exception("File alignment can't be less than 512", pe_exception::incorrect_file_alignment);
-
- if(!pe_utils::is_power_of_2(alignment))
- throw pe_exception("File alignment must be a power of 2", pe_exception::incorrect_file_alignment);
-
- if(alignment > get_section_alignment())
- throw pe_exception("File alignment must be <= section alignment", pe_exception::incorrect_file_alignment);
-
- //Set file alignment without any additional checks
- set_file_alignment_unchecked(alignment);
-}
-
-//Returns size of image
-uint32_t pe_base::get_size_of_image() const
-{
- return props_->get_size_of_image();
-}
-
-//Returns image entry point
-uint32_t pe_base::get_ep() const
-{
- return props_->get_ep();
-}
-
-//Sets image entry point (just a value of PE header)
-void pe_base::set_ep(uint32_t new_ep)
-{
- props_->set_ep(new_ep);
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-uint32_t pe_base::get_number_of_rvas_and_sizes() const
-{
- return props_->get_number_of_rvas_and_sizes();
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-void pe_base::set_number_of_rvas_and_sizes(uint32_t number)
-{
- props_->set_number_of_rvas_and_sizes(number);
-}
-
-//Returns PE characteristics
-uint16_t pe_base::get_characteristics() const
-{
- return props_->get_characteristics();
-}
-
-//Sets PE characteristics (a value inside header)
-void pe_base::set_characteristics(uint16_t ch)
-{
- props_->set_characteristics(ch);
-}
-
-//Returns section from RVA
-section& pe_base::section_from_rva(uint32_t rva)
-{
- //Search for section
- for(section_list::iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- section& s = *i;
- //Return section if found
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return s;
- }
-
- throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from RVA
-const section& pe_base::section_from_rva(uint32_t rva) const
-{
- //Search for section
- for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- const section& s = *i;
- //Return section if found
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return s;
- }
-
- throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from directory ID
-section& pe_base::section_from_directory(uint32_t directory_id)
-{
- return section_from_rva(get_directory_rva(directory_id));
-}
-
-//Returns section from directory ID
-const section& pe_base::section_from_directory(uint32_t directory_id) const
-{
- return section_from_rva(get_directory_rva(directory_id));
-}
-
-//Sets section virtual size (actual for the last one of this PE or for unbound section)
-void pe_base::set_section_virtual_size(section& s, uint32_t vsize)
-{
- //Check if we're changing virtual size of the last section
- //Of course, we can change virtual size of section that's not bound to this PE file
- if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
- throw pe_exception("Can't change virtual size of any section, except last one", pe_exception::error_changing_section_virtual_size);
-
- //If we're setting virtual size to zero
- if(vsize == 0)
- {
- //Check if section is empty
- if(s.empty())
- throw pe_exception("Cannot set virtual size of empty section to zero", pe_exception::error_changing_section_virtual_size);
-
- //Set virtual size equal to aligned size of raw data
- s.set_virtual_size(s.get_size_of_raw_data());
- }
- else
- {
- s.set_virtual_size(vsize);
- }
-
- //Update image size if we're changing virtual size for the last section of this PE
- if(!sections_.empty() || &s == &(*(sections_.end() - 1)))
- update_image_size();
-}
-
-//Expands section raw or virtual size to hold data from specified RVA with specified size
-//Section must be free (not bound to any image)
-//or the last section of this image
-bool pe_base::expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand)
-{
- //Check if we're changing the last section
- //Of course, we can change the section that's not bound to this PE file
- if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
- throw pe_exception("Can't expand any section, except last one", pe_exception::error_expanding_section);
-
- //Check if we should expand our section
- if(expand == expand_section_raw && section_data_length_from_rva(s, needed_rva, section_data_raw) < needed_size)
- {
- //Expand section raw data
- s.get_raw_data().resize(needed_rva - s.get_virtual_address() + needed_size);
- recalculate_section_sizes(s, false);
- return true;
- }
- else if(expand == expand_section_virtual && section_data_length_from_rva(s, needed_rva, section_data_virtual) < needed_size)
- {
- //Expand section virtual data
- set_section_virtual_size(s, needed_rva - s.get_virtual_address() + needed_size);
- return true;
- }
-
- return false;
-}
-
-//Updates image virtual size
-void pe_base::update_image_size()
-{
- //Write virtual size of image to headers
- if(!sections_.empty())
- set_size_of_image(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()));
- else
- set_size_of_image(get_size_of_headers());
-}
-
-//Returns checksum of PE file from header
-uint32_t pe_base::get_checksum() const
-{
- return props_->get_checksum();
-}
-
-//Sets checksum of PE file
-void pe_base::set_checksum(uint32_t checksum)
-{
- props_->set_checksum(checksum);
-}
-
-//Returns timestamp of PE file from header
-uint32_t pe_base::get_time_date_stamp() const
-{
- return props_->get_time_date_stamp();
-}
-
-//Sets timestamp of PE file
-void pe_base::set_time_date_stamp(uint32_t timestamp)
-{
- props_->set_time_date_stamp(timestamp);
-}
-
-//Returns Machine field value of PE file from header
-uint16_t pe_base::get_machine() const
-{
- return props_->get_machine();
-}
-
-//Sets Machine field value of PE file
-void pe_base::set_machine(uint16_t machine)
-{
- props_->set_machine(machine);
-}
-
-//Prepares section before attaching it
-void pe_base::prepare_section(section& s)
-{
- //Calculate its size of raw data
- s.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(s.get_raw_data().length(), get_file_alignment())));
-
- //Check section virtual and raw size
- if(!s.get_size_of_raw_data() && !s.get_virtual_size())
- throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
- //If section virtual size is zero
- if(!s.get_virtual_size())
- {
- s.set_virtual_size(s.get_size_of_raw_data());
- }
- else
- {
- //Else calculate its virtual size
- s.set_virtual_size(
- std::max<uint32_t>(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()),
- pe_utils::align_up(s.get_virtual_size(), get_section_alignment())));
- }
-}
-
-//Adds section to image
-section& pe_base::add_section(section s)
-{
- if(sections_.size() >= maximum_number_of_sections)
- throw pe_exception("Maximum number of sections has been reached", pe_exception::no_more_sections_can_be_added);
-
- //Prepare section before adding it
- prepare_section(s);
-
- //Calculate section virtual address
- if(!sections_.empty())
- {
- s.set_virtual_address(pe_utils::align_up(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()), get_section_alignment()));
-
- //We should align last section raw size, if it wasn't aligned
- section& last = sections_.back();
- last.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(last.get_raw_data().length(), get_file_alignment())));
- }
- else
- {
- s.set_virtual_address(
- s.get_virtual_address() == 0
- ? pe_utils::align_up(get_size_of_headers(), get_section_alignment())
- : pe_utils::align_up(s.get_virtual_address(), get_section_alignment()));
- }
-
- //Add section to the end of section list
- sections_.push_back(s);
- //Set number of sections in PE header
- set_number_of_sections(static_cast<uint16_t>(sections_.size()));
- //Recalculate virtual size of image
- set_size_of_image(get_size_of_image() + s.get_aligned_virtual_size(get_section_alignment()));
- //Return last section
- return sections_.back();
-}
-
-//Returns true if sectios "s" is already attached to this PE file
-bool pe_base::section_attached(const section& s) const
-{
- return sections_.end() != std::find_if(sections_.begin(), sections_.end(), section_ptr_finder(s));
-}
-
-//Returns true if directory exists
-bool pe_base::directory_exists(uint32_t id) const
-{
- return props_->directory_exists(id);
-}
-
-//Removes directory
-void pe_base::remove_directory(uint32_t id)
-{
- props_->remove_directory(id);
-}
-
-//Returns directory RVA
-uint32_t pe_base::get_directory_rva(uint32_t id) const
-{
- return props_->get_directory_rva(id);
-}
-
-//Returns directory size
-uint32_t pe_base::get_directory_size(uint32_t id) const
-{
- return props_->get_directory_size(id);
-}
-
-//Sets directory RVA (just a value of PE header, no moving occurs)
-void pe_base::set_directory_rva(uint32_t id, uint32_t rva)
-{
- return props_->set_directory_rva(id, rva);
-}
-
-//Sets directory size (just a value of PE header, no moving occurs)
-void pe_base::set_directory_size(uint32_t id, uint32_t size)
-{
- return props_->set_directory_size(id, size);
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-uint32_t pe_base::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
- return props_->strip_data_directories(min_count, strip_iat_directory);
-}
-
-//Returns true if image has import directory
-bool pe_base::has_imports() const
-{
- return directory_exists(image_directory_entry_import);
-}
-
-//Returns true if image has export directory
-bool pe_base::has_exports() const
-{
- return directory_exists(image_directory_entry_export);
-}
-
-//Returns true if image has resource directory
-bool pe_base::has_resources() const
-{
- return directory_exists(image_directory_entry_resource);
-}
-
-//Returns true if image has security directory
-bool pe_base::has_security() const
-{
- return directory_exists(image_directory_entry_security);
-}
-
-//Returns true if image has relocations
-bool pe_base::has_reloc() const
-{
- return directory_exists(image_directory_entry_basereloc) && !(get_characteristics() & image_file_relocs_stripped);
-}
-
-//Returns true if image has TLS directory
-bool pe_base::has_tls() const
-{
- return directory_exists(image_directory_entry_tls);
-}
-
-//Returns true if image has config directory
-bool pe_base::has_config() const
-{
- return directory_exists(image_directory_entry_load_config);
-}
-
-//Returns true if image has bound import directory
-bool pe_base::has_bound_import() const
-{
- return directory_exists(image_directory_entry_bound_import);
-}
-
-//Returns true if image has delay import directory
-bool pe_base::has_delay_import() const
-{
- return directory_exists(image_directory_entry_delay_import);
-}
-
-//Returns true if image has COM directory
-bool pe_base::is_dotnet() const
-{
- return directory_exists(image_directory_entry_com_descriptor);
-}
-
-//Returns true if image has exception directory
-bool pe_base::has_exception_directory() const
-{
- return directory_exists(image_directory_entry_exception);
-}
-
-//Returns true if image has debug directory
-bool pe_base::has_debug() const
-{
- return directory_exists(image_directory_entry_debug);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-char* pe_base::section_data_from_rva(section& s, uint32_t rva)
-{
- //Check if RVA is inside section "s"
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- {
- if(s.get_raw_data().empty())
- throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
- return &s.get_raw_data()[rva - s.get_virtual_address()];
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-const char* pe_base::section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype) const
-{
- //Check if RVA is inside section "s"
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return static_cast<unsigned long>(full_headers_data_.length());
-
- const section& s = section_from_rva(rva);
- return static_cast<unsigned long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()));
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const
-{
- //if RVAs are inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length() && rva_inside < full_headers_data_.length())
- return static_cast<unsigned long>(full_headers_data_.length() - rva_inside);
-
- const section& s = section_from_rva(rva);
- if(rva_inside < s.get_virtual_address())
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-
- //Calculate remaining length of section data from "rva" address
- long length = static_cast<long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
- + s.get_virtual_address() - rva_inside;
-
- if(length < 0)
- return 0;
-
- return static_cast<unsigned long>(length);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-uint32_t pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype) const
-{
- //Check rva_inside
- if(rva_inside >= s.get_virtual_address() && rva_inside < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- {
- //Calculate remaining length of section data from "rva" address
- int32_t length = static_cast<int32_t>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
- + s.get_virtual_address() - rva_inside;
-
- if(length < 0)
- return 0;
-
- return static_cast<uint32_t>(length);
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const
-{
- return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32/PE64 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const
-{
- return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns corresponding section data pointer from RVA inside section
-char* pe_base::section_data_from_rva(uint32_t rva, bool include_headers)
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return &full_headers_data_[rva];
-
- section& s = section_from_rva(rva);
-
- if(s.get_raw_data().empty())
- throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
- return &s.get_raw_data()[rva - s.get_virtual_address()];
-}
-
-//Returns corresponding section data pointer from RVA inside section
-const char* pe_base::section_data_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return &full_headers_data_[rva];
-
- const section& s = section_from_rva(rva);
- return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file, image_dos_header& header)
-{
- //Check istream flags
- if(file.bad() || file.eof())
- throw pe_exception("PE file stream is bad or closed.", pe_exception::bad_pe_file);
-
- //Read DOS header and check istream
- file.read(reinterpret_cast<char*>(&header), sizeof(image_dos_header));
- if(file.bad() || file.eof())
- throw pe_exception("Unable to read IMAGE_DOS_HEADER", pe_exception::bad_dos_header);
-
- //Check DOS header magic
- if(header.e_magic != 0x5a4d) //"MZ"
- throw pe_exception("IMAGE_DOS_HEADER signature is incorrect", pe_exception::bad_dos_header);
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file)
-{
- read_dos_header(file, dos_header_);
-}
-
-//Reads PE image from istream
-void pe_base::read_pe(std::istream& file, bool read_debug_raw_data)
-{
- //Get istream size
- std::streamoff filesize = pe_utils::get_file_size(file);
-
- //Check if PE header is DWORD-aligned
- if((dos_header_.e_lfanew % sizeof(uint32_t)) != 0)
- throw pe_exception("PE header is not DWORD-aligned", pe_exception::bad_dos_header);
-
- //Seek to NT headers
- file.seekg(dos_header_.e_lfanew);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
- //Read NT headers
- file.read(get_nt_headers_ptr(), get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
- //Check PE signature
- if(get_pe_signature() != 0x4550) //"PE"
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check number of directories
- if(get_number_of_rvas_and_sizes() > image_numberof_directory_entries)
- set_number_of_rvas_and_sizes(image_numberof_directory_entries);
-
- if(get_number_of_rvas_and_sizes() > 0)
- {
- //Read data directory headers, if any
- file.read(get_nt_headers_ptr() + (get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries), sizeof(image_data_directory) * get_number_of_rvas_and_sizes());
- if(file.bad() || file.eof())
- throw pe_exception("Error reading DATA_DIRECTORY headers", pe_exception::error_reading_data_directories);
- }
-
- //Check section number
- //Images with zero section number accepted
- if(get_number_of_sections() > maximum_number_of_sections)
- throw pe_exception("Incorrect number of sections", pe_exception::section_number_incorrect);
-
- //Check PE magic
- if(get_magic() != get_needed_magic())
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check section alignment
- if(!pe_utils::is_power_of_2(get_section_alignment()))
- throw pe_exception("Incorrect section alignment", pe_exception::incorrect_section_alignment);
-
- //Check file alignment
- if(!pe_utils::is_power_of_2(get_file_alignment()))
- throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
- if(get_file_alignment() != get_section_alignment() && (get_file_alignment() < minimum_file_alignment || get_file_alignment() > get_section_alignment()))
- throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
- //Check size of image
- if(pe_utils::align_up(get_size_of_image(), get_section_alignment()) == 0)
- throw pe_exception("Incorrect size of image", pe_exception::incorrect_size_of_image);
-
- //Read rich data overlay / DOS stub (if any)
- if(static_cast<uint32_t>(dos_header_.e_lfanew) > sizeof(image_dos_header))
- {
- rich_overlay_.resize(dos_header_.e_lfanew - sizeof(image_dos_header));
- file.seekg(sizeof(image_dos_header));
- file.read(&rich_overlay_[0], dos_header_.e_lfanew - sizeof(image_dos_header));
- if(file.bad() || file.eof())
- throw pe_exception("Error reading 'Rich' & 'DOS stub' overlay", pe_exception::error_reading_overlay);
- }
-
- //Calculate first section raw position
- //Sum is safe here
- uint32_t first_section = dos_header_.e_lfanew + get_size_of_optional_header() + sizeof(image_file_header) + sizeof(uint32_t) /* Signature */;
-
- if(get_number_of_sections() > 0)
- {
- //Go to first section
- file.seekg(first_section);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach section headers", pe_exception::image_section_headers_not_found);
- }
-
- uint32_t last_raw_size = 0;
-
- //Read all sections
- for(int i = 0; i < get_number_of_sections(); i++)
- {
- section s;
- //Read section header
- file.read(reinterpret_cast<char*>(&s.get_raw_header()), sizeof(image_section_header));
- if(file.bad() || file.eof())
- throw pe_exception("Error reading section header", pe_exception::error_reading_section_header);
-
- //Save next section header position
- std::streamoff next_sect = file.tellg();
-
- //Check section virtual and raw sizes
- if(!s.get_size_of_raw_data() && !s.get_virtual_size())
- throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
- //Check for adequate values of section fields
- if(!pe_utils::is_sum_safe(s.get_virtual_address(), s.get_virtual_size()) || s.get_virtual_size() > pe_utils::two_gb
- || !pe_utils::is_sum_safe(s.get_pointer_to_raw_data(), s.get_size_of_raw_data()) || s.get_size_of_raw_data() > pe_utils::two_gb)
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- if(s.get_size_of_raw_data() != 0)
- {
- //If section has raw data
-
- //If section raw data size is greater than virtual, fix it
- last_raw_size = s.get_size_of_raw_data();
- if(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()) > pe_utils::align_up(s.get_virtual_size(), get_section_alignment()))
- s.set_size_of_raw_data(s.get_virtual_size());
-
- //Check virtual and raw section sizes and addresses
- if(s.get_virtual_address() + pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment())
- ||
- pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()) + s.get_size_of_raw_data() > static_cast<uint32_t>(filesize))
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- //Seek to section raw data
- file.seekg(pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()));
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach section data", pe_exception::image_section_data_not_found);
-
- //Read section raw data
- s.get_raw_data().resize(s.get_size_of_raw_data());
- file.read(&s.get_raw_data()[0], s.get_size_of_raw_data());
- if(file.bad() || file.fail())
- throw pe_exception("Error reading section data", pe_exception::image_section_data_not_found);
- }
-
- //Check virtual address and size of section
- if(s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment()))
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- //Save section
- sections_.push_back(s);
-
- //Seek to the next section header
- file.seekg(next_sect);
- }
-
- //Check size of headers: SizeOfHeaders can't be larger than first section VA
- if(!sections_.empty() && get_size_of_headers() > sections_.front().get_virtual_address())
- throw pe_exception("Incorrect size of headers", pe_exception::incorrect_size_of_headers);
-
- //If image has more than two sections
- if(sections_.size() >= 2)
- {
- //Check sections virtual sizes
- for(section_list::const_iterator i = sections_.begin() + 1; i != sections_.end(); ++i)
- {
- if((*i).get_virtual_address() != (*(i - 1)).get_virtual_address() + (*(i - 1)).get_aligned_virtual_size(get_section_alignment()))
- throw pe_exception("Section table is incorrect", pe_exception::image_section_table_incorrect);
- }
- }
-
- //Check if image has overlay in the end of file
- has_overlay_ = !sections_.empty() && filesize > static_cast<std::streamoff>(sections_.back().get_pointer_to_raw_data() + last_raw_size);
-
- {
- //Additionally, read data from the beginning of istream to size of headers
- file.seekg(0);
- uint32_t size_of_headers = std::min<uint32_t>(get_size_of_headers(), static_cast<uint32_t>(filesize));
-
- if(!sections_.empty())
- {
- for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- if(!(*i).empty())
- {
- size_of_headers = std::min<uint32_t>(get_size_of_headers(), (*i).get_pointer_to_raw_data());
- break;
- }
- }
- }
-
- full_headers_data_.resize(size_of_headers);
- file.read(&full_headers_data_[0], size_of_headers);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading file", pe_exception::error_reading_file);
- }
-
- //Moreover, if there's debug directory, read its raw data for some debug info types
- while(read_debug_raw_data && has_debug())
- {
- try
- {
- //Check the length in bytes of the section containing debug directory
- if(section_data_length_from_rva(get_directory_rva(image_directory_entry_debug), get_directory_rva(image_directory_entry_debug), section_data_virtual, true) < sizeof(image_debug_directory))
- break;
-
- unsigned long current_pos = get_directory_rva(image_directory_entry_debug);
-
- //First IMAGE_DEBUG_DIRECTORY table
- image_debug_directory directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
- //Iterate over all IMAGE_DEBUG_DIRECTORY directories
- while(directory.PointerToRawData
- && current_pos < get_directory_rva(image_directory_entry_debug) + get_directory_size(image_directory_entry_debug))
- {
- //If we have something to read
- if((directory.Type == image_debug_type_codeview
- || directory.Type == image_debug_type_misc
- || directory.Type == image_debug_type_coff)
- && directory.SizeOfData)
- {
- std::string data;
- data.resize(directory.SizeOfData);
- file.seekg(directory.PointerToRawData);
- file.read(&data[0], directory.SizeOfData);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading file", pe_exception::error_reading_file);
-
- debug_data_.insert(std::make_pair(directory.PointerToRawData, data));
- }
-
- //Go to next debug entry
- current_pos += sizeof(image_debug_directory);
- directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
- }
-
- break;
- }
- catch(const pe_exception&)
- {
- //Don't throw any exception here, if debug info is corrupted or incorrect
- break;
- }
- catch(const std::bad_alloc&)
- {
- //Don't throw any exception here, if debug info is corrupted or incorrect
- break;
- }
- }
-}
-
-//Returns PE type of this image
-pe_type pe_base::get_pe_type() const
-{
- return props_->get_pe_type();
-}
-
-//Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
-pe_type pe_base::get_pe_type(std::istream& file)
-{
- //Save state of the istream
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
- image_nt_headers32 nt_headers;
- image_dos_header header;
-
- try
- {
- //Read dos header
- file.exceptions(std::ios::goodbit);
- read_dos_header(file, header);
-
- //Seek to the NT headers start
- file.seekg(header.e_lfanew);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
- //Read NT headers (we're using 32-bit version, because there's no significant differencies between 32 and 64 bit version structures)
- file.read(reinterpret_cast<char*>(&nt_headers), sizeof(image_nt_headers32) - sizeof(image_data_directory) * image_numberof_directory_entries);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
- //Check NT headers signature
- if(nt_headers.Signature != 0x4550) //"PE"
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check NT headers magic
- if(nt_headers.OptionalHeader.Magic != image_nt_optional_hdr32_magic && nt_headers.OptionalHeader.Magic != image_nt_optional_hdr64_magic)
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
- //Retrhow exception
- throw;
- }
-
- //Restore stream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
-
- //Determine PE type and return it
- return nt_headers.OptionalHeader.Magic == image_nt_optional_hdr64_magic ? pe_type_64 : pe_type_32;
-}
-
-//Returns true if image has overlay data at the end of file
-bool pe_base::has_overlay() const
-{
- return has_overlay_;
-}
-
-//Clears PE characteristics flag
-void pe_base::clear_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_base::set_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() | flags);
-}
-
-//Returns true if PE characteristics flag set
-bool pe_base::check_characteristics_flag(uint16_t flag) const
-{
- return (get_characteristics() & flag) ? true : false;
-}
-
-//Returns subsystem value
-uint16_t pe_base::get_subsystem() const
-{
- return props_->get_subsystem();
-}
-
-//Sets subsystem value
-void pe_base::set_subsystem(uint16_t subsystem)
-{
- props_->set_subsystem(subsystem);
-}
-
-//Returns true if image has console subsystem
-bool pe_base::is_console() const
-{
- return get_subsystem() == image_subsystem_windows_cui;
-}
-
-//Returns true if image has Windows GUI subsystem
-bool pe_base::is_gui() const
-{
- return get_subsystem() == image_subsystem_windows_gui;
-}
-
-//Sets required operation system version
-void pe_base::set_os_version(uint16_t major, uint16_t minor)
-{
- props_->set_os_version(major, minor);
-}
-
-//Returns required operation system version (minor word)
-uint16_t pe_base::get_minor_os_version() const
-{
- return props_->get_minor_os_version();
-}
-
-//Returns required operation system version (major word)
-uint16_t pe_base::get_major_os_version() const
-{
- return props_->get_major_os_version();
-}
-
-//Sets required subsystem version
-void pe_base::set_subsystem_version(uint16_t major, uint16_t minor)
-{
- props_->set_subsystem_version(major, minor);
-}
-
-//Returns required subsystem version (minor word)
-uint16_t pe_base::get_minor_subsystem_version() const
-{
- return props_->get_minor_subsystem_version();
-}
-
-//Returns required subsystem version (major word)
-uint16_t pe_base::get_major_subsystem_version() const
-{
- return props_->get_major_subsystem_version();
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint32_t va) //Always returns raw data
-{
- return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint32_t va, section_data_type datatype) const
-{
- return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-char* pe_base::section_data_from_va(uint32_t va, bool include_headers) //Always returns raw data
-{
- return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-const char* pe_base::section_data_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint64_t va) //Always returns raw data
-{
- return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint64_t va, section_data_type datatype) const
-{
- return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-char* pe_base::section_data_from_va(uint64_t va, bool include_headers) //Always returns raw data
-{
- return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-const char* pe_base::section_data_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section from VA inside it for PE32
-section& pe_base::section_from_va(uint32_t va)
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from VA inside it for PE32/PE64
-section& pe_base::section_from_va(uint64_t va)
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32
-const section& pe_base::section_from_va(uint32_t va) const
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32/PE64
-const section& pe_base::section_from_va(uint64_t va) const
-{
- return section_from_rva(va_to_rva(va));
-}
-
-uint32_t pe_base::va_to_rva(uint32_t va, bool bound_check) const
-{
- return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::va_to_rva(uint64_t va, bool bound_check) const
-{
- return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::rva_to_va_32(uint32_t rva) const
-{
- return props_->rva_to_va_32(rva);
-}
-
-uint64_t pe_base::rva_to_va_64(uint32_t rva) const
-{
- return props_->rva_to_va_64(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertion for PE32
-void pe_base::rva_to_va(uint32_t rva, uint32_t& va) const
-{
- va = rva_to_va_32(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-void pe_base::rva_to_va(uint32_t rva, uint64_t& va) const
-{
- va = rva_to_va_64(rva);
-}
-
-//Returns section from file offset (4gb max)
-section& pe_base::section_from_file_offset(uint32_t offset)
-{
- return *file_offset_to_section(offset);
-}
-
-//Returns section from file offset (4gb max)
-const section& pe_base::section_from_file_offset(uint32_t offset) const
-{
- return *file_offset_to_section(offset);
-}
-
-//Returns section and offset (raw data only) from its start from RVA
-const std::pair<uint32_t, const section*> pe_base::section_and_offset_from_rva(uint32_t rva) const
-{
- const section& s = section_from_rva(rva);
- return std::make_pair(rva - s.get_virtual_address(), &s);
-}
-
-//Returns DLL Characteristics
-uint16_t pe_base::get_dll_characteristics() const
-{
- return props_->get_dll_characteristics();
-}
-
-//Sets DLL Characteristics
-void pe_base::set_dll_characteristics(uint16_t characteristics)
-{
- props_->set_dll_characteristics(characteristics);
-}
-
-//Returns size of headers
-uint32_t pe_base::get_size_of_headers() const
-{
- return props_->get_size_of_headers();
-}
-
-//Returns size of optional header
-uint16_t pe_base::get_size_of_optional_header() const
-{
- return props_->get_size_of_optional_header();
-}
-
-//Returns PE signature
-uint32_t pe_base::get_pe_signature() const
-{
- return props_->get_pe_signature();
-}
-
-//Returns magic value
-uint32_t pe_base::get_magic() const
-{
- return props_->get_magic();
-}
-
-//Returns image base for PE32
-void pe_base::get_image_base(uint32_t& base) const
-{
- base = get_image_base_32();
-}
-
-//Returns image base for PE32 and PE64 respectively
-uint32_t pe_base::get_image_base_32() const
-{
- return props_->get_image_base_32();
-}
-
-//Sets image base for PE32 and PE64 respectively
-uint64_t pe_base::get_image_base_64() const
-{
- return props_->get_image_base_64();
-}
-
-//RVA to RAW file offset convertion (4gb max)
-uint32_t pe_base::rva_to_file_offset(uint32_t rva) const
-{
- //Maybe, RVA is inside PE headers
- if(rva < get_size_of_headers())
- return rva;
-
- const section& s = section_from_rva(rva);
- return s.get_pointer_to_raw_data() + rva - s.get_virtual_address();
-}
-
-//RAW file offset to RVA convertion (4gb max)
-uint32_t pe_base::file_offset_to_rva(uint32_t offset) const
-{
- //Maybe, offset is inside PE headers
- if(offset < get_size_of_headers())
- return offset;
-
- const section_list::const_iterator it = file_offset_to_section(offset);
- return offset - (*it).get_pointer_to_raw_data() + (*it).get_virtual_address();
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::const_iterator pe_base::file_offset_to_section(uint32_t offset) const
-{
- section_list::const_iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
- if(it == sections_.end())
- throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-
- return it;
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::iterator pe_base::file_offset_to_section(uint32_t offset)
-{
- section_list::iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
- if(it == sections_.end())
- throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-
- return it;
-}
-
-//RVA from section raw data offset
-uint32_t pe_base::rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start)
-{
- return s.get_virtual_address() + raw_offset_from_section_start;
-}
-
-//Returns image base for PE32/PE64
-void pe_base::get_image_base(uint64_t& base) const
-{
- base = get_image_base_64();
-}
-
-//Sets new image base
-void pe_base::set_image_base(uint32_t base)
-{
- props_->set_image_base(base);
-}
-
-void pe_base::set_image_base_64(uint64_t base)
-{
- props_->set_image_base_64(base);
-}
-
-//Sets heap size commit for PE32 and PE64 respectively
-void pe_base::set_heap_size_commit(uint32_t size)
-{
- props_->set_heap_size_commit(size);
-}
-
-void pe_base::set_heap_size_commit(uint64_t size)
-{
- props_->set_heap_size_commit(size);
-}
-
-//Sets heap size reserve for PE32 and PE64 respectively
-void pe_base::set_heap_size_reserve(uint32_t size)
-{
- props_->set_heap_size_reserve(size);
-}
-
-void pe_base::set_heap_size_reserve(uint64_t size)
-{
- props_->set_heap_size_reserve(size);
-}
-
-//Sets stack size commit for PE32 and PE64 respectively
-void pe_base::set_stack_size_commit(uint32_t size)
-{
- props_->set_stack_size_commit(size);
-}
-
-void pe_base::set_stack_size_commit(uint64_t size)
-{
- props_->set_stack_size_commit(size);
-}
-
-//Sets stack size reserve for PE32 and PE64 respectively
-void pe_base::set_stack_size_reserve(uint32_t size)
-{
- props_->set_stack_size_reserve(size);
-}
-
-void pe_base::set_stack_size_reserve(uint64_t size)
-{
- props_->set_stack_size_reserve(size);
-}
-
-//Returns heap size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_commit_32() const
-{
- return props_->get_heap_size_commit_32();
-}
-
-uint64_t pe_base::get_heap_size_commit_64() const
-{
- return props_->get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_reserve_32() const
-{
- return props_->get_heap_size_reserve_32();
-}
-
-uint64_t pe_base::get_heap_size_reserve_64() const
-{
- return props_->get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_commit_32() const
-{
- return props_->get_stack_size_commit_32();
-}
-
-uint64_t pe_base::get_stack_size_commit_64() const
-{
- return props_->get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_reserve_32() const
-{
- return props_->get_stack_size_reserve_32();
-}
-
-uint64_t pe_base::get_stack_size_reserve_64() const
-{
- return props_->get_stack_size_reserve_64();
-}
-
-//Returns heap size commit for PE32
-void pe_base::get_heap_size_commit(uint32_t& size) const
-{
- size = get_heap_size_commit_32();
-}
-
-//Returns heap size commit for PE32/PE64
-void pe_base::get_heap_size_commit(uint64_t& size) const
-{
- size = get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32
-void pe_base::get_heap_size_reserve(uint32_t& size) const
-{
- size = get_heap_size_reserve_32();
-}
-
-//Returns heap size reserve for PE32/PE64
-void pe_base::get_heap_size_reserve(uint64_t& size) const
-{
- size = get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32
-void pe_base::get_stack_size_commit(uint32_t& size) const
-{
- size = get_stack_size_commit_32();
-}
-
-//Returns stack size commit for PE32/PE64
-void pe_base::get_stack_size_commit(uint64_t& size) const
-{
- size = get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32
-void pe_base::get_stack_size_reserve(uint32_t& size) const
-{
- size = get_stack_size_reserve_32();
-}
-
-//Returns stack size reserve for PE32/PE64
-void pe_base::get_stack_size_reserve(uint64_t& size) const
-{
- size = get_stack_size_reserve_64();
-}
-
-//Realigns file (changes file alignment)
-void pe_base::realign_file(uint32_t new_file_alignment)
-{
- //Checks alignment for correctness
- set_file_alignment(new_file_alignment);
- realign_all_sections();
-}
-
-//Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
-void pe_base::recalculate_section_sizes(section& s, bool auto_strip)
-{
- prepare_section(s); //Recalculate section raw addresses
-
- //Strip RAW size of section, if it is the last one
- //For all others it must be file-aligned and calculated by prepare_section() call
- if(auto_strip && !(sections_.empty() || &s == &*(sections_.end() - 1)))
- {
- //Strip ending raw data nullbytes to optimize size
- std::string& raw_data = s.get_raw_data();
- if(!raw_data.empty())
- {
- std::string::size_type i = raw_data.length();
- for(; i != 1; --i)
- {
- if(raw_data[i - 1] != 0)
- break;
- }
-
- raw_data.resize(i);
- }
-
- s.set_size_of_raw_data(static_cast<uint32_t>(raw_data.length()));
- }
-
- //Can occur only for last section
- if(pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) < pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()))
- set_section_virtual_size(s, pe_utils::align_up(s.get_size_of_raw_data(), get_section_alignment())); //Recalculate section virtual size
-}
-
-//Returns data from the beginning of image
-//Size = SizeOfHeaders
-const std::string& pe_base::get_full_headers_data() const
-{
- return full_headers_data_;
-}
-
-const pe_base::debug_data_list& pe_base::get_raw_debug_data_list() const
-{
- return debug_data_;
-}
-
-//Sets number of sections
-void pe_base::set_number_of_sections(uint16_t number)
-{
- props_->set_number_of_sections(number);
-}
-
-//Sets size of image
-void pe_base::set_size_of_image(uint32_t size)
-{
- props_->set_size_of_image(size);
-}
-
-//Sets size of headers
-void pe_base::set_size_of_headers(uint32_t size)
-{
- props_->set_size_of_headers(size);
-}
-
-//Sets size of optional headers
-void pe_base::set_size_of_optional_header(uint16_t size)
-{
- props_->set_size_of_optional_header(size);
-}
-
-//Returns nt headers data pointer
-char* pe_base::get_nt_headers_ptr()
-{
- return props_->get_nt_headers_ptr();
-}
-
-//Returns nt headers data pointer
-const char* pe_base::get_nt_headers_ptr() const
-{
- return props_->get_nt_headers_ptr();
-}
-
-//Returns sizeof() nt headers
-uint32_t pe_base::get_sizeof_nt_header() const
-{
- return props_->get_sizeof_nt_header();
-}
-
-//Returns sizeof() optional headers
-uint32_t pe_base::get_sizeof_opt_headers() const
-{
- return props_->get_sizeof_opt_headers();
-}
-
-//Sets file alignment (no checks)
-void pe_base::set_file_alignment_unchecked(uint32_t alignment)
-{
- props_->set_file_alignment_unchecked(alignment);
-}
-
-//Sets base of code
-void pe_base::set_base_of_code(uint32_t base)
-{
- props_->set_base_of_code(base);
-}
-
-//Returns base of code
-uint32_t pe_base::get_base_of_code() const
-{
- return props_->get_base_of_code();
-}
-
-//Returns needed magic of image
-uint32_t pe_base::get_needed_magic() const
-{
- return props_->get_needed_magic();
-}
-}
diff --git a/tools/pe_bliss/pe_base.h b/tools/pe_bliss/pe_base.h
deleted file mode 100644
index b5416cf1e2..0000000000
--- a/tools/pe_bliss/pe_base.h
+++ /dev/null
@@ -1,544 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <map>
-#include "pe_exception.h"
-#include "pe_structures.h"
-#include "utils.h"
-#include "pe_section.h"
-#include "pe_properties.h"
-
-//Please don't remove this information from header
-//PEBliss 1.0.0
-//(c) DX 2011 - 2012, http://kaimi.ru
-//Free to use for commertial and non-commertial purposes, modification and distribution
-
-// == more important ==
-//TODO: compact import rebuilder
-//TODO: remove sections in the middle
-//== less important ==
-//TODO: relocations that take more than one element (seems to be not possible in Windows PE, but anyway)
-//TODO: delay import directory
-//TODO: write message tables
-//TODO: write string tables
-//TODO: read security information
-//TODO: read full .NET information
-
-namespace pe_bliss
-{
-//Portable executable class
-class pe_base
-{
-public: //CONSTRUCTORS
- //Constructor from stream
- pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data = true);
-
- //Constructor of empty PE-file
- explicit pe_base(const pe_properties& props, uint32_t section_alignment = 0x1000, bool dll = false, uint16_t subsystem = pe_win::image_subsystem_windows_gui);
-
- pe_base(const pe_base& pe);
- pe_base& operator=(const pe_base& pe);
-
-public:
- ~pe_base();
-
-public: //STUB
- //Strips stub MSVS overlay, if any
- void strip_stub_overlay();
- //Fills stub MSVS overlay with specified byte
- void fill_stub_overlay(char c);
- //Sets stub MSVS overlay
- void set_stub_overlay(const std::string& data);
- //Returns stub overlay contents
- const std::string& get_stub_overlay() const;
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- bool directory_exists(uint32_t id) const;
- //Removes directory
- void remove_directory(uint32_t id);
-
- //Returns directory RVA
- uint32_t get_directory_rva(uint32_t id) const;
- //Returns directory size
- uint32_t get_directory_size(uint32_t id) const;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- void set_directory_rva(uint32_t id, uint32_t rva);
- //Sets directory size (just a value of PE header, no moving occurs)
- void set_directory_size(uint32_t id, uint32_t size);
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
- //Returns true if image has import directory
- bool has_imports() const;
- //Returns true if image has export directory
- bool has_exports() const;
- //Returns true if image has resource directory
- bool has_resources() const;
- //Returns true if image has security directory
- bool has_security() const;
- //Returns true if image has relocations
- bool has_reloc() const;
- //Returns true if image has TLS directory
- bool has_tls() const;
- //Returns true if image has config directory
- bool has_config() const;
- //Returns true if image has bound import directory
- bool has_bound_import() const;
- //Returns true if image has delay import directory
- bool has_delay_import() const;
- //Returns true if image has COM directory
- bool is_dotnet() const;
- //Returns true if image has exception directory
- bool has_exception_directory() const;
- //Returns true if image has debug directory
- bool has_debug() const;
-
- //Returns subsystem value
- uint16_t get_subsystem() const;
- //Sets subsystem value
- void set_subsystem(uint16_t subsystem);
- //Returns true if image has console subsystem
- bool is_console() const;
- //Returns true if image has Windows GUI subsystem
- bool is_gui() const;
-
- //Sets required operation system version
- void set_os_version(uint16_t major, uint16_t minor);
- //Returns required operation system version (minor word)
- uint16_t get_minor_os_version() const;
- //Returns required operation system version (major word)
- uint16_t get_major_os_version() const;
-
- //Sets required subsystem version
- void set_subsystem_version(uint16_t major, uint16_t minor);
- //Returns required subsystem version (minor word)
- uint16_t get_minor_subsystem_version() const;
- //Returns required subsystem version (major word)
- uint16_t get_major_subsystem_version() const;
-
-public: //PE HEADER
- //Returns DOS header
- const pe_win::image_dos_header& get_dos_header() const;
- pe_win::image_dos_header& get_dos_header();
-
- //Returns PE header start (e_lfanew)
- int32_t get_pe_header_start() const;
-
- //Returns file alignment
- uint32_t get_file_alignment() const;
- //Sets file alignment, checking the correctness of its value
- void set_file_alignment(uint32_t alignment);
-
- //Returns size of image
- uint32_t get_size_of_image() const;
-
- //Returns image entry point
- uint32_t get_ep() const;
- //Sets image entry point (just a value of PE header)
- void set_ep(uint32_t new_ep);
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- uint32_t get_number_of_rvas_and_sizes() const;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- void set_number_of_rvas_and_sizes(uint32_t number);
-
- //Returns PE characteristics
- uint16_t get_characteristics() const;
- //Sets PE characteristics (a value inside header)
- void set_characteristics(uint16_t ch);
- //Clears PE characteristics flag
- void clear_characteristics_flags(uint16_t flags);
- //Sets PE characteristics flag
- void set_characteristics_flags(uint16_t flags);
- //Returns true if PE characteristics flag set
- bool check_characteristics_flag(uint16_t flag) const;
-
- //Returns DLL Characteristics
- uint16_t get_dll_characteristics() const;
- //Sets DLL Characteristics
- void set_dll_characteristics(uint16_t characteristics);
-
- //Returns size of headers
- uint32_t get_size_of_headers() const;
- //Returns size of optional header
- uint16_t get_size_of_optional_header() const;
-
- //Returns PE signature
- uint32_t get_pe_signature() const;
-
- //Returns magic value
- uint32_t get_magic() const;
-
- //Returns image base for PE32 and PE64 respectively
- uint32_t get_image_base_32() const;
- void get_image_base(uint32_t& base) const;
- //Sets image base for PE32 and PE64 respectively
- uint64_t get_image_base_64() const;
- void get_image_base(uint64_t& base) const;
-
- //Sets new image base
- void set_image_base(uint32_t base);
- void set_image_base_64(uint64_t base);
-
- //Sets heap size commit for PE32 and PE64 respectively
- void set_heap_size_commit(uint32_t size);
- void set_heap_size_commit(uint64_t size);
- //Sets heap size reserve for PE32 and PE64 respectively
- void set_heap_size_reserve(uint32_t size);
- void set_heap_size_reserve(uint64_t size);
- //Sets stack size commit for PE32 and PE64 respectively
- void set_stack_size_commit(uint32_t size);
- void set_stack_size_commit(uint64_t size);
- //Sets stack size reserve for PE32 and PE64 respectively
- void set_stack_size_reserve(uint32_t size);
- void set_stack_size_reserve(uint64_t size);
-
- //Returns heap size commit for PE32 and PE64 respectively
- uint32_t get_heap_size_commit_32() const;
- void get_heap_size_commit(uint32_t& size) const;
- uint64_t get_heap_size_commit_64() const;
- void get_heap_size_commit(uint64_t& size) const;
- //Returns heap size reserve for PE32 and PE64 respectively
- uint32_t get_heap_size_reserve_32() const;
- void get_heap_size_reserve(uint32_t& size) const;
- uint64_t get_heap_size_reserve_64() const;
- void get_heap_size_reserve(uint64_t& size) const;
- //Returns stack size commit for PE32 and PE64 respectively
- uint32_t get_stack_size_commit_32() const;
- void get_stack_size_commit(uint32_t& size) const;
- uint64_t get_stack_size_commit_64() const;
- void get_stack_size_commit(uint64_t& size) const;
- //Returns stack size reserve for PE32 and PE64 respectively
- uint32_t get_stack_size_reserve_32() const;
- void get_stack_size_reserve(uint32_t& size) const;
- uint64_t get_stack_size_reserve_64() const;
- void get_stack_size_reserve(uint64_t& size) const;
-
- //Updates virtual size of image corresponding to section virtual sizes
- void update_image_size();
-
- //Returns checksum of PE file from header
- uint32_t get_checksum() const;
- //Sets checksum of PE file
- void set_checksum(uint32_t checksum);
-
- //Returns timestamp of PE file from header
- uint32_t get_time_date_stamp() const;
- //Sets timestamp of PE file
- void set_time_date_stamp(uint32_t timestamp);
-
- //Returns Machine field value of PE file from header
- uint16_t get_machine() const;
- //Sets Machine field value of PE file
- void set_machine(uint16_t machine);
-
- //Returns data from the beginning of image
- //Size = SizeOfHeaders
- const std::string& get_full_headers_data() const;
-
- typedef std::multimap<uint32_t, std::string> debug_data_list;
- //Returns raw list of debug data
- const debug_data_list& get_raw_debug_data_list() const;
-
- //Reads and checks DOS header
- static void read_dos_header(std::istream& file, pe_win::image_dos_header& header);
-
- //Returns sizeof() nt headers
- uint32_t get_sizeof_nt_header() const;
- //Returns sizeof() optional headers
- uint32_t get_sizeof_opt_headers() const;
- //Returns raw nt headers data pointer
- const char* get_nt_headers_ptr() const;
-
- //Sets size of headers (to NT headers)
- void set_size_of_headers(uint32_t size);
- //Sets size of optional headers (to NT headers)
- void set_size_of_optional_header(uint16_t size);
-
- //Sets base of code
- void set_base_of_code(uint32_t base);
- //Returns base of code
- uint32_t get_base_of_code() const;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
- uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- uint32_t rva_to_va_32(uint32_t rva) const;
- void rva_to_va(uint32_t rva, uint32_t& va) const;
- uint64_t rva_to_va_64(uint32_t rva) const;
- void rva_to_va(uint32_t rva, uint64_t& va) const;
-
- //RVA to RAW file offset convertion (4gb max)
- uint32_t rva_to_file_offset(uint32_t rva) const;
- //RAW file offset to RVA convertion (4gb max)
- uint32_t file_offset_to_rva(uint32_t offset) const;
-
- //RVA from section raw data offset
- static uint32_t rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start);
-
-public: //IMAGE SECTIONS
- //Returns number of sections from PE header
- uint16_t get_number_of_sections() const;
-
- //Updates number of sections in PE header
- uint16_t update_number_of_sections();
-
- //Returns section alignment
- uint32_t get_section_alignment() const;
-
- //Returns section list
- section_list& get_image_sections();
- const section_list& get_image_sections() const;
-
- //Realigns all sections, if you made any changes to sections or alignments
- void realign_all_sections();
- //Resligns section with specified index
- void realign_section(uint32_t index);
-
- //Returns section from RVA inside it
- section& section_from_rva(uint32_t rva);
- const section& section_from_rva(uint32_t rva) const;
- //Returns section from directory ID
- section& section_from_directory(uint32_t directory_id);
- const section& section_from_directory(uint32_t directory_id) const;
- //Returns section from VA inside it for PE32 and PE64 respectively
- section& section_from_va(uint32_t va);
- const section& section_from_va(uint32_t va) const;
- section& section_from_va(uint64_t va);
- const section& section_from_va(uint64_t va) const;
- //Returns section from file offset (4gb max)
- section& section_from_file_offset(uint32_t offset);
- const section& section_from_file_offset(uint32_t offset) const;
-
- //Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 and PE64 respectively
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- uint32_t section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
- uint32_t section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw) const;
- //Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 and PE64 respectively (checks bounds)
- uint32_t section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const;
- uint32_t section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const;
-
- //Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 and PE64 respectively
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- uint32_t section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- //Returns corresponding section data pointer from RVA inside section
- char* section_data_from_rva(uint32_t rva, bool include_headers = false);
- const char* section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns corresponding section data pointer from VA inside section for PE32 and PE64 respectively
- char* section_data_from_va(uint32_t va, bool include_headers = false);
- const char* section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- char* section_data_from_va(uint64_t va, bool include_headers = false);
- const char* section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
- char* section_data_from_rva(section& s, uint32_t rva);
- const char* section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const;
- //Returns corresponding section data pointer from VA inside section "s" for PE32 and PE64 respectively (checks bounds)
- char* section_data_from_va(section& s, uint32_t va); //Always returns raw data
- const char* section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const;
- char* section_data_from_va(section& s, uint64_t va); //Always returns raw data
- const char* section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const;
-
- //Returns corresponding section data pointer from RVA inside section "s" (checks bounds, checks sizes, the most safe function)
- template<typename T>
- T section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const
- {
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) && pe_utils::is_sum_safe(rva, sizeof(T)))
- {
- const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
- //Don't check for underflow here, comparsion is unsigned
- if(data.size() < rva - s.get_virtual_address() + sizeof(T))
- throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
- return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
- }
-
- //Returns corresponding section data pointer from RVA inside section (checks rva, checks sizes, the most safe function)
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- template<typename T>
- T section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && pe_utils::is_sum_safe(rva, sizeof(T)) && (rva + sizeof(T) < full_headers_data_.length()))
- return *reinterpret_cast<const T*>(&full_headers_data_[rva]);
-
- const section& s = section_from_rva(rva);
- const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
- //Don't check for underflow here, comparsion is unsigned
- if(data.size() < rva - s.get_virtual_address() + sizeof(T))
- throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
- return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
- }
-
- //Returns corresponding section data pointer from VA inside section "s" (checks bounds, checks sizes, the most safe function)
- template<typename T>
- T section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const
- {
- return section_data_from_rva<T>(s, va_to_rva(va), datatype);
- }
-
- template<typename T>
- T section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const
- {
- return section_data_from_rva<T>(s, va_to_rva(va), datatype);
- }
-
- //Returns corresponding section data pointer from VA inside section (checks rva, checks sizes, the most safe function)
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- template<typename T>
- T section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
- }
-
- template<typename T>
- T section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
- }
-
- //Returns section and offset (raw data only) from its start from RVA
- const std::pair<uint32_t, const section*> section_and_offset_from_rva(uint32_t rva) const;
-
- //Sets virtual size of section "s"
- //Section must be free (not bound to any image)
- //or the last section of this image
- //Function calls update_image_size automatically in second case
- void set_section_virtual_size(section& s, uint32_t vsize);
-
- //Represents section expand type for expand_section function
- enum section_expand_type
- {
- expand_section_raw, //Section raw data size will be expanded
- expand_section_virtual //Section virtual data size will be expanded
- };
-
- //Expands section raw or virtual size to hold data from specified RVA with specified size
- //Section must be free (not bound to any image)
- //or the last section of this image
- //Returns true if section was expanded
- bool expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand);
-
- //Adds section to image
- //Returns last section
- section& add_section(section s);
- //Prepares section to later add it to image (checks and recalculates virtual and raw section size)
- //Section must be prepared by this function before calling add_section
- void prepare_section(section& s);
-
- //Returns true if sectios "s" is already attached to this PE file
- bool section_attached(const section& s) const;
-
-
-public: //IMAGE
- //Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
- static pe_type get_pe_type(std::istream& file);
- //Returns PE type of this image
- pe_type get_pe_type() const;
-
- //Returns true if image has overlay data at the end of file
- bool has_overlay() const;
-
- //Realigns file (changes file alignment)
- void realign_file(uint32_t new_file_alignment);
-
- //Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
- //auto_strip = strip section, if necessary
- void recalculate_section_sizes(section& s, bool auto_strip);
-
- // ========== END OF PUBLIC MEMBERS AND STRUCTURES ========== //
-private:
- //Image DOS header
- pe_win::image_dos_header dos_header_;
- //Rich (stub) overlay data (for MSVS)
- std::string rich_overlay_;
- //List of image sections
- section_list sections_;
- //True if image has overlay
- bool has_overlay_;
- //Raw SizeOfHeaders-sized data from the beginning of image
- std::string full_headers_data_;
- //Raw debug data for all directories
- //PointerToRawData; Data
- debug_data_list debug_data_;
- //PE or PE+ related properties
- pe_properties* props_;
-
- //Reads and checks DOS header
- void read_dos_header(std::istream& file);
-
- //Reads and checks PE headers and section headers, data
- void read_pe(std::istream& file, bool read_debug_raw_data);
-
- //Sets number of sections
- void set_number_of_sections(uint16_t number);
- //Sets size of image
- void set_size_of_image(uint32_t size);
- //Sets file alignment (no checks)
- void set_file_alignment_unchecked(uint32_t alignment);
- //Returns needed magic of image
- uint32_t get_needed_magic() const;
- //Returns nt headers data pointer
- char* get_nt_headers_ptr();
-
-private:
- static const uint16_t maximum_number_of_sections = 0x60;
- static const uint32_t minimum_file_alignment = 512;
-
-private:
- //RAW file offset to section convertion helpers (4gb max)
- section_list::const_iterator file_offset_to_section(uint32_t offset) const;
- section_list::iterator file_offset_to_section(uint32_t offset);
-};
-}
diff --git a/tools/pe_bliss/pe_bliss.h b/tools/pe_bliss/pe_bliss.h
deleted file mode 100644
index 1a8b430284..0000000000
--- a/tools/pe_bliss/pe_bliss.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "pe_base.h"
-#include "pe_rebuilder.h"
-#include "pe_factory.h"
-#include "pe_bound_import.h"
-#include "pe_debug.h"
-#include "pe_dotnet.h"
-#include "pe_exception_directory.h"
-#include "pe_exports.h"
-#include "pe_imports.h"
-#include "pe_load_config.h"
-#include "pe_relocations.h"
-#include "pe_resources.h"
-#include "pe_rich_data.h"
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-#include "pe_checksum.h"
-#include "entropy.h"
diff --git a/tools/pe_bliss/pe_bliss_godot.cpp b/tools/pe_bliss/pe_bliss_godot.cpp
deleted file mode 100644
index 8297aa1045..0000000000
--- a/tools/pe_bliss/pe_bliss_godot.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "pe_bliss/pe_bliss.h"
-#include "pe_bliss/pe_bliss_resources.h"
-#include "core/ustring.h"
-#include "core/dvector.h"
-#include "os/file_access.h"
-
-using namespace pe_bliss;
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
- String& company_name, String& file_description,
- String& legal_copyright, String& version_text,
- String& product_name, String& godot_version,
- DVector<uint8_t>& icon_content) {
- try
- {
- pe_base image(pe_factory::create_pe(p_path));
-
- const section_list& pe_sections = image.get_image_sections();
- uint32_t end_of_pe = 0;
- FileAccess *dst;
- DVector<uint8_t> overlay_data;
- if(image.has_overlay())
- {
- end_of_pe = pe_sections.back().get_pointer_to_raw_data() + pe_sections.back().get_size_of_raw_data();
- dst=FileAccess::open(p_path,FileAccess::READ);
- if (dst) {
- overlay_data.resize(dst->get_len()-end_of_pe);
- dst->seek(end_of_pe);
- DVector<uint8_t>::Write overlay_data_write = overlay_data.write();
- dst->get_buffer(overlay_data_write.ptr(),overlay_data.size());
- dst->close();
- memdelete(dst);
- }
- }
- resource_directory root;
- if(image.has_resources())
- {
- root = resource_directory(get_resources(image));
- }
- pe_resource_manager res(root);
- if(image.has_resources())
- {
- if(icon_content.size()) {
- if(res.resource_exists(pe_resource_viewer::resource_icon))
- {
- res.remove_resource_type(pe_resource_viewer::resource_icon);
- }
- if(res.resource_exists(pe_resource_viewer::resource_icon_group))
- {
- res.remove_resource_type(pe_resource_viewer::resource_icon_group);
- }
- }
- if(res.resource_exists(pe_resource_viewer::resource_version))
- {
- res.remove_resource_type(pe_resource_viewer::resource_version);
- }
- }
- file_version_info file_info;
- file_info.set_file_os(file_version_info::file_os_nt_win32);
- file_info.set_file_type(file_version_info::file_type_application);
- unsigned int ver = version_major << 16;
- ver = ver + version_minor;
- file_info.set_file_version_ms(ver);
- file_info.set_file_version_ls(0x00000000);
- file_info.set_product_version_ms(ver);
- file_info.set_product_version_ls(0x00000000);
- lang_string_values_map strings;
- translation_values_map translations;
- version_info_editor version(strings, translations);
- version.add_translation(version_info_editor::default_language_translation);
- version.set_company_name(company_name.c_str());
- version.set_file_description(file_description.c_str());
- if (!product_name.empty()) {
- version.set_internal_name((product_name+String(".exe")).c_str());
- version.set_original_filename((product_name+String(".exe")).c_str());
- version.set_product_name(product_name.c_str());
- }
- version.set_legal_copyright(legal_copyright.c_str());
- version.set_product_version(version_text.c_str());
- if(!godot_version.empty()) version.set_property(L"Godot Engine Version", godot_version.c_str() );
- resource_version_info_writer(res).set_version_info(file_info, strings, translations, 1033, 1200);
- if(icon_content.size()) {
- std::string icon;
- icon.resize(icon_content.size());
- for(int i=0; i<icon_content.size(); i++)
- {
- icon[i] = icon_content[i];
- }
- resource_cursor_icon_writer(res).add_icon(icon, L"MAIN_ICON", 1033);
- }
- if(image.has_resources())
- {
- rebuild_resources(image, root, image.section_from_directory(pe_win::image_directory_entry_resource));
- } else {
- section new_resources;
- new_resources.get_raw_data().resize(1);
- new_resources.set_name(".rsrc");
- new_resources.readable(true);
- section& attached_section = image.add_section(new_resources);
- rebuild_resources(image, root, attached_section);
- }
- rebuild_pe(image, p_path);
- if(image.has_overlay() && end_of_pe) {
- dst=FileAccess::open(p_path,FileAccess::READ_WRITE);
- if (dst) {
- dst->seek_end();
- DVector<uint8_t>::Read overlay_data_read = overlay_data.read();
- dst->store_buffer(overlay_data_read.ptr(),overlay_data.size());
- dst->close();
- memdelete(dst);
- }
- }
- return String();
- } catch(const pe_exception& e) {
- String ret("Error In Add rsrc Section : ");
- return ret + String(e.what());
- }
-}
diff --git a/tools/pe_bliss/pe_bliss_godot.h b/tools/pe_bliss/pe_bliss_godot.h
deleted file mode 100644
index 0365ca9eaf..0000000000
--- a/tools/pe_bliss/pe_bliss_godot.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
- String& company_name, String& file_description,
- String& legal_copyright, String& version_text,
- String& product_name, String& godot_version,
- DVector<uint8_t>& icon_content);
diff --git a/tools/pe_bliss/pe_bliss_resources.h b/tools/pe_bliss/pe_bliss_resources.h
deleted file mode 100644
index 60369f8011..0000000000
--- a/tools/pe_bliss/pe_bliss_resources.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "file_version_info.h"
-#include "message_table.h"
-#include "pe_resource_manager.h"
-#include "pe_resource_viewer.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-#include "resource_bitmap_reader.h"
-#include "resource_bitmap_writer.h"
-#include "resource_cursor_icon_reader.h"
-#include "resource_cursor_icon_writer.h"
-#include "resource_version_info_reader.h"
-#include "resource_version_info_writer.h"
-#include "resource_string_table_reader.h"
-#include "resource_message_list_reader.h"
diff --git a/tools/pe_bliss/pe_bound_import.cpp b/tools/pe_bliss/pe_bound_import.cpp
deleted file mode 100644
index 4b54b36105..0000000000
--- a/tools/pe_bliss/pe_bound_import.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_bound_import.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//BOUND IMPORT
-//Default constructor
-bound_import_ref::bound_import_ref()
- :timestamp_(0)
-{}
-
-//Constructor from data
-bound_import_ref::bound_import_ref(const std::string& module_name, uint32_t timestamp)
- :module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import_ref::get_module_name() const
-{
- return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import_ref::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Sets module name
-void bound_import_ref::set_module_name(const std::string& module_name)
-{
- module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import_ref::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Default constructor
-bound_import::bound_import()
- :timestamp_(0)
-{}
-
-//Constructor from data
-bound_import::bound_import(const std::string& module_name, uint32_t timestamp)
- :module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import::get_module_name() const
-{
- return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns bound references cound
-size_t bound_import::get_module_ref_count() const
-{
- return refs_.size();
-}
-
-//Returns module references
-const bound_import::ref_list& bound_import::get_module_ref_list() const
-{
- return refs_;
-}
-
-//Adds module reference
-void bound_import::add_module_ref(const bound_import_ref& ref)
-{
- refs_.push_back(ref);
-}
-
-//Clears module references list
-void bound_import::clear_module_refs()
-{
- refs_.clear();
-}
-
-//Returns module references
-bound_import::ref_list& bound_import::get_module_ref_list()
-{
- return refs_;
-}
-
-//Sets module name
-void bound_import::set_module_name(const std::string& module_name)
-{
- module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe)
-{
- //Returned bound import modules list
- bound_import_module_list ret;
-
- //If image has no bound imports
- if(!pe.has_bound_import())
- return ret;
-
- uint32_t bound_import_data_len =
- pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
- if(bound_import_data_len < pe.get_directory_size(image_directory_entry_bound_import))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- const char* bound_import_data = pe.section_data_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
- //Check read in "read_pe" function raw bound import data size
- if(bound_import_data_len < sizeof(image_bound_import_descriptor))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //current bound_import_data_ in-string position
- unsigned long current_pos = 0;
- //first bound import descriptor
- //so, we're working with raw data here, no section helpers available
- const image_bound_import_descriptor* descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
- //Enumerate until zero
- while(descriptor->OffsetModuleName)
- {
- //Check module name offset
- if(descriptor->OffsetModuleName >= bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Check module name for null-termination
- if(!pe_utils::is_null_terminated(&bound_import_data[descriptor->OffsetModuleName], bound_import_data_len - descriptor->OffsetModuleName))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Create bound import descriptor structure
- bound_import elem(&bound_import_data[descriptor->OffsetModuleName], descriptor->TimeDateStamp);
-
- //Check DWORDs
- if(descriptor->NumberOfModuleForwarderRefs >= pe_utils::max_dword / sizeof(image_bound_forwarder_ref)
- || !pe_utils::is_sum_safe(current_pos, 2 /* this descriptor and the next one */ * sizeof(image_bound_import_descriptor) + descriptor->NumberOfModuleForwarderRefs * sizeof(image_bound_forwarder_ref)))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Move after current descriptor
- current_pos += sizeof(image_bound_import_descriptor);
-
- //Enumerate referenced bound import descriptors
- for(unsigned long i = 0; i != descriptor->NumberOfModuleForwarderRefs; ++i)
- {
- //They're just after parent descriptor
- //Check size of structure
- if(current_pos + sizeof(image_bound_forwarder_ref) > bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Get IMAGE_BOUND_FORWARDER_REF pointer
- const image_bound_forwarder_ref* ref_descriptor = reinterpret_cast<const image_bound_forwarder_ref*>(&bound_import_data[current_pos]);
-
- //Check referenced module name
- if(ref_descriptor->OffsetModuleName >= bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //And its null-termination
- if(!pe_utils::is_null_terminated(&bound_import_data[ref_descriptor->OffsetModuleName], bound_import_data_len - ref_descriptor->OffsetModuleName))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Add referenced module to current bound import structure
- elem.add_module_ref(bound_import_ref(&bound_import_data[ref_descriptor->OffsetModuleName], ref_descriptor->TimeDateStamp));
-
- //Move after referenced bound import descriptor
- current_pos += sizeof(image_bound_forwarder_ref);
- }
-
- //Check structure size
- if(current_pos + sizeof(image_bound_import_descriptor) > bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Move to next bound import descriptor
- descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
- //Save created descriptor structure and references
- ret.push_back(elem);
- }
-
- //Return result
- return ret;
-}
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that exports_section is attached to this PE image
- if(!pe.section_attached(imports_section))
- throw pe_exception("Bound import section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
- uint32_t needed_size = sizeof(image_bound_import_descriptor) /* Ending null descriptor */;
- uint32_t needed_size_for_strings = 0;
-
- //Calculate needed size for bound import data
- for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- const bound_import& import = *it;
- needed_size += sizeof(image_bound_import_descriptor);
- needed_size_for_strings += static_cast<uint32_t>((*it).get_module_name().length()) + 1 /* nullbyte */;
-
- const bound_import::ref_list& refs = import.get_module_ref_list();
- for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
- {
- needed_size_for_strings += static_cast<uint32_t>((*ref_it).get_module_name().length()) + 1 /* nullbyte */;
- needed_size += sizeof(image_bound_forwarder_ref);
- }
- }
-
- needed_size += needed_size_for_strings;
-
- //Check if imports_section is last one. If it's not, check if there's enough place for bound import data
- if(&imports_section != &*(pe.get_image_sections().end() - 1) &&
- (imports_section.empty() || pe_utils::align_up(imports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
- throw pe_exception("Insufficient space for bound import directory", pe_exception::insufficient_space);
-
- std::string& raw_data = imports_section.get_raw_data();
-
- //This will be done only if imports_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + directory_pos)
- raw_data.resize(needed_size + directory_pos); //Expand section raw data
-
- uint32_t current_pos_for_structures = directory_pos;
- uint32_t current_pos_for_strings = current_pos_for_structures + needed_size - needed_size_for_strings;
-
- for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- const bound_import& import = *it;
- image_bound_import_descriptor descriptor;
- descriptor.NumberOfModuleForwarderRefs = static_cast<uint16_t>(import.get_module_ref_list().size());
- descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
- descriptor.TimeDateStamp = import.get_timestamp();
-
- memcpy(&raw_data[current_pos_for_structures], &descriptor, sizeof(descriptor));
- current_pos_for_structures += sizeof(descriptor);
-
- size_t length = import.get_module_name().length() + 1 /* nullbyte */;
- memcpy(&raw_data[current_pos_for_strings], import.get_module_name().c_str(), length);
- current_pos_for_strings += static_cast<uint32_t>(length);
-
- const bound_import::ref_list& refs = import.get_module_ref_list();
- for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
- {
- const bound_import_ref& ref = *ref_it;
- image_bound_forwarder_ref ref_descriptor = {0};
- ref_descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
- ref_descriptor.TimeDateStamp = ref.get_timestamp();
-
- memcpy(&raw_data[current_pos_for_structures], &ref_descriptor, sizeof(ref_descriptor));
- current_pos_for_structures += sizeof(ref_descriptor);
-
- length = ref.get_module_name().length() + 1 /* nullbyte */;
- memcpy(&raw_data[current_pos_for_strings], ref.get_module_name().c_str(), length);
- current_pos_for_strings += static_cast<uint32_t>(length);
- }
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(imports_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(imports_section, directory_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_bound_import, ret.get_rva());
- pe.set_directory_size(image_directory_entry_bound_import, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_bound_import.h b/tools/pe_bliss/pe_bound_import.h
deleted file mode 100644
index 667e28792e..0000000000
--- a/tools/pe_bliss/pe_bound_import.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing bound import reference
-class bound_import_ref
-{
-public:
- //Default constructor
- bound_import_ref();
- //Constructor from data
- bound_import_ref(const std::string& module_name, uint32_t timestamp);
-
- //Returns imported module name
- const std::string& get_module_name() const;
- //Returns bound import date and time stamp
- uint32_t get_timestamp() const;
-
-public: //Setters
- //Sets module name
- void set_module_name(const std::string& module_name);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
-private:
- std::string module_name_; //Imported module name
- uint32_t timestamp_; //Bound import timestamp
-};
-
-//Class representing image bound import information
-class bound_import
-{
-public:
- typedef std::vector<bound_import_ref> ref_list;
-
-public:
- //Default constructor
- bound_import();
- //Constructor from data
- bound_import(const std::string& module_name, uint32_t timestamp);
-
- //Returns imported module name
- const std::string& get_module_name() const;
- //Returns bound import date and time stamp
- uint32_t get_timestamp() const;
-
- //Returns bound references cound
- size_t get_module_ref_count() const;
- //Returns module references
- const ref_list& get_module_ref_list() const;
-
-public: //Setters
- //Sets module name
- void set_module_name(const std::string& module_name);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
- //Adds module reference
- void add_module_ref(const bound_import_ref& ref);
- //Clears module references list
- void clear_module_refs();
- //Returns module references
- ref_list& get_module_ref_list();
-
-private:
- std::string module_name_; //Imported module name
- uint32_t timestamp_; //Bound import timestamp
- ref_list refs_; //Module references list
-};
-
-typedef std::vector<bound_import> bound_import_module_list;
-
-//Returns bound import information
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe);//Export directory rebuilder
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_checksum.cpp b/tools/pe_bliss/pe_checksum.cpp
deleted file mode 100644
index 5971a33c90..0000000000
--- a/tools/pe_bliss/pe_checksum.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_checksum.h"
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Calculate checksum of image
-uint32_t calculate_checksum(std::istream& file)
-{
- //Save istream state
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
-
- //Checksum value
- unsigned long long checksum = 0;
-
- try
- {
- image_dos_header header;
-
- file.exceptions(std::ios::goodbit);
-
- //Read DOS header
- pe_base::read_dos_header(file, header);
-
- //Calculate PE checksum
- file.seekg(0);
- unsigned long long top = 0xFFFFFFFF;
- top++;
-
- //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
- static const unsigned long checksum_pos_in_optional_headers = 64;
- //Calculate real PE headers "CheckSum" field position
- //Sum is safe here
- unsigned long pe_checksum_pos = header.e_lfanew + sizeof(image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
-
- //Calculate checksum for each byte of file
- std::streamoff filesize = pe_utils::get_file_size(file);
- for(long long i = 0; i < filesize; i += 4)
- {
- unsigned long dw = 0;
-
- //Read DWORD from file
- file.read(reinterpret_cast<char*>(&dw), sizeof(unsigned long));
- //Skip "CheckSum" DWORD
- if(i == pe_checksum_pos)
- continue;
-
- //Calculate checksum
- checksum = (checksum & 0xffffffff) + dw + (checksum >> 32);
- if(checksum > top)
- checksum = (checksum & 0xffffffff) + (checksum >> 32);
- }
-
- //Finish checksum
- checksum = (checksum & 0xffff) + (checksum >> 16);
- checksum = (checksum) + (checksum >> 16);
- checksum = checksum & 0xffff;
-
- checksum += static_cast<unsigned long>(filesize);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
- //Rethrow
- throw;
- }
-
- //Restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
-
- //Return checksum
- return static_cast<uint32_t>(checksum);
-}
-}
diff --git a/tools/pe_bliss/pe_checksum.h b/tools/pe_bliss/pe_checksum.h
deleted file mode 100644
index a568d5d369..0000000000
--- a/tools/pe_bliss/pe_checksum.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Calculate checksum of image (performs no checks on PE structures)
-uint32_t calculate_checksum(std::istream& file);
-}
diff --git a/tools/pe_bliss/pe_debug.cpp b/tools/pe_bliss/pe_debug.cpp
deleted file mode 100644
index a0ed3f5af1..0000000000
--- a/tools/pe_bliss/pe_debug.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_debug.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-//DEBUG
-//Default constructor
-debug_info::debug_info()
- :characteristics_(0),
- time_stamp_(0),
- major_version_(0), minor_version_(0),
- type_(0),
- size_of_data_(0),
- address_of_raw_data_(0),
- pointer_to_raw_data_(0),
- advanced_info_type_(advanced_info_none)
-{}
-
-//Constructor from data
-debug_info::debug_info(const image_debug_directory& debug)
- :characteristics_(debug.Characteristics),
- time_stamp_(debug.TimeDateStamp),
- major_version_(debug.MajorVersion), minor_version_(debug.MinorVersion),
- type_(debug.Type),
- size_of_data_(debug.SizeOfData),
- address_of_raw_data_(debug.AddressOfRawData),
- pointer_to_raw_data_(debug.PointerToRawData),
- advanced_info_type_(advanced_info_none)
-{}
-
-//Returns debug characteristics
-uint32_t debug_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns debug datetimestamp
-uint32_t debug_info::get_time_stamp() const
-{
- return time_stamp_;
-}
-
-//Returns major version
-uint32_t debug_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version
-uint32_t debug_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns type of debug info (unchecked)
-uint32_t debug_info::get_type_raw() const
-{
- return type_;
-}
-
-//Returns type of debug info from debug_info_type enumeration
-debug_info::debug_info_type debug_info::get_type() const
-{
- //Determine debug type
- switch(type_)
- {
- case image_debug_type_coff:
- return debug_type_coff;
-
- case image_debug_type_codeview:
- return debug_type_codeview;
-
- case image_debug_type_fpo:
- return debug_type_fpo;
-
- case image_debug_type_misc:
- return debug_type_misc;
-
- case image_debug_type_exception:
- return debug_type_exception;
-
- case image_debug_type_fixup:
- return debug_type_fixup;
-
- case image_debug_type_omap_to_src:
- return debug_type_omap_to_src;
-
- case image_debug_type_omap_from_src:
- return debug_type_omap_from_src;
-
- case image_debug_type_borland:
- return debug_type_borland;
-
- case image_debug_type_clsid:
- return debug_type_clsid;
-
- case image_debug_type_reserved10:
- return debug_type_reserved10;
- }
-
- return debug_type_unknown;
-}
-
-//Returns size of debug data (internal, .pdb or other file doesn't count)
-uint32_t debug_info::get_size_of_data() const
-{
- return size_of_data_;
-}
-
-//Returns RVA of debug info when mapped to memory or zero, if info is not mapped
-uint32_t debug_info::get_rva_of_raw_data() const
-{
- return address_of_raw_data_;
-}
-
-//Returns raw file pointer to raw data
-uint32_t debug_info::get_pointer_to_raw_data() const
-{
- return pointer_to_raw_data_;
-}
-
-//Copy constructor
-debug_info::debug_info(const debug_info& info)
- :characteristics_(info.characteristics_),
- time_stamp_(info.time_stamp_),
- major_version_(info.major_version_), minor_version_(info.minor_version_),
- type_(info.type_),
- size_of_data_(info.size_of_data_),
- address_of_raw_data_(info.address_of_raw_data_),
- pointer_to_raw_data_(info.pointer_to_raw_data_),
- advanced_info_type_(info.advanced_info_type_)
-{
- copy_advanced_info(info);
-}
-
-//Copy assignment operator
-debug_info& debug_info::operator=(const debug_info& info)
-{
- copy_advanced_info(info);
-
- characteristics_ = info.characteristics_;
- time_stamp_ = info.time_stamp_;
- major_version_ = info.major_version_;
- minor_version_ = info.minor_version_;
- type_ = info.type_;
- size_of_data_ = info.size_of_data_;
- address_of_raw_data_ = info.address_of_raw_data_;
- pointer_to_raw_data_ = info.pointer_to_raw_data_;
- advanced_info_type_ = info.advanced_info_type_;
-
- return *this;
-}
-
-//Default constructor
-debug_info::advanced_info::advanced_info()
- :adv_pdb_7_0_info(0) //Zero pointer to advanced data
-{}
-
-//Returns true if advanced debug info is present
-bool debug_info::advanced_info::is_present() const
-{
- return adv_pdb_7_0_info != 0;
-}
-
-//Helper for advanced debug information copying
-void debug_info::copy_advanced_info(const debug_info& info)
-{
- free_present_advanced_info();
-
- switch(info.advanced_info_type_)
- {
- case advanced_info_pdb_7_0:
- advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(*info.advanced_debug_info_.adv_pdb_7_0_info);
- break;
- case advanced_info_pdb_2_0:
- advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(*info.advanced_debug_info_.adv_pdb_2_0_info);
- break;
- case advanced_info_misc:
- advanced_debug_info_.adv_misc_info = new misc_debug_info(*info.advanced_debug_info_.adv_misc_info);
- break;
- case advanced_info_coff:
- advanced_debug_info_.adv_coff_info = new coff_debug_info(*info.advanced_debug_info_.adv_coff_info);
- break;
- default:
- break;
- }
-
- advanced_info_type_ = info.advanced_info_type_;
-}
-
-//Helper for clearing any present advanced debug information
-void debug_info::free_present_advanced_info()
-{
- switch(advanced_info_type_)
- {
- case advanced_info_pdb_7_0:
- delete advanced_debug_info_.adv_pdb_7_0_info;
- break;
- case advanced_info_pdb_2_0:
- delete advanced_debug_info_.adv_pdb_2_0_info;
- break;
- case advanced_info_misc:
- delete advanced_debug_info_.adv_misc_info;
- break;
- case advanced_info_coff:
- delete advanced_debug_info_.adv_coff_info;
- break;
- default:
- break;
- }
-
- advanced_debug_info_.adv_pdb_7_0_info = 0;
- advanced_info_type_ = advanced_info_none;
-}
-
-//Destructor
-debug_info::~debug_info()
-{
- free_present_advanced_info();
-}
-
-//Sets advanced debug information
-void debug_info::set_advanced_debug_info(const pdb_7_0_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(info);
- advanced_info_type_ = advanced_info_pdb_7_0;
-}
-
-void debug_info::set_advanced_debug_info(const pdb_2_0_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(info);
- advanced_info_type_ = advanced_info_pdb_2_0;
-}
-
-void debug_info::set_advanced_debug_info(const misc_debug_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_misc_info = new misc_debug_info(info);
- advanced_info_type_ = advanced_info_misc;
-}
-
-void debug_info::set_advanced_debug_info(const coff_debug_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_coff_info = new coff_debug_info(info);
- advanced_info_type_ = advanced_info_coff;
-}
-
-//Returns advanced debug information type
-debug_info::advanced_info_type debug_info::get_advanced_info_type() const
-{
- return advanced_info_type_;
-}
-
-//Returns advanced debug information or throws an exception,
-//if requested information type is not contained by structure
-template<>
-const pdb_7_0_info debug_info::get_advanced_debug_info<pdb_7_0_info>() const
-{
- if(advanced_info_type_ != advanced_info_pdb_7_0)
- throw pe_exception("Debug info structure does not contain PDB 7.0 data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_pdb_7_0_info;
-}
-
-template<>
-const pdb_2_0_info debug_info::get_advanced_debug_info<pdb_2_0_info>() const
-{
- if(advanced_info_type_ != advanced_info_pdb_2_0)
- throw pe_exception("Debug info structure does not contain PDB 2.0 data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_pdb_2_0_info;
-}
-
-template<>
-const misc_debug_info debug_info::get_advanced_debug_info<misc_debug_info>() const
-{
- if(advanced_info_type_ != advanced_info_misc)
- throw pe_exception("Debug info structure does not contain MISC data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_misc_info;
-}
-
-template<>
-const coff_debug_info debug_info::get_advanced_debug_info<coff_debug_info>() const
-{
- if(advanced_info_type_ != advanced_info_coff)
- throw pe_exception("Debug info structure does not contain COFF data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_coff_info;
-}
-
-//Sets advanced debug information type, if no advanced info structure available
-void debug_info::set_advanced_info_type(advanced_info_type type)
-{
- free_present_advanced_info();
- if(advanced_info_type_ >= advanced_info_codeview_4_0) //Don't set info type for those types, which have advanced info structures
- advanced_info_type_ = type;
-}
-
-//Default constructor
-pdb_7_0_info::pdb_7_0_info()
- :age_(0)
-{
- memset(&guid_, 0, sizeof(guid_));
-}
-
-//Constructor from data
-pdb_7_0_info::pdb_7_0_info(const CV_INFO_PDB70* info)
- :age_(info->Age), guid_(info->Signature),
- pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 7.0 structure GUID
-const guid pdb_7_0_info::get_guid() const
-{
- return guid_;
-}
-
-//Returns age of build
-uint32_t pdb_7_0_info::get_age() const
-{
- return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_7_0_info::get_pdb_file_name() const
-{
- return pdb_file_name_;
-}
-
-//Default constructor
-pdb_2_0_info::pdb_2_0_info()
- :age_(0), signature_(0)
-{}
-
-//Constructor from data
-pdb_2_0_info::pdb_2_0_info(const CV_INFO_PDB20* info)
- :age_(info->Age), signature_(info->Signature),
- pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 2.0 structure signature
-uint32_t pdb_2_0_info::get_signature() const
-{
- return signature_;
-}
-
-//Returns age of build
-uint32_t pdb_2_0_info::get_age() const
-{
- return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_2_0_info::get_pdb_file_name() const
-{
- return pdb_file_name_;
-}
-
-//Default constructor
-misc_debug_info::misc_debug_info()
- :data_type_(0), unicode_(false)
-{}
-
-//Constructor from data
-misc_debug_info::misc_debug_info(const image_debug_misc* info)
- :data_type_(info->DataType), unicode_(info->Unicode ? true : false)
-{
- //IMAGE_DEBUG_MISC::Data must be checked before!
- if(info->Unicode)
- {
-#ifdef PE_BLISS_WINDOWS
- debug_data_unicode_ = std::wstring(reinterpret_cast<const wchar_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2);
-#else
- debug_data_unicode_ = pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2));
-#endif
-
- pe_utils::strip_nullbytes(debug_data_unicode_); //Strip nullbytes in the end of string
- }
- else
- {
- debug_data_ansi_ = std::string(reinterpret_cast<const char*>(info->Data), info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */);
- pe_utils::strip_nullbytes(debug_data_ansi_); //Strip nullbytes in the end of string
- }
-}
-
-//Returns debug data type
-uint32_t misc_debug_info::get_data_type() const
-{
- return data_type_;
-}
-
-//Returns true if data type is exe name
-bool misc_debug_info::is_exe_name() const
-{
- return data_type_ == image_debug_misc_exename;
-}
-
-//Returns true if debug data is UNICODE
-bool misc_debug_info::is_unicode() const
-{
- return unicode_;
-}
-
-//Returns debug data (ANSI)
-const std::string& misc_debug_info::get_data_ansi() const
-{
- return debug_data_ansi_;
-}
-
-//Returns debug data (UNICODE)
-const std::wstring& misc_debug_info::get_data_unicode() const
-{
- return debug_data_unicode_;
-}
-
-//Default constructor
-coff_debug_info::coff_debug_info()
- :number_of_symbols_(0),
- lva_to_first_symbol_(0),
- number_of_line_numbers_(0),
- lva_to_first_line_number_(0),
- rva_to_first_byte_of_code_(0),
- rva_to_last_byte_of_code_(0),
- rva_to_first_byte_of_data_(0),
- rva_to_last_byte_of_data_(0)
-{}
-
-//Constructor from data
-coff_debug_info::coff_debug_info(const image_coff_symbols_header* info)
- :number_of_symbols_(info->NumberOfSymbols),
- lva_to_first_symbol_(info->LvaToFirstSymbol),
- number_of_line_numbers_(info->NumberOfLinenumbers),
- lva_to_first_line_number_(info->LvaToFirstLinenumber),
- rva_to_first_byte_of_code_(info->RvaToFirstByteOfCode),
- rva_to_last_byte_of_code_(info->RvaToLastByteOfCode),
- rva_to_first_byte_of_data_(info->RvaToFirstByteOfData),
- rva_to_last_byte_of_data_(info->RvaToLastByteOfData)
-{}
-
-//Returns number of symbols
-uint32_t coff_debug_info::get_number_of_symbols() const
-{
- return number_of_symbols_;
-}
-
-//Returns virtual address of the first symbol
-uint32_t coff_debug_info::get_lva_to_first_symbol() const
-{
- return lva_to_first_symbol_;
-}
-
-//Returns number of line-number entries
-uint32_t coff_debug_info::get_number_of_line_numbers() const
-{
- return number_of_line_numbers_;
-}
-
-//Returns virtual address of the first line-number entry
-uint32_t coff_debug_info::get_lva_to_first_line_number() const
-{
- return lva_to_first_line_number_;
-}
-
-//Returns relative virtual address of the first byte of code
-uint32_t coff_debug_info::get_rva_to_first_byte_of_code() const
-{
- return rva_to_first_byte_of_code_;
-}
-
-//Returns relative virtual address of the last byte of code
-uint32_t coff_debug_info::get_rva_to_last_byte_of_code() const
-{
- return rva_to_last_byte_of_code_;
-}
-
-//Returns relative virtual address of the first byte of data
-uint32_t coff_debug_info::get_rva_to_first_byte_of_data() const
-{
- return rva_to_first_byte_of_data_;
-}
-
-//Returns relative virtual address of the last byte of data
-uint32_t coff_debug_info::get_rva_to_last_byte_of_data() const
-{
- return rva_to_last_byte_of_data_;
-}
-
-//Returns COFF symbols list
-const coff_debug_info::coff_symbols_list& coff_debug_info::get_symbols() const
-{
- return symbols_;
-}
-
-//Adds COFF symbol
-void coff_debug_info::add_symbol(const coff_symbol& sym)
-{
- symbols_.push_back(sym);
-}
-
-//Default constructor
-coff_debug_info::coff_symbol::coff_symbol()
- :storage_class_(0),
- index_(0),
- section_number_(0), rva_(0),
- type_(0),
- is_filename_(false)
-{}
-
-//Returns storage class
-uint32_t coff_debug_info::coff_symbol::get_storage_class() const
-{
- return storage_class_;
-}
-
-//Returns symbol index
-uint32_t coff_debug_info::coff_symbol::get_index() const
-{
- return index_;
-}
-
-//Returns section number
-uint32_t coff_debug_info::coff_symbol::get_section_number() const
-{
- return section_number_;
-}
-
-//Returns RVA
-uint32_t coff_debug_info::coff_symbol::get_rva() const
-{
- return rva_;
-}
-
-//Returns true if structure contains file name
-bool coff_debug_info::coff_symbol::is_file() const
-{
- return is_filename_;
-}
-
-//Returns text data (symbol or file name)
-const std::string& coff_debug_info::coff_symbol::get_symbol() const
-{
- return name_;
-}
-
-//Sets storage class
-void coff_debug_info::coff_symbol::set_storage_class(uint32_t storage_class)
-{
- storage_class_ = storage_class;
-}
-
-//Sets symbol index
-void coff_debug_info::coff_symbol::set_index(uint32_t index)
-{
- index_ = index;
-}
-
-//Sets section number
-void coff_debug_info::coff_symbol::set_section_number(uint32_t section_number)
-{
- section_number_ = section_number;
-}
-
-//Sets RVA
-void coff_debug_info::coff_symbol::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets file name
-void coff_debug_info::coff_symbol::set_file_name(const std::string& file_name)
-{
- name_ = file_name;
- is_filename_ = true;
-}
-
-//Sets symbol name
-void coff_debug_info::coff_symbol::set_symbol_name(const std::string& symbol_name)
-{
- name_ = symbol_name;
- is_filename_ = false;
-}
-
-//Returns type
-uint16_t coff_debug_info::coff_symbol::get_type() const
-{
- return type_;
-}
-
-//Sets type
-void coff_debug_info::coff_symbol::set_type(uint16_t type)
-{
- type_ = type;
-}
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe)
-{
- debug_info_list ret;
-
- //If there's no debug directory, return empty list
- if(!pe.has_debug())
- return ret;
-
- //Check the length in bytes of the section containing debug directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_rva(image_directory_entry_debug), section_data_virtual, true)
- < sizeof(image_debug_directory))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_debug);
-
- //First IMAGE_DEBUG_DIRECTORY table
- image_debug_directory directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
- if(!pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_size(image_directory_entry_debug)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Iterate over all IMAGE_DEBUG_DIRECTORY directories
- while(directory.PointerToRawData
- && current_pos < pe.get_directory_rva(image_directory_entry_debug) + pe.get_directory_size(image_directory_entry_debug))
- {
- //Create debug information structure
- debug_info info(directory);
-
- //Find raw debug data
- const pe_base::debug_data_list& debug_datas = pe.get_raw_debug_data_list();
- pe_base::debug_data_list::const_iterator it = debug_datas.find(directory.PointerToRawData);
- if(it != debug_datas.end()) //If it exists, we'll do some detailed debug info research
- {
- const std::string& debug_data = (*it).second;
- switch(directory.Type)
- {
- case image_debug_type_coff:
- {
- //Check data length
- if(debug_data.length() < sizeof(image_coff_symbols_header))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get coff header structure pointer
- const image_coff_symbols_header* coff = reinterpret_cast<const image_coff_symbols_header*>(debug_data.data());
-
- //Check possible overflows
- if(coff->NumberOfSymbols >= pe_utils::max_dword / sizeof(image_symbol)
- || !pe_utils::is_sum_safe(coff->NumberOfSymbols * sizeof(image_symbol), coff->LvaToFirstSymbol))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Check data length again
- if(debug_data.length() < coff->NumberOfSymbols * sizeof(image_symbol) + coff->LvaToFirstSymbol)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Create COFF debug info structure
- coff_debug_info coff_info(coff);
-
- //Enumerate debug symbols data
- for(uint32_t i = 0; i < coff->NumberOfSymbols; ++i)
- {
- //Safe sum (checked above)
- const image_symbol* sym = reinterpret_cast<const image_symbol*>(debug_data.data() + i * sizeof(image_symbol) + coff->LvaToFirstSymbol);
-
- coff_debug_info::coff_symbol symbol;
- symbol.set_index(i); //Save symbol index
- symbol.set_storage_class(sym->StorageClass); //Save storage class
- symbol.set_type(sym->Type); //Save storage class
-
- //Check data length again
- if(!pe_utils::is_sum_safe(i, sym->NumberOfAuxSymbols)
- || (i + sym->NumberOfAuxSymbols) > coff->NumberOfSymbols
- || debug_data.length() < (i + 1) * sizeof(image_symbol) + coff->LvaToFirstSymbol + sym->NumberOfAuxSymbols * sizeof(image_symbol))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //If symbol is filename
- if(sym->StorageClass == image_sym_class_file)
- {
- //Save file name, it is situated just after this IMAGE_SYMBOL structure
- std::string file_name(reinterpret_cast<const char*>(debug_data.data() + (i + 1) * sizeof(image_symbol)), sym->NumberOfAuxSymbols * sizeof(image_symbol));
- pe_utils::strip_nullbytes(file_name);
- symbol.set_file_name(file_name);
-
- //Save symbol info
- coff_info.add_symbol(symbol);
-
- //Move to next symbol
- i += sym->NumberOfAuxSymbols;
- continue;
- }
-
- //Dump some other symbols
- if(((sym->StorageClass == image_sym_class_static)
- && (sym->NumberOfAuxSymbols == 0)
- && (sym->SectionNumber == 1))
- ||
- ((sym->StorageClass == image_sym_class_external)
- && ISFCN(sym->Type)
- && (sym->SectionNumber > 0))
- )
- {
- //Save RVA and section number
- symbol.set_section_number(sym->SectionNumber);
- symbol.set_rva(sym->Value);
-
- //If symbol has short name
- if(sym->N.Name.Short)
- {
- //Copy and save symbol name
- char name_buff[9];
- memcpy(name_buff, sym->N.ShortName, 8);
- name_buff[8] = '\0';
- symbol.set_symbol_name(name_buff);
- }
- else
- {
- //Symbol has long name
-
- //Check possible overflows
- if(!pe_utils::is_sum_safe(coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol), sym->N.Name.Long))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Here we have an offset to the string table
- uint32_t symbol_offset = coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol) + sym->N.Name.Long;
-
- //Check data length
- if(debug_data.length() < symbol_offset)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Check symbol name for null-termination
- if(!pe_utils::is_null_terminated(debug_data.data() + symbol_offset, debug_data.length() - symbol_offset))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Save symbol name
- symbol.set_symbol_name(debug_data.data() + symbol_offset);
- }
-
- //Save symbol info
- coff_info.add_symbol(symbol);
-
- //Move to next symbol
- i += sym->NumberOfAuxSymbols;
- continue;
- }
- }
-
- info.set_advanced_debug_info(coff_info);
- }
- break;
-
- case image_debug_type_codeview:
- {
- //Check data length
- if(debug_data.length() < sizeof(OMFSignature*))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get POMFSignature structure pointer from the very beginning of debug data
- const OMFSignature* sig = reinterpret_cast<const OMFSignature*>(debug_data.data());
- if(!memcmp(sig->Signature, "RSDS", 4))
- {
- //Signature is "RSDS" - PDB 7.0
-
- //Check data length
- if(debug_data.length() < sizeof(CV_INFO_PDB70))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- const CV_INFO_PDB70* pdb_data = reinterpret_cast<const CV_INFO_PDB70*>(debug_data.data());
-
- //Check PDB file name null-termination
- if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB70) - 1 /* BYTE of filename in structure */)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- info.set_advanced_debug_info(pdb_7_0_info(pdb_data));
- }
- else if(!memcmp(sig->Signature, "NB10", 4))
- {
- //Signature is "NB10" - PDB 2.0
-
- //Check data length
- if(debug_data.length() < sizeof(CV_INFO_PDB20))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- const CV_INFO_PDB20* pdb_data = reinterpret_cast<const CV_INFO_PDB20*>(debug_data.data());
-
- //Check PDB file name null-termination
- if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB20) - 1 /* BYTE of filename in structure */)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- info.set_advanced_debug_info(pdb_2_0_info(pdb_data));
- }
- else if(!memcmp(sig->Signature, "NB09", 4))
- {
- //CodeView 4.0, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview_4_0);
- }
- else if(!memcmp(sig->Signature, "NB11", 4))
- {
- //CodeView 5.0, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview_5_0);
- }
- else if(!memcmp(sig->Signature, "NB05", 4))
- {
- //Other CodeView, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview);
- }
- }
-
- break;
-
- case image_debug_type_misc:
- {
- //Check data length
- if(debug_data.length() < sizeof(image_debug_misc))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get misc structure pointer
- const image_debug_misc* misc_data = reinterpret_cast<const image_debug_misc*>(debug_data.data());
-
- //Check misc data length
- if(debug_data.length() < misc_data->Length /* Total length of record */)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Save advanced information
- info.set_advanced_debug_info(misc_debug_info(misc_data));
- }
- break;
- }
- }
-
- //Save debug information structure
- ret.push_back(info);
-
- //Check possible overflow
- if(!pe_utils::is_sum_safe(current_pos, sizeof(image_debug_directory)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Go to next debug entry
- current_pos += sizeof(image_debug_directory);
- directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_debug.h b/tools/pe_bliss/pe_debug.h
deleted file mode 100644
index 73a7e6860d..0000000000
--- a/tools/pe_bliss/pe_debug.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing advanced RSDS (PDB 7.0) information
-class pdb_7_0_info
-{
-public:
- //Default constructor
- pdb_7_0_info();
- //Constructor from data
- explicit pdb_7_0_info(const pe_win::CV_INFO_PDB70* info);
-
- //Returns debug PDB 7.0 structure GUID
- const pe_win::guid get_guid() const;
- //Returns age of build
- uint32_t get_age() const;
- //Returns PDB file name / path
- const std::string& get_pdb_file_name() const;
-
-private:
- uint32_t age_;
- pe_win::guid guid_;
- std::string pdb_file_name_;
-};
-
-//Class representing advanced NB10 (PDB 2.0) information
-class pdb_2_0_info
-{
-public:
- //Default constructor
- pdb_2_0_info();
- //Constructor from data
- explicit pdb_2_0_info(const pe_win::CV_INFO_PDB20* info);
-
- //Returns debug PDB 2.0 structure signature
- uint32_t get_signature() const;
- //Returns age of build
- uint32_t get_age() const;
- //Returns PDB file name / path
- const std::string& get_pdb_file_name() const;
-
-private:
- uint32_t age_;
- uint32_t signature_;
- std::string pdb_file_name_;
-};
-
-//Class representing advanced misc (IMAGE_DEBUG_TYPE_MISC) info
-class misc_debug_info
-{
-public:
- //Default constructor
- misc_debug_info();
- //Constructor from data
- explicit misc_debug_info(const pe_win::image_debug_misc* info);
-
- //Returns debug data type
- uint32_t get_data_type() const;
- //Returns true if data type is exe name
- bool is_exe_name() const;
-
- //Returns true if debug data is UNICODE
- bool is_unicode() const;
- //Returns debug data (ANSI or UNICODE)
- const std::string& get_data_ansi() const;
- const std::wstring& get_data_unicode() const;
-
-private:
- uint32_t data_type_;
- bool unicode_;
- std::string debug_data_ansi_;
- std::wstring debug_data_unicode_;
-};
-
-//Class representing COFF (IMAGE_DEBUG_TYPE_COFF) debug info
-class coff_debug_info
-{
-public:
- //Structure representing COFF symbol
- struct coff_symbol
- {
- public:
- //Default constructor
- coff_symbol();
-
- //Returns storage class
- uint32_t get_storage_class() const;
- //Returns symbol index
- uint32_t get_index() const;
- //Returns section number
- uint32_t get_section_number() const;
- //Returns RVA
- uint32_t get_rva() const;
- //Returns type
- uint16_t get_type() const;
-
- //Returns true if structure contains file name
- bool is_file() const;
- //Returns text data (symbol or file name)
- const std::string& get_symbol() const;
-
- public: //These functions do not change everything inside image, they are used by PE class
- //Sets storage class
- void set_storage_class(uint32_t storage_class);
- //Sets symbol index
- void set_index(uint32_t index);
- //Sets section number
- void set_section_number(uint32_t section_number);
- //Sets RVA
- void set_rva(uint32_t rva);
- //Sets type
- void set_type(uint16_t type);
-
- //Sets file name
- void set_file_name(const std::string& file_name);
- //Sets symbol name
- void set_symbol_name(const std::string& symbol_name);
-
- private:
- uint32_t storage_class_;
- uint32_t index_;
- uint32_t section_number_, rva_;
- uint16_t type_;
- bool is_filename_;
- std::string name_;
- };
-
-public:
- typedef std::vector<coff_symbol> coff_symbols_list;
-
-public:
- //Default constructor
- coff_debug_info();
- //Constructor from data
- explicit coff_debug_info(const pe_win::image_coff_symbols_header* info);
-
- //Returns number of symbols
- uint32_t get_number_of_symbols() const;
- //Returns virtual address of the first symbol
- uint32_t get_lva_to_first_symbol() const;
- //Returns number of line-number entries
- uint32_t get_number_of_line_numbers() const;
- //Returns virtual address of the first line-number entry
- uint32_t get_lva_to_first_line_number() const;
- //Returns relative virtual address of the first byte of code
- uint32_t get_rva_to_first_byte_of_code() const;
- //Returns relative virtual address of the last byte of code
- uint32_t get_rva_to_last_byte_of_code() const;
- //Returns relative virtual address of the first byte of data
- uint32_t get_rva_to_first_byte_of_data() const;
- //Returns relative virtual address of the last byte of data
- uint32_t get_rva_to_last_byte_of_data() const;
-
- //Returns COFF symbols list
- const coff_symbols_list& get_symbols() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Adds COFF symbol
- void add_symbol(const coff_symbol& sym);
-
-private:
- uint32_t number_of_symbols_;
- uint32_t lva_to_first_symbol_;
- uint32_t number_of_line_numbers_;
- uint32_t lva_to_first_line_number_;
- uint32_t rva_to_first_byte_of_code_;
- uint32_t rva_to_last_byte_of_code_;
- uint32_t rva_to_first_byte_of_data_;
- uint32_t rva_to_last_byte_of_data_;
-
-private:
- coff_symbols_list symbols_;
-};
-
-//Class representing debug information
-class debug_info
-{
-public:
- //Enumeration of debug information types
- enum debug_info_type
- {
- debug_type_unknown,
- debug_type_coff,
- debug_type_codeview,
- debug_type_fpo,
- debug_type_misc,
- debug_type_exception,
- debug_type_fixup,
- debug_type_omap_to_src,
- debug_type_omap_from_src,
- debug_type_borland,
- debug_type_reserved10,
- debug_type_clsid
- };
-
-public:
- //Enumeration of advanced debug information types
- enum advanced_info_type
- {
- advanced_info_none, //No advanced info
- advanced_info_pdb_7_0, //PDB 7.0
- advanced_info_pdb_2_0, //PDB 2.0
- advanced_info_misc, //MISC debug info
- advanced_info_coff, //COFF debug info
- //No advanced info structures available for types below
- advanced_info_codeview_4_0, //CodeView 4.0
- advanced_info_codeview_5_0, //CodeView 5.0
- advanced_info_codeview //CodeView
- };
-
-public:
- //Default constructor
- debug_info();
- //Constructor from data
- explicit debug_info(const pe_win::image_debug_directory& debug);
- //Copy constructor
- debug_info(const debug_info& info);
- //Copy assignment operator
- debug_info& operator=(const debug_info& info);
- //Destructor
- ~debug_info();
-
- //Returns debug characteristics
- uint32_t get_characteristics() const;
- //Returns debug datetimestamp
- uint32_t get_time_stamp() const;
- //Returns major version
- uint32_t get_major_version() const;
- //Returns minor version
- uint32_t get_minor_version() const;
- //Returns type of debug info (unchecked)
- uint32_t get_type_raw() const;
- //Returns type of debug info from debug_info_type enumeration
- debug_info_type get_type() const;
- //Returns size of debug data (internal, .pdb or other file doesn't count)
- uint32_t get_size_of_data() const;
- //Returns RVA of debug info when mapped to memory or zero, if info is not mapped
- uint32_t get_rva_of_raw_data() const;
- //Returns raw file pointer to raw data
- uint32_t get_pointer_to_raw_data() const;
-
- //Returns advanced debug information type
- advanced_info_type get_advanced_info_type() const;
- //Returns advanced debug information or throws an exception,
- //if requested information type is not contained by structure
- template<typename AdvancedInfo>
- const AdvancedInfo get_advanced_debug_info() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Sets advanced debug information
- void set_advanced_debug_info(const pdb_7_0_info& info);
- void set_advanced_debug_info(const pdb_2_0_info& info);
- void set_advanced_debug_info(const misc_debug_info& info);
- void set_advanced_debug_info(const coff_debug_info& info);
-
- //Sets advanced debug information type, if no advanced info structure available
- void set_advanced_info_type(advanced_info_type type);
-
-private:
- uint32_t characteristics_;
- uint32_t time_stamp_;
- uint32_t major_version_, minor_version_;
- uint32_t type_;
- uint32_t size_of_data_;
- uint32_t address_of_raw_data_; //RVA when mapped or 0
- uint32_t pointer_to_raw_data_; //RAW file offset
-
- //Union containing advanced debug information pointer
- union advanced_info
- {
- public:
- //Default constructor
- advanced_info();
-
- //Returns true if advanced debug info is present
- bool is_present() const;
-
- public:
- pdb_7_0_info* adv_pdb_7_0_info;
- pdb_2_0_info* adv_pdb_2_0_info;
- misc_debug_info* adv_misc_info;
- coff_debug_info* adv_coff_info;
- };
-
- //Helper for advanced debug information copying
- void copy_advanced_info(const debug_info& info);
- //Helper for clearing any present advanced debug information
- void free_present_advanced_info();
-
- advanced_info advanced_debug_info_;
- //Advanced information type
- advanced_info_type advanced_info_type_;
-};
-
-typedef std::vector<debug_info> debug_info_list;
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_directory.cpp b/tools/pe_bliss/pe_directory.cpp
deleted file mode 100644
index 13ad2afc5d..0000000000
--- a/tools/pe_bliss/pe_directory.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Default constructor
-image_directory::image_directory()
- :rva_(0), size_(0)
-{}
-
-//Constructor from data
-image_directory::image_directory(uint32_t rva, uint32_t size)
- :rva_(rva), size_(size)
-{}
-
-//Returns RVA
-uint32_t image_directory::get_rva() const
-{
- return rva_;
-}
-
-//Returns size
-uint32_t image_directory::get_size() const
-{
- return size_;
-}
-
-//Sets RVA
-void image_directory::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets size
-void image_directory::set_size(uint32_t size)
-{
- size_ = size;
-}
-}
diff --git a/tools/pe_bliss/pe_directory.h b/tools/pe_bliss/pe_directory.h
deleted file mode 100644
index a7b1ea7a5f..0000000000
--- a/tools/pe_bliss/pe_directory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Class representing image directory data
-class image_directory
-{
-public:
- //Default constructor
- image_directory();
- //Constructor from data
- image_directory(uint32_t rva, uint32_t size);
-
- //Returns RVA
- uint32_t get_rva() const;
- //Returns size
- uint32_t get_size() const;
-
- //Sets RVA
- void set_rva(uint32_t rva);
- //Sets size
- void set_size(uint32_t size);
-
-private:
- uint32_t rva_;
- uint32_t size_;
-};
-}
diff --git a/tools/pe_bliss/pe_dotnet.cpp b/tools/pe_bliss/pe_dotnet.cpp
deleted file mode 100644
index f34a76eae8..0000000000
--- a/tools/pe_bliss/pe_dotnet.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_dotnet.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//.NET
-basic_dotnet_info::basic_dotnet_info()
-{
- memset(&header_, 0, sizeof(header_));
-}
-
-//Constructor from data
-basic_dotnet_info::basic_dotnet_info(const image_cor20_header& header)
- :header_(header)
-{}
-
-//Returns major runtime version
-uint16_t basic_dotnet_info::get_major_runtime_version() const
-{
- return header_.MajorRuntimeVersion;
-}
-
-//Returns minor runtime version
-uint16_t basic_dotnet_info::get_minor_runtime_version() const
-{
- return header_.MinorRuntimeVersion;
-}
-
-//Returns RVA of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_rva_of_metadata() const
-{
- return header_.MetaData.VirtualAddress;
-}
-
-//Returns size of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_size_of_metadata() const
-{
- return header_.MetaData.Size;
-}
-
-//Returns flags
-uint32_t basic_dotnet_info::get_flags() const
-{
- return header_.Flags;
-}
-
-//Returns true if entry point is native
-bool basic_dotnet_info::is_native_entry_point() const
-{
- return (header_.Flags & comimage_flags_native_entrypoint) ? true : false;
-}
-
-//Returns true if 32 bit required
-bool basic_dotnet_info::is_32bit_required() const
-{
- return (header_.Flags & comimage_flags_32bitrequired) ? true : false;
-}
-
-//Returns true if image is IL library
-bool basic_dotnet_info::is_il_library() const
-{
- return (header_.Flags & comimage_flags_il_library) ? true : false;
-}
-
-//Returns true if image uses IL only
-bool basic_dotnet_info::is_il_only() const
-{
- return (header_.Flags & comimage_flags_ilonly) ? true : false;
-}
-
-//Returns entry point RVA (if entry point is native)
-//Returns entry point managed token (if entry point is managed)
-uint32_t basic_dotnet_info::get_entry_point_rva_or_token() const
-{
- return header_.EntryPointToken;
-}
-
-//Returns RVA of managed resources
-uint32_t basic_dotnet_info::get_rva_of_resources() const
-{
- return header_.Resources.VirtualAddress;
-}
-
-//Returns size of managed resources
-uint32_t basic_dotnet_info::get_size_of_resources() const
-{
- return header_.Resources.Size;
-}
-
-//Returns RVA of strong name signature
-uint32_t basic_dotnet_info::get_rva_of_strong_name_signature() const
-{
- return header_.StrongNameSignature.VirtualAddress;
-}
-
-//Returns size of strong name signature
-uint32_t basic_dotnet_info::get_size_of_strong_name_signature() const
-{
- return header_.StrongNameSignature.Size;
-}
-
-//Returns RVA of code manager table
-uint32_t basic_dotnet_info::get_rva_of_code_manager_table() const
-{
- return header_.CodeManagerTable.VirtualAddress;
-}
-
-//Returns size of code manager table
-uint32_t basic_dotnet_info::get_size_of_code_manager_table() const
-{
- return header_.CodeManagerTable.Size;
-}
-
-//Returns RVA of VTable fixups
-uint32_t basic_dotnet_info::get_rva_of_vtable_fixups() const
-{
- return header_.VTableFixups.VirtualAddress;
-}
-
-//Returns size of VTable fixups
-uint32_t basic_dotnet_info::get_size_of_vtable_fixups() const
-{
- return header_.VTableFixups.Size;
-}
-
-//Returns RVA of export address table jumps
-uint32_t basic_dotnet_info::get_rva_of_export_address_table_jumps() const
-{
- return header_.ExportAddressTableJumps.VirtualAddress;
-}
-
-//Returns size of export address table jumps
-uint32_t basic_dotnet_info::get_size_of_export_address_table_jumps() const
-{
- return header_.ExportAddressTableJumps.Size;
-}
-
-//Returns RVA of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_rva_of_managed_native_header() const
-{
- return header_.ManagedNativeHeader.VirtualAddress;
-}
-
-//Returns size of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_size_of_managed_native_header() const
-{
- return header_.ManagedNativeHeader.Size;
-}
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe)
-{
- //If there's no debug directory, return empty list
- if(!pe.is_dotnet())
- throw pe_exception("Image does not have managed code", pe_exception::image_does_not_have_managed_code);
-
- //Return basic .NET information
- return basic_dotnet_info(pe.section_data_from_rva<image_cor20_header>(pe.get_directory_rva(image_directory_entry_com_descriptor), section_data_virtual, true));
-}
-}
diff --git a/tools/pe_bliss/pe_dotnet.h b/tools/pe_bliss/pe_dotnet.h
deleted file mode 100644
index 96b0ac7d0a..0000000000
--- a/tools/pe_bliss/pe_dotnet.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing basic .NET header information
-class basic_dotnet_info
-{
-public:
- //Default constructor
- basic_dotnet_info();
- //Constructor from data
- explicit basic_dotnet_info(const pe_win::image_cor20_header& header);
-
- //Returns major runtime version
- uint16_t get_major_runtime_version() const;
- //Returns minor runtime version
- uint16_t get_minor_runtime_version() const;
-
- //Returns RVA of metadata (symbol table and startup information)
- uint32_t get_rva_of_metadata() const;
- //Returns size of metadata (symbol table and startup information)
- uint32_t get_size_of_metadata() const;
-
- //Returns flags
- uint32_t get_flags() const;
-
- //Returns true if entry point is native
- bool is_native_entry_point() const;
- //Returns true if 32 bit required
- bool is_32bit_required() const;
- //Returns true if image is IL library
- bool is_il_library() const;
- //Returns true if image uses IL only
- bool is_il_only() const;
-
- //Returns entry point RVA (if entry point is native)
- //Returns entry point managed token (if entry point is managed)
- uint32_t get_entry_point_rva_or_token() const;
-
- //Returns RVA of managed resources
- uint32_t get_rva_of_resources() const;
- //Returns size of managed resources
- uint32_t get_size_of_resources() const;
- //Returns RVA of strong name signature
- uint32_t get_rva_of_strong_name_signature() const;
- //Returns size of strong name signature
- uint32_t get_size_of_strong_name_signature() const;
- //Returns RVA of code manager table
- uint32_t get_rva_of_code_manager_table() const;
- //Returns size of code manager table
- uint32_t get_size_of_code_manager_table() const;
- //Returns RVA of VTable fixups
- uint32_t get_rva_of_vtable_fixups() const;
- //Returns size of VTable fixups
- uint32_t get_size_of_vtable_fixups() const;
- //Returns RVA of export address table jumps
- uint32_t get_rva_of_export_address_table_jumps() const;
- //Returns size of export address table jumps
- uint32_t get_size_of_export_address_table_jumps() const;
- //Returns RVA of managed native header
- //(precompiled header info, usually set to zero, for internal use)
- uint32_t get_rva_of_managed_native_header() const;
- //Returns size of managed native header
- //(precompiled header info, usually set to zero, for internal use)
- uint32_t get_size_of_managed_native_header() const;
-
-private:
- pe_win::image_cor20_header header_;
-};
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_exception.cpp b/tools/pe_bliss/pe_exception.cpp
deleted file mode 100644
index 3161f93599..0000000000
--- a/tools/pe_bliss/pe_exception.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_exception.h"
-
-namespace pe_bliss
-{
-//PE exception class constructors
-pe_exception::pe_exception(const char* text, exception_id id)
- :std::runtime_error(text), id_(id)
-{}
-
-pe_exception::pe_exception(const std::string& text, exception_id id)
- :std::runtime_error(text), id_(id)
-{}
-
-//Returns exception ID
-pe_exception::exception_id pe_exception::get_id() const
-{
- return id_;
-}
-}
diff --git a/tools/pe_bliss/pe_exception.h b/tools/pe_bliss/pe_exception.h
deleted file mode 100644
index 2b58a95772..0000000000
--- a/tools/pe_bliss/pe_exception.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <exception>
-#include <stdexcept>
-
-namespace pe_bliss
-{
-//PE exception class
-class pe_exception : public std::runtime_error
-{
-public:
- //Exception IDs
- enum exception_id
- {
- unknown_error,
- bad_pe_file,
- bad_dos_header,
- image_nt_headers_not_found,
- error_reading_image_nt_headers,
- error_reading_data_directories,
- error_reading_file,
- pe_signature_incorrect,
- incorrect_number_of_rva_and_sizes,
- error_changing_section_virtual_size,
- section_number_incorrect,
- section_table_incorrect,
- incorrect_section_alignment,
- incorrect_file_alignment,
- incorrect_size_of_image,
- incorrect_size_of_headers,
- image_section_headers_not_found,
- zero_section_sizes,
- section_incorrect_addr_or_size,
- section_not_found,
- image_section_data_not_found,
- no_section_found,
- image_section_table_incorrect,
- directory_does_not_exist,
- rva_not_exists,
- error_reading_section_header,
- error_reading_overlay,
- incorrect_address_conversion,
-
- incorrect_export_directory,
- incorrect_import_directory,
- incorrect_relocation_directory,
- incorrect_tls_directory,
- incorrect_config_directory,
- incorrect_bound_import_directory,
- incorrect_resource_directory,
- incorrect_exception_directory,
- incorrect_debug_directory,
-
- resource_directory_entry_error,
- resource_directory_entry_not_found,
- resource_data_entry_not_found,
- resource_incorrect_bitmap,
- resource_incorrect_icon,
- resource_incorrect_cursor,
- resource_incorrect_string_table,
- resource_string_not_found,
- resource_incorrect_message_table,
- resource_incorrect_version_info,
-
- advanced_debug_information_request_error,
- image_does_not_have_managed_code,
-
- section_is_empty,
- data_is_empty,
- stream_is_bad,
-
- section_is_not_attached,
- insufficient_space,
-
- cannot_rebase_relocations,
-
- exports_list_is_empty,
- duplicate_exported_function_ordinal,
- duplicate_exported_function_name,
-
- version_info_string_does_not_exist,
-
- no_more_sections_can_be_added,
-
- no_icon_group_found,
- no_cursor_group_found,
-
- encoding_convertion_error,
-
- error_expanding_section,
-
- cannot_rebuild_image
- };
-
-public:
- //Class constructors
- explicit pe_exception(const char* text, exception_id id = unknown_error);
- explicit pe_exception(const std::string& text, exception_id id = unknown_error);
-
- //Returns exception ID from exception_id enumeration
- exception_id get_id() const;
-
- //Destructor
- virtual ~pe_exception() throw()
- {}
-
-private:
- exception_id id_;
-};
-}
diff --git a/tools/pe_bliss/pe_exception_directory.cpp b/tools/pe_bliss/pe_exception_directory.cpp
deleted file mode 100644
index 1813f02021..0000000000
--- a/tools/pe_bliss/pe_exception_directory.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_exception_directory.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXCEPTION DIRECTORY (exists on PE+ only)
-//Default constructor
-exception_entry::exception_entry()
- :begin_address_(0), end_address_(0), unwind_info_address_(0),
- unwind_info_version_(0),
- flags_(0),
- size_of_prolog_(0),
- count_of_codes_(0),
- frame_register_(0),
- frame_offset_(0)
-{}
-
-//Constructor from data
-exception_entry::exception_entry(const image_runtime_function_entry& entry, const unwind_info& unwind_info)
- :begin_address_(entry.BeginAddress), end_address_(entry.EndAddress), unwind_info_address_(entry.UnwindInfoAddress),
- unwind_info_version_(unwind_info.Version),
- flags_(unwind_info.Flags),
- size_of_prolog_(unwind_info.SizeOfProlog),
- count_of_codes_(unwind_info.CountOfCodes),
- frame_register_(unwind_info.FrameRegister),
- frame_offset_(unwind_info.FrameOffset)
-{}
-
-//Returns starting address of function, affected by exception unwinding
-uint32_t exception_entry::get_begin_address() const
-{
- return begin_address_;
-}
-
-//Returns ending address of function, affected by exception unwinding
-uint32_t exception_entry::get_end_address() const
-{
- return end_address_;
-}
-
-//Returns unwind info address
-uint32_t exception_entry::get_unwind_info_address() const
-{
- return unwind_info_address_;
-}
-
-//Returns UNWIND_INFO structure version
-uint8_t exception_entry::get_unwind_info_version() const
-{
- return unwind_info_version_;
-}
-
-//Returns unwind info flags
-uint8_t exception_entry::get_flags() const
-{
- return flags_;
-}
-
-//The function has an exception handler that should be called
-//when looking for functions that need to examine exceptions
-bool exception_entry::has_exception_handler() const
-{
- return (flags_ & unw_flag_ehandler) ? true : false;
-}
-
-//The function has a termination handler that should be called
-//when unwinding an exception
-bool exception_entry::has_termination_handler() const
-{
- return (flags_ & unw_flag_uhandler) ? true : false;
-}
-
-//The unwind info structure is not the primary one for the procedure
-bool exception_entry::is_chaininfo() const
-{
- return (flags_ & unw_flag_chaininfo) ? true : false;
-}
-
-//Returns size of function prolog
-uint8_t exception_entry::get_size_of_prolog() const
-{
- return size_of_prolog_;
-}
-
-//Returns number of unwind slots
-uint8_t exception_entry::get_number_of_unwind_slots() const
-{
- return count_of_codes_;
-}
-
-//If the function uses frame pointer
-bool exception_entry::uses_frame_pointer() const
-{
- return frame_register_ != 0;
-}
-
-//Number of the nonvolatile register used as the frame pointer,
-//using the same encoding for the operation info field of UNWIND_CODE nodes
-uint8_t exception_entry::get_frame_pointer_register_number() const
-{
- return frame_register_;
-}
-
-//The scaled offset from RSP that is applied to the FP reg when it is established.
-//The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
-uint8_t exception_entry::get_scaled_rsp_offset() const
-{
- return frame_offset_;
-}
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe)
-{
- exception_entry_list ret;
-
- //If image doesn't have exception directory, return empty list
- if(!pe.has_exception_directory())
- return ret;
-
- //Check the length in bytes of the section containing exception directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_exception), pe.get_directory_rva(image_directory_entry_exception), section_data_virtual, true)
- < sizeof(image_runtime_function_entry))
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_exception);
-
- //Check if structures are DWORD-aligned
- if(current_pos % sizeof(uint32_t))
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- //First IMAGE_RUNTIME_FUNCTION_ENTRY table
- image_runtime_function_entry exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
-
- //todo: virtual addresses BeginAddress and EndAddress are not checked to be inside image
- while(exception_table.BeginAddress)
- {
- //Check addresses
- if(exception_table.BeginAddress > exception_table.EndAddress)
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- //Get unwind information
- unwind_info info = pe.section_data_from_rva<unwind_info>(exception_table.UnwindInfoAddress, section_data_virtual, true);
-
- //Create exception entry and save it
- ret.push_back(exception_entry(exception_table, info));
-
- //Go to next exception entry
- current_pos += sizeof(image_runtime_function_entry);
- exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_exception_directory.h b/tools/pe_bliss/pe_exception_directory.h
deleted file mode 100644
index 6f4fc2298b..0000000000
--- a/tools/pe_bliss/pe_exception_directory.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing exception directory entry
-class exception_entry
-{
-public:
- //Default constructor
- exception_entry();
- //Constructor from data
- exception_entry(const pe_win::image_runtime_function_entry& entry, const pe_win::unwind_info& unwind_info);
-
- //Returns starting address of function, affected by exception unwinding
- uint32_t get_begin_address() const;
- //Returns ending address of function, affected by exception unwinding
- uint32_t get_end_address() const;
- //Returns unwind info address
- uint32_t get_unwind_info_address() const;
-
- //Returns UNWIND_INFO structure version
- uint8_t get_unwind_info_version() const;
-
- //Returns unwind info flags
- uint8_t get_flags() const;
- //The function has an exception handler that should be called
- //when looking for functions that need to examine exceptions
- bool has_exception_handler() const;
- //The function has a termination handler that should be called
- //when unwinding an exception
- bool has_termination_handler() const;
- //The unwind info structure is not the primary one for the procedure
- bool is_chaininfo() const;
-
- //Returns size of function prolog
- uint8_t get_size_of_prolog() const;
-
- //Returns number of unwind slots
- uint8_t get_number_of_unwind_slots() const;
-
- //If the function uses frame pointer
- bool uses_frame_pointer() const;
- //Number of the nonvolatile register used as the frame pointer,
- //using the same encoding for the operation info field of UNWIND_CODE nodes
- uint8_t get_frame_pointer_register_number() const;
- //The scaled offset from RSP that is applied to the FP reg when it is established.
- //The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
- uint8_t get_scaled_rsp_offset() const;
-
-private:
- uint32_t begin_address_, end_address_, unwind_info_address_;
- uint8_t unwind_info_version_;
- uint8_t flags_;
- uint8_t size_of_prolog_;
- uint8_t count_of_codes_;
- uint8_t frame_register_, frame_offset_;
-};
-
-typedef std::vector<exception_entry> exception_entry_list;
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_exports.cpp b/tools/pe_bliss/pe_exports.cpp
deleted file mode 100644
index c2ad895554..0000000000
--- a/tools/pe_bliss/pe_exports.cpp
+++ /dev/null
@@ -1,700 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <set>
-#include <algorithm>
-#include <string.h>
-#include "pe_exports.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXPORTS
-//Default constructor
-exported_function::exported_function()
- :ordinal_(0), rva_(0), has_name_(false), name_ordinal_(0), forward_(false)
-{}
-
-//Returns ordinal of function (actually, ordinal = hint + ordinal base)
-uint16_t exported_function::get_ordinal() const
-{
- return ordinal_;
-}
-
-//Returns RVA of function
-uint32_t exported_function::get_rva() const
-{
- return rva_;
-}
-
-//Returns name of function
-const std::string& exported_function::get_name() const
-{
- return name_;
-}
-
-//Returns true if function has name and name ordinal
-bool exported_function::has_name() const
-{
- return has_name_;
-}
-
-//Returns name ordinal of function
-uint16_t exported_function::get_name_ordinal() const
-{
- return name_ordinal_;
-}
-
-//Returns true if function is forwarded to other library
-bool exported_function::is_forwarded() const
-{
- return forward_;
-}
-
-//Returns the name of forwarded function
-const std::string& exported_function::get_forwarded_name() const
-{
- return forward_name_;
-}
-
-//Sets ordinal of function
-void exported_function::set_ordinal(uint16_t ordinal)
-{
- ordinal_ = ordinal;
-}
-
-//Sets RVA of function
-void exported_function::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets name of function (or clears it, if empty name is passed)
-void exported_function::set_name(const std::string& name)
-{
- name_ = name;
- has_name_ = !name.empty();
-}
-
-//Sets name ordinal
-void exported_function::set_name_ordinal(uint16_t name_ordinal)
-{
- name_ordinal_ = name_ordinal;
-}
-
-//Sets forwarded function name (or clears it, if empty name is passed)
-void exported_function::set_forwarded_name(const std::string& name)
-{
- forward_name_ = name;
- forward_ = !name.empty();
-}
-
-//Default constructor
-export_info::export_info()
- :characteristics_(0),
- timestamp_(0),
- major_version_(0),
- minor_version_(0),
- ordinal_base_(0),
- number_of_functions_(0),
- number_of_names_(0),
- address_of_functions_(0),
- address_of_names_(0),
- address_of_name_ordinals_(0)
-{}
-
-//Returns characteristics
-uint32_t export_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns timestamp
-uint32_t export_info::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns major version
-uint16_t export_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version
-uint16_t export_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns DLL name
-const std::string& export_info::get_name() const
-{
- return name_;
-}
-
-//Returns ordinal base
-uint32_t export_info::get_ordinal_base() const
-{
- return ordinal_base_;
-}
-
-//Returns number of functions
-uint32_t export_info::get_number_of_functions() const
-{
- return number_of_functions_;
-}
-
-//Returns number of function names
-uint32_t export_info::get_number_of_names() const
-{
- return number_of_names_;
-}
-
-//Returns RVA of function address table
-uint32_t export_info::get_rva_of_functions() const
-{
- return address_of_functions_;
-}
-
-//Returns RVA of function name address table
-uint32_t export_info::get_rva_of_names() const
-{
- return address_of_names_;
-}
-
-//Returns RVA of name ordinals table
-uint32_t export_info::get_rva_of_name_ordinals() const
-{
- return address_of_name_ordinals_;
-}
-
-//Sets characteristics
-void export_info::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets timestamp
-void export_info::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Sets major version
-void export_info::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version
-void export_info::set_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Sets DLL name
-void export_info::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets ordinal base
-void export_info::set_ordinal_base(uint32_t ordinal_base)
-{
- ordinal_base_ = ordinal_base;
-}
-
-//Sets number of functions
-void export_info::set_number_of_functions(uint32_t number_of_functions)
-{
- number_of_functions_ = number_of_functions;
-}
-
-//Sets number of function names
-void export_info::set_number_of_names(uint32_t number_of_names)
-{
- number_of_names_ = number_of_names;
-}
-
-//Sets RVA of function address table
-void export_info::set_rva_of_functions(uint32_t rva_of_functions)
-{
- address_of_functions_ = rva_of_functions;
-}
-
-//Sets RVA of function name address table
-void export_info::set_rva_of_names(uint32_t rva_of_names)
-{
- address_of_names_ = rva_of_names;
-}
-
-//Sets RVA of name ordinals table
-void export_info::set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals)
-{
- address_of_name_ordinals_ = rva_of_name_ordinals;
-}
-
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info);
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe)
-{
- return get_exported_functions(pe, 0);
-}
-
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info)
-{
- return get_exported_functions(pe, &info);
-}
-
-//Helper: sorts exported function list by ordinals
-struct ordinal_sorter
-{
-public:
- bool operator()(const exported_function& func1, const exported_function& func2) const;
-};
-
-//Returns array of exported functions and information about export (if info != 0)
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info)
-{
- //Returned exported functions info array
- std::vector<exported_function> ret;
-
- if(pe.has_exports())
- {
- //Check the length in bytes of the section containing export directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_export),
- pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true)
- < sizeof(image_export_directory))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- image_export_directory exports = pe.section_data_from_rva<image_export_directory>(pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true);
-
- unsigned long max_name_length;
-
- if(info)
- {
- //Save some export info data
- info->set_characteristics(exports.Characteristics);
- info->set_major_version(exports.MajorVersion);
- info->set_minor_version(exports.MinorVersion);
-
- //Get byte count that we have for dll name
- if((max_name_length = pe.section_data_length_from_rva(exports.Name, exports.Name, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get dll name pointer
- const char* dll_name = pe.section_data_from_rva(exports.Name, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(dll_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Save the rest of export information data
- info->set_name(dll_name);
- info->set_number_of_functions(exports.NumberOfFunctions);
- info->set_number_of_names(exports.NumberOfNames);
- info->set_ordinal_base(exports.Base);
- info->set_rva_of_functions(exports.AddressOfFunctions);
- info->set_rva_of_names(exports.AddressOfNames);
- info->set_rva_of_name_ordinals(exports.AddressOfNameOrdinals);
- info->set_timestamp(exports.TimeDateStamp);
- }
-
- if(!exports.NumberOfFunctions)
- return ret;
-
- //Check IMAGE_EXPORT_DIRECTORY fields
- if(exports.NumberOfNames > exports.NumberOfFunctions)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Check some export directory fields
- if((!exports.AddressOfNameOrdinals && exports.AddressOfNames) ||
- (exports.AddressOfNameOrdinals && !exports.AddressOfNames) ||
- !exports.AddressOfFunctions
- || exports.NumberOfFunctions >= pe_utils::max_dword / sizeof(uint32_t)
- || exports.NumberOfNames > pe_utils::max_dword / sizeof(uint32_t)
- || !pe_utils::is_sum_safe(exports.AddressOfFunctions, exports.NumberOfFunctions * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(exports.AddressOfNames, exports.NumberOfNames * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(exports.AddressOfNameOrdinals, exports.NumberOfFunctions * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_export), pe.get_directory_size(image_directory_entry_export)))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Check if it is enough bytes to hold AddressOfFunctions table
- if(pe.section_data_length_from_rva(exports.AddressOfFunctions, exports.AddressOfFunctions, section_data_virtual, true)
- < exports.NumberOfFunctions * sizeof(uint32_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- if(exports.AddressOfNames)
- {
- //Check if it is enough bytes to hold name and ordinal tables
- if(pe.section_data_length_from_rva(exports.AddressOfNameOrdinals, exports.AddressOfNameOrdinals, section_data_virtual, true)
- < exports.NumberOfNames * sizeof(uint16_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- if(pe.section_data_length_from_rva(exports.AddressOfNames, exports.AddressOfNames, section_data_virtual, true)
- < exports.NumberOfNames * sizeof(uint32_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
- }
-
- for(uint32_t ordinal = 0; ordinal < exports.NumberOfFunctions; ordinal++)
- {
- //Get function address
- //Sum and multiplication are safe (checked above)
- uint32_t rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfFunctions + ordinal * sizeof(uint32_t), section_data_virtual, true);
-
- //If we have a skip
- if(!rva)
- continue;
-
- exported_function func;
- func.set_rva(rva);
-
- if(!pe_utils::is_sum_safe(exports.Base, ordinal) || exports.Base + ordinal > pe_utils::max_word)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- func.set_ordinal(static_cast<uint16_t>(ordinal + exports.Base));
-
- //Scan for function name ordinal
- for(uint32_t i = 0; i < exports.NumberOfNames; i++)
- {
- uint16_t ordinal2 = pe.section_data_from_rva<uint16_t>(exports.AddressOfNameOrdinals + i * sizeof(uint16_t), section_data_virtual, true);
-
- //If function has name (and name ordinal)
- if(ordinal == ordinal2)
- {
- //Get function name
- //Sum and multiplication are safe (checked above)
- uint32_t function_name_rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfNames + i * sizeof(uint32_t), section_data_virtual, true);
-
- //Get byte count that we have for function name
- if((max_name_length = pe.section_data_length_from_rva(function_name_rva, function_name_rva, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get function name pointer
- const char* func_name = pe.section_data_from_rva(function_name_rva, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(func_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Save function info
- func.set_name(func_name);
- func.set_name_ordinal(ordinal2);
-
- //If the function is just a redirect, save its name
- if(rva >= pe.get_directory_rva(image_directory_entry_export) + sizeof(image_directory_entry_export) &&
- rva < pe.get_directory_rva(image_directory_entry_export) + pe.get_directory_size(image_directory_entry_export))
- {
- if((max_name_length = pe.section_data_length_from_rva(rva, rva, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get forwarded function name pointer
- const char* forwarded_func_name = pe.section_data_from_rva(rva, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(forwarded_func_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Set the name of forwarded function
- func.set_forwarded_name(forwarded_func_name);
- }
-
- break;
- }
- }
-
- //Add function info to output array
- ret.push_back(func);
- }
- }
-
- return ret;
-}
-
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports)
-{
- if(exports.empty())
- return std::make_pair(0, 0);
-
- uint16_t max_ordinal = 0; //Maximum ordinal number
- uint16_t ordinal_base = pe_utils::max_word; //Minimum ordinal value
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
-
- //Calculate maximum and minimum ordinal numbers
- max_ordinal = std::max<uint16_t>(max_ordinal, func.get_ordinal());
- ordinal_base = std::min<uint16_t>(ordinal_base, func.get_ordinal());
- }
-
- return std::make_pair(ordinal_base, max_ordinal);
-}
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports)
-{
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- if((*it).has_name() && (*it).get_name() == function_name)
- return true;
- }
-
- return false;
-}
-
-//Checks if exported function name already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports)
-{
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- if((*it).get_ordinal() == ordinal)
- return true;
- }
-
- return false;
-}
-
-//Helper: sorts exported function list by ordinals
-bool ordinal_sorter::operator()(const exported_function& func1, const exported_function& func2) const
-{
- return func1.get_ordinal() < func2.get_ordinal();
-}
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that exports_section is attached to this PE image
- if(!pe.section_attached(exports_section))
- throw pe_exception("Exports section must be attached to PE file", pe_exception::section_is_not_attached);
-
- //Needed space for strings
- uint32_t needed_size_for_strings = static_cast<uint32_t>(info.get_name().length() + 1);
- uint32_t number_of_names = 0; //Number of named functions
- uint32_t max_ordinal = 0; //Maximum ordinal number
- uint32_t ordinal_base = static_cast<uint32_t>(-1); //Minimum ordinal value
-
- if(exports.empty())
- ordinal_base = info.get_ordinal_base();
-
- uint32_t needed_size_for_function_names = 0; //Needed space for function name strings
- uint32_t needed_size_for_function_forwards = 0; //Needed space for function forwards names
-
- //List all exported functions
- //Calculate needed size for function list
- {
- //Also check that there're no duplicate names and ordinals
- std::set<std::string> used_function_names;
- std::set<uint16_t> used_function_ordinals;
-
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
- //Calculate maximum and minimum ordinal numbers
- max_ordinal = std::max<uint32_t>(max_ordinal, func.get_ordinal());
- ordinal_base = std::min<uint32_t>(ordinal_base, func.get_ordinal());
-
- //Check if ordinal is unique
- if(!used_function_ordinals.insert(func.get_ordinal()).second)
- throw pe_exception("Duplicate exported function ordinal", pe_exception::duplicate_exported_function_ordinal);
-
- if(func.has_name())
- {
- //If function is named
- ++number_of_names;
- needed_size_for_function_names += static_cast<uint32_t>(func.get_name().length() + 1);
-
- //Check if it's name and name ordinal are unique
- if(!used_function_names.insert(func.get_name()).second)
- throw pe_exception("Duplicate exported function name", pe_exception::duplicate_exported_function_name);
- }
-
- //If function is forwarded to another DLL
- if(func.is_forwarded())
- needed_size_for_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
- }
- }
-
- //Sort functions by ordinal value
- std::sort(exports.begin(), exports.end(), ordinal_sorter());
-
- //Calculate needed space for different things...
- needed_size_for_strings += needed_size_for_function_names;
- needed_size_for_strings += needed_size_for_function_forwards;
- uint32_t needed_size_for_function_name_ordinals = number_of_names * sizeof(uint16_t);
- uint32_t needed_size_for_function_name_rvas = number_of_names * sizeof(uint32_t);
- uint32_t needed_size_for_function_addresses = (max_ordinal - ordinal_base + 1) * sizeof(uint32_t);
-
- //Export directory header will be placed first
- uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
- uint32_t needed_size = sizeof(image_export_directory); //Calculate needed size for export tables and strings
- //sizeof(IMAGE_EXPORT_DIRECTORY) = export directory header
-
- //Total needed space...
- needed_size += needed_size_for_function_name_ordinals; //For list of names ordinals
- needed_size += needed_size_for_function_addresses; //For function RVAs
- needed_size += needed_size_for_strings; //For all strings
- needed_size += needed_size_for_function_name_rvas; //For function name strings RVAs
-
- //Check if exports_section is last one. If it's not, check if there's enough place for exports data
- if(&exports_section != &*(pe.get_image_sections().end() - 1) &&
- (exports_section.empty() || pe_utils::align_up(exports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
- throw pe_exception("Insufficient space for export directory", pe_exception::insufficient_space);
-
- std::string& raw_data = exports_section.get_raw_data();
-
- //This will be done only if exports_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + directory_pos)
- raw_data.resize(needed_size + directory_pos); //Expand section raw data
-
- //Library name will be placed after it
- uint32_t current_pos_of_function_names = static_cast<uint32_t>(info.get_name().length() + 1 + directory_pos + sizeof(image_export_directory));
- //Next - function names
- uint32_t current_pos_of_function_name_ordinals = current_pos_of_function_names + needed_size_for_function_names;
- //Next - function name ordinals
- uint32_t current_pos_of_function_forwards = current_pos_of_function_name_ordinals + needed_size_for_function_name_ordinals;
- //Finally - function addresses
- uint32_t current_pos_of_function_addresses = current_pos_of_function_forwards + needed_size_for_function_forwards;
- //Next - function names RVAs
- uint32_t current_pos_of_function_names_rvas = current_pos_of_function_addresses + needed_size_for_function_addresses;
-
- {
- //Create export directory and fill it
- image_export_directory dir = {0};
- dir.Characteristics = info.get_characteristics();
- dir.MajorVersion = info.get_major_version();
- dir.MinorVersion = info.get_minor_version();
- dir.TimeDateStamp = info.get_timestamp();
- dir.NumberOfFunctions = max_ordinal - ordinal_base + 1;
- dir.NumberOfNames = number_of_names;
- dir.Base = ordinal_base;
- dir.AddressOfFunctions = pe.rva_from_section_offset(exports_section, current_pos_of_function_addresses);
- dir.AddressOfNameOrdinals = pe.rva_from_section_offset(exports_section, current_pos_of_function_name_ordinals);
- dir.AddressOfNames = pe.rva_from_section_offset(exports_section, current_pos_of_function_names_rvas);
- dir.Name = pe.rva_from_section_offset(exports_section, directory_pos + sizeof(image_export_directory));
-
- //Save it
- memcpy(&raw_data[directory_pos], &dir, sizeof(dir));
- }
-
- //Sve library name
- memcpy(&raw_data[directory_pos + sizeof(image_export_directory)], info.get_name().c_str(), info.get_name().length() + 1);
-
- //A map to sort function names alphabetically
- typedef std::map<std::string, uint16_t> funclist; //function name; function name ordinal
- funclist funcs;
-
- uint32_t last_ordinal = ordinal_base;
- //Enumerate all exported functions
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
-
- //If we're skipping some ordinals...
- if(func.get_ordinal() > last_ordinal)
- {
- //Fill this function RVAs data with zeros
- uint32_t len = sizeof(uint32_t) * (func.get_ordinal() - last_ordinal - 1);
- if(len)
- {
- memset(&raw_data[current_pos_of_function_addresses], 0, len);
- current_pos_of_function_addresses += len;
- }
-
- //Save last encountered ordinal
- last_ordinal = func.get_ordinal();
- }
-
- //If function is named, save its name ordinal and name in sorted alphabetically order
- if(func.has_name())
- funcs.insert(std::make_pair(func.get_name(), static_cast<uint16_t>(func.get_ordinal() - ordinal_base))); //Calculate name ordinal
-
- //If function is forwarded to another DLL
- if(func.is_forwarded())
- {
- //Write its forwarded name and its RVA
- uint32_t function_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_forwards);
- memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
- current_pos_of_function_addresses += sizeof(function_rva);
-
- memcpy(&raw_data[current_pos_of_function_forwards], func.get_forwarded_name().c_str(), func.get_forwarded_name().length() + 1);
- current_pos_of_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
- }
- else
- {
- //Write actual function RVA
- uint32_t function_rva = func.get_rva();
- memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
- current_pos_of_function_addresses += sizeof(function_rva);
- }
- }
-
- //Enumerate sorted function names
- for(funclist::const_iterator it = funcs.begin(); it != funcs.end(); ++it)
- {
- //Save function name RVA
- uint32_t function_name_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_names);
- memcpy(&raw_data[current_pos_of_function_names_rvas], &function_name_rva, sizeof(function_name_rva));
- current_pos_of_function_names_rvas += sizeof(function_name_rva);
-
- //Save function name
- memcpy(&raw_data[current_pos_of_function_names], (*it).first.c_str(), (*it).first.length() + 1);
- current_pos_of_function_names += static_cast<uint32_t>((*it).first.length() + 1);
-
- //Save function name ordinal
- uint16_t name_ordinal = (*it).second;
- memcpy(&raw_data[current_pos_of_function_name_ordinals], &name_ordinal, sizeof(name_ordinal));
- current_pos_of_function_name_ordinals += sizeof(name_ordinal);
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(exports_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(exports_section, directory_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_export, ret.get_rva());
- pe.set_directory_size(image_directory_entry_export, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_exports.h b/tools/pe_bliss/pe_exports.h
deleted file mode 100644
index 127cf86ed6..0000000000
--- a/tools/pe_bliss/pe_exports.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing exported function
-class exported_function
-{
-public:
- //Default constructor
- exported_function();
-
- //Returns ordinal of function (actually, ordinal = hint + ordinal base)
- uint16_t get_ordinal() const;
-
- //Returns RVA of function
- uint32_t get_rva() const;
-
- //Returns true if function has name and name ordinal
- bool has_name() const;
- //Returns name of function
- const std::string& get_name() const;
- //Returns name ordinal of function
- uint16_t get_name_ordinal() const;
-
- //Returns true if function is forwarded to other library
- bool is_forwarded() const;
- //Returns the name of forwarded function
- const std::string& get_forwarded_name() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild export directory
-
- //Sets ordinal of function
- void set_ordinal(uint16_t ordinal);
-
- //Sets RVA of function
- void set_rva(uint32_t rva);
-
- //Sets name of function (or clears it, if empty name is passed)
- void set_name(const std::string& name);
- //Sets name ordinal
- void set_name_ordinal(uint16_t name_ordinal);
-
- //Sets forwarded function name (or clears it, if empty name is passed)
- void set_forwarded_name(const std::string& name);
-
-private:
- uint16_t ordinal_; //Function ordinal
- uint32_t rva_; //Function RVA
- std::string name_; //Function name
- bool has_name_; //true == function has name
- uint16_t name_ordinal_; //Function name ordinal
- bool forward_; //true == function is forwarded
- std::string forward_name_; //Name of forwarded function
-};
-
-//Class representing export information
-class export_info
-{
-public:
- //Default constructor
- export_info();
-
- //Returns characteristics
- uint32_t get_characteristics() const;
- //Returns timestamp
- uint32_t get_timestamp() const;
- //Returns major version
- uint16_t get_major_version() const;
- //Returns minor version
- uint16_t get_minor_version() const;
- //Returns DLL name
- const std::string& get_name() const;
- //Returns ordinal base
- uint32_t get_ordinal_base() const;
- //Returns number of functions
- uint32_t get_number_of_functions() const;
- //Returns number of function names
- uint32_t get_number_of_names() const;
- //Returns RVA of function address table
- uint32_t get_rva_of_functions() const;
- //Returns RVA of function name address table
- uint32_t get_rva_of_names() const;
- //Returns RVA of name ordinals table
- uint32_t get_rva_of_name_ordinals() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild export directory using rebuild_exports
-
- //Sets characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
- //Sets major version
- void set_major_version(uint16_t major_version);
- //Sets minor version
- void set_minor_version(uint16_t minor_version);
- //Sets DLL name
- void set_name(const std::string& name);
- //Sets ordinal base
- void set_ordinal_base(uint32_t ordinal_base);
- //Sets number of functions
- void set_number_of_functions(uint32_t number_of_functions);
- //Sets number of function names
- void set_number_of_names(uint32_t number_of_names);
- //Sets RVA of function address table
- void set_rva_of_functions(uint32_t rva_of_functions);
- //Sets RVA of function name address table
- void set_rva_of_names(uint32_t rva_of_names);
- //Sets RVA of name ordinals table
- void set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals);
-
-private:
- uint32_t characteristics_;
- uint32_t timestamp_;
- uint16_t major_version_;
- uint16_t minor_version_;
- std::string name_;
- uint32_t ordinal_base_;
- uint32_t number_of_functions_;
- uint32_t number_of_names_;
- uint32_t address_of_functions_;
- uint32_t address_of_names_;
- uint32_t address_of_name_ordinals_;
-};
-
-//Exported functions list typedef
-typedef std::vector<exported_function> exported_functions_list;
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe);
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info);
-
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports);
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports);
-
-//Checks if exported function ordinal already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports);
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_factory.cpp b/tools/pe_bliss/pe_factory.cpp
deleted file mode 100644
index f6d8a3e1ed..0000000000
--- a/tools/pe_bliss/pe_factory.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_factory.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-pe_base pe_factory::create_pe(std::istream& file, bool read_debug_raw_data)
-{
- return pe_base::get_pe_type(file) == pe_type_32
- ? pe_base(file, pe_properties_32(), read_debug_raw_data)
- : pe_base(file, pe_properties_64(), read_debug_raw_data);
-}
-
-pe_base pe_factory::create_pe(const char* file_path, bool read_debug_raw_data)
-{
- std::ifstream pe_file(file_path, std::ios::in | std::ios::binary);
- if(!pe_file)
- {
- throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
- }
- return pe_factory::create_pe(pe_file,read_debug_raw_data);
-}
-}
diff --git a/tools/pe_bliss/pe_factory.h b/tools/pe_bliss/pe_factory.h
deleted file mode 100644
index 60b42d9b71..0000000000
--- a/tools/pe_bliss/pe_factory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include <fstream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class pe_factory
-{
-public:
- //Creates pe_base class instance from PE or PE+ istream
- //If read_bound_import_raw_data, raw bound import data will be read (used to get bound import info)
- //If read_debug_raw_data, raw debug data will be read (used to get image debug info)
- static pe_base create_pe(std::istream& file, bool read_debug_raw_data = true);
- static pe_base create_pe(const char* file_path, bool read_debug_raw_data = true);
-};
-}
diff --git a/tools/pe_bliss/pe_imports.cpp b/tools/pe_bliss/pe_imports.cpp
deleted file mode 100644
index 0a6c01d6c0..0000000000
--- a/tools/pe_bliss/pe_imports.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_imports.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMPORTS
-//Default constructor
-//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
-//to new value after import rebuilding
-//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
-//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
-//to be able to modify IAT thunks
-import_rebuilder_settings::import_rebuilder_settings(bool set_to_pe_headers, bool auto_zero_directory_entry_iat)
- :offset_from_section_start_(0),
- build_original_iat_(true),
- save_iat_and_original_iat_rvas_(true),
- fill_missing_original_iats_(false),
- set_to_pe_headers_(set_to_pe_headers),
- zero_directory_entry_iat_(auto_zero_directory_entry_iat),
- rewrite_iat_and_original_iat_contents_(false),
- auto_strip_last_section_(true)
-{}
-
-//Returns offset from section start where import directory data will be placed
-uint32_t import_rebuilder_settings::get_offset_from_section_start() const
-{
- return offset_from_section_start_;
-}
-
-//Returns true if Original import address table (IAT) will be rebuilt
-bool import_rebuilder_settings::build_original_iat() const
-{
- return build_original_iat_;
-}
-
-//Returns true if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-bool import_rebuilder_settings::save_iat_and_original_iat_rvas() const
-{
- return save_iat_and_original_iat_rvas_;
-}
-
-//Returns true if Original import address and import address tables contents will be rewritten
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-//and save_iat_and_original_iat_rvas is true
-bool import_rebuilder_settings::rewrite_iat_and_original_iat_contents() const
-{
- return rewrite_iat_and_original_iat_contents_;
-}
-
-//Returns true if original missing IATs will be rebuilt
-//(only if IATs are saved)
-bool import_rebuilder_settings::fill_missing_original_iats() const
-{
- return fill_missing_original_iats_;
-}
-
-//Returns true if PE headers should be updated automatically after rebuilding of imports
-bool import_rebuilder_settings::auto_set_to_pe_headers() const
-{
- return set_to_pe_headers_;
-}
-
-//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-bool import_rebuilder_settings::zero_directory_entry_iat() const
-{
- return zero_directory_entry_iat_;
-}
-
-//Returns true if the last section should be stripped automatically, if imports are inside it
-bool import_rebuilder_settings::auto_strip_last_section_enabled() const
-{
- return auto_strip_last_section_;
-}
-
-//Sets offset from section start where import directory data will be placed
-void import_rebuilder_settings::set_offset_from_section_start(uint32_t offset)
-{
- offset_from_section_start_ = offset;
-}
-
-//Sets if Original import address table (IAT) will be rebuilt
-void import_rebuilder_settings::build_original_iat(bool enable)
-{
- build_original_iat_ = enable;
-}
-
-//Sets if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-void import_rebuilder_settings::save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents)
-{
- save_iat_and_original_iat_rvas_ = enable;
- if(save_iat_and_original_iat_rvas_)
- rewrite_iat_and_original_iat_contents_ = enable_rewrite_iat_and_original_iat_contents;
- else
- rewrite_iat_and_original_iat_contents_ = false;
-}
-
-//Sets if original missing IATs will be rebuilt
-//(only if IATs are saved)
-void import_rebuilder_settings::fill_missing_original_iats(bool enable)
-{
- fill_missing_original_iats_ = enable;
-}
-
-//Sets if PE headers should be updated automatically after rebuilding of imports
-void import_rebuilder_settings::auto_set_to_pe_headers(bool enable)
-{
- set_to_pe_headers_ = enable;
-}
-
-//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-void import_rebuilder_settings::zero_directory_entry_iat(bool enable)
-{
- zero_directory_entry_iat_ = enable;
-}
-
-//Sets if the last section should be stripped automatically, if imports are inside it, default true
-void import_rebuilder_settings::enable_auto_strip_last_section(bool enable)
-{
- auto_strip_last_section_ = enable;
-}
-
-//Default constructor
-imported_function::imported_function()
- :hint_(0), ordinal_(0), iat_va_(0)
-{}
-
-//Returns name of function
-const std::string& imported_function::get_name() const
-{
- return name_;
-}
-
-//Returns true if imported function has name (and hint)
-bool imported_function::has_name() const
-{
- return !name_.empty();
-}
-
-//Returns hint
-uint16_t imported_function::get_hint() const
-{
- return hint_;
-}
-
-//Returns ordinal of function
-uint16_t imported_function::get_ordinal() const
-{
- return ordinal_;
-}
-
-//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
-uint64_t imported_function::get_iat_va() const
-{
- return iat_va_;
-}
-
-//Sets name of function
-void imported_function::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets hint
-void imported_function::set_hint(uint16_t hint)
-{
- hint_ = hint;
-}
-
-//Sets ordinal
-void imported_function::set_ordinal(uint16_t ordinal)
-{
- ordinal_ = ordinal;
-}
-
-//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
-void imported_function::set_iat_va(uint64_t va)
-{
- iat_va_ = va;
-}
-
-//Default constructor
-import_library::import_library()
- :rva_to_iat_(0), rva_to_original_iat_(0), timestamp_(0)
-{}
-
-//Returns name of library
-const std::string& import_library::get_name() const
-{
- return name_;
-}
-
-//Returns RVA to Import Address Table (IAT)
-uint32_t import_library::get_rva_to_iat() const
-{
- return rva_to_iat_;
-}
-
-//Returns RVA to Original Import Address Table (Original IAT)
-uint32_t import_library::get_rva_to_original_iat() const
-{
- return rva_to_original_iat_;
-}
-
-//Returns timestamp
-uint32_t import_library::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Sets name of library
-void import_library::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets RVA to Import Address Table (IAT)
-void import_library::set_rva_to_iat(uint32_t rva_to_iat)
-{
- rva_to_iat_ = rva_to_iat;
-}
-
-//Sets RVA to Original Import Address Table (Original IAT)
-void import_library::set_rva_to_original_iat(uint32_t rva_to_original_iat)
-{
- rva_to_original_iat_ = rva_to_original_iat;
-}
-
-//Sets timestamp
-void import_library::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Returns imported functions list
-const import_library::imported_list& import_library::get_imported_functions() const
-{
- return imports_;
-}
-
-//Adds imported function
-void import_library::add_import(const imported_function& func)
-{
- imports_.push_back(func);
-}
-
-//Clears imported functions list
-void import_library::clear_imports()
-{
- imports_.clear();
-}
-
-const imported_functions_list get_imported_functions(const pe_base& pe)
-{
- return (pe.get_pe_type() == pe_type_32 ?
- get_imported_functions_base<pe_types_class_32>(pe)
- : get_imported_functions_base<pe_types_class_64>(pe));
-}
-
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
- return (pe.get_pe_type() == pe_type_32 ?
- rebuild_imports_base<pe_types_class_32>(pe, imports, import_section, import_settings)
- : rebuild_imports_base<pe_types_class_64>(pe, imports, import_section, import_settings));
-}
-
-//Returns imported functions list with related libraries info
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe)
-{
- imported_functions_list ret;
-
- //If image has no imports, return empty array
- if(!pe.has_imports())
- return ret;
-
- unsigned long current_descriptor_pos = pe.get_directory_rva(image_directory_entry_import);
- //Get first IMAGE_IMPORT_DESCRIPTOR
- image_import_descriptor import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
- //Iterate them until we reach zero-element
- //We don't need to check correctness of this, because exception will be thrown
- //inside of loop if we go outsize of section
- while(import_descriptor.Name)
- {
- //Get imported library information
- import_library lib;
-
- unsigned long max_name_length;
- //Get byte count that we have for library name
- if((max_name_length = pe.section_data_length_from_rva(import_descriptor.Name, import_descriptor.Name, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get DLL name pointer
- const char* dll_name = pe.section_data_from_rva(import_descriptor.Name, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(dll_name, max_name_length))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Set library name
- lib.set_name(dll_name);
- //Set library timestamp
- lib.set_timestamp(import_descriptor.TimeDateStamp);
- //Set library RVA to IAT and original IAT
- lib.set_rva_to_iat(import_descriptor.FirstThunk);
- lib.set_rva_to_original_iat(import_descriptor.OriginalFirstThunk);
-
- //Get RVA to IAT (it must be filled by loader when loading PE)
- uint32_t current_thunk_rva = import_descriptor.FirstThunk;
- typename PEClassType::BaseSize import_address_table = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
-
- //Get RVA to original IAT (lookup table), which must handle imported functions names
- //Some linkers leave this pointer zero-filled
- //Such image is valid, but it is not possible to restore imported functions names
- //afted image was loaded, because IAT becomes the only one table
- //containing both function names and function RVAs after loading
- uint32_t current_original_thunk_rva = import_descriptor.OriginalFirstThunk;
- typename PEClassType::BaseSize import_lookup_table = current_original_thunk_rva == 0 ? import_address_table : pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
- if(current_original_thunk_rva == 0)
- current_original_thunk_rva = current_thunk_rva;
-
- //List all imported functions for current DLL
- if(import_lookup_table != 0 && import_address_table != 0)
- {
- while(true)
- {
- //Imported function description
- imported_function func;
-
- //Get VA from IAT
- typename PEClassType::BaseSize address = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
- //Move pointer
- current_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
- //Jump to next DLL if we finished with this one
- if(!address)
- break;
-
- func.set_iat_va(address);
-
- //Get VA from original IAT
- typename PEClassType::BaseSize lookup = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
- //Move pointer
- current_original_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
- //Check if function is imported by ordinal
- if((lookup & PEClassType::ImportSnapFlag) != 0)
- {
- //Set function ordinal
- func.set_ordinal(static_cast<uint16_t>(lookup & 0xffff));
- }
- else
- {
- //Get byte count that we have for function name
- if(lookup > static_cast<uint32_t>(-1) - sizeof(uint16_t))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get maximum available length of function name
- if((max_name_length = pe.section_data_length_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get imported function name
- const char* func_name = pe.section_data_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(func_name, max_name_length))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //HINT in import table is ORDINAL in export table
- uint16_t hint = pe.section_data_from_rva<uint16_t>(static_cast<uint32_t>(lookup), section_data_virtual, true);
-
- //Save hint and name
- func.set_name(func_name);
- func.set_hint(hint);
- }
-
- //Add function to list
- lib.add_import(func);
- }
- }
-
- //Check possible overflow
- if(!pe_utils::is_sum_safe(current_descriptor_pos, sizeof(image_import_descriptor)))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Go to next library
- current_descriptor_pos += sizeof(image_import_descriptor);
- import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
- //Save import information
- ret.push_back(lib);
- }
-
- //Return resulting list
- return ret;
-}
-
-
-//Simple import directory rebuilder
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
- //Check that import_section is attached to this PE image
- if(!pe.section_attached(import_section))
- throw pe_exception("Import section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t needed_size = 0; //Calculate needed size for import structures and strings
- uint32_t needed_size_for_strings = 0; //Calculate needed size for import strings (library and function names and hints)
- uint32_t size_of_iat = 0; //Size of IAT structures
-
- needed_size += static_cast<uint32_t>((1 /* ending null descriptor */ + imports.size()) * sizeof(image_import_descriptor));
-
- //Enumerate imported functions
- for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- needed_size_for_strings += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-
- const import_library::imported_list& funcs = (*it).get_imported_functions();
-
- //IMAGE_THUNK_DATA
- size_of_iat += static_cast<uint32_t>(sizeof(typename PEClassType::BaseSize) * (1 /*ending null */ + funcs.size()));
-
- //Enumerate all imported functions in library
- for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
- {
- if((*f).has_name())
- needed_size_for_strings += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
- }
- }
-
- if(import_settings.build_original_iat() || import_settings.fill_missing_original_iats())
- needed_size += size_of_iat * 2; //We'll have two similar-sized IATs if we're building original IAT
- else
- needed_size += size_of_iat;
-
- needed_size += sizeof(typename PEClassType::BaseSize); //Maximum align for IAT and original IAT
-
- //Total needed size for import structures and strings
- needed_size += needed_size_for_strings;
-
- //Check if import_section is last one. If it's not, check if there's enough place for import data
- if(&import_section != &*(pe.get_image_sections().end() - 1) &&
- (import_section.empty() || pe_utils::align_up(import_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + import_settings.get_offset_from_section_start()))
- throw pe_exception("Insufficient space for import directory", pe_exception::insufficient_space);
-
- std::string& raw_data = import_section.get_raw_data();
-
- //This will be done only if image_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + import_settings.get_offset_from_section_start())
- raw_data.resize(needed_size + import_settings.get_offset_from_section_start()); //Expand section raw data
-
- uint32_t current_string_pointer = import_settings.get_offset_from_section_start();/* we will paste structures after strings */
-
- //Position for IAT
- uint32_t current_pos_for_iat = pe_utils::align_up(static_cast<uint32_t>(needed_size_for_strings + import_settings.get_offset_from_section_start() + (1 + imports.size()) * sizeof(image_import_descriptor)), sizeof(typename PEClassType::BaseSize));
- //Position for original IAT
- uint32_t current_pos_for_original_iat = current_pos_for_iat + size_of_iat;
- //Position for import descriptors
- uint32_t current_pos_for_descriptors = needed_size_for_strings + import_settings.get_offset_from_section_start();
-
- //Build imports
- for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- //Create import descriptor
- image_import_descriptor descr;
- memset(&descr, 0, sizeof(descr));
- descr.TimeDateStamp = (*it).get_timestamp(); //Restore timestamp
- descr.Name = pe.rva_from_section_offset(import_section, current_string_pointer); //Library name RVA
-
- //If we should save IAT for current import descriptor
- bool save_iats_for_this_descriptor = import_settings.save_iat_and_original_iat_rvas() && (*it).get_rva_to_iat() != 0;
- //If we should write original IAT
- bool write_original_iat = (!save_iats_for_this_descriptor && import_settings.build_original_iat()) || import_settings.fill_missing_original_iats();
-
- //If we should rewrite saved original IAT for current import descriptor (without changing its position)
- bool rewrite_saved_original_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && import_settings.build_original_iat();
- //If we should rewrite saved IAT for current import descriptor (without changing its position)
- bool rewrite_saved_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && (*it).get_rva_to_iat() != 0;
-
- //Helper values if we're rewriting existing IAT or orig.IAT
- uint32_t original_first_thunk = 0;
- uint32_t first_thunk = 0;
-
- if(save_iats_for_this_descriptor)
- {
- //If there's no original IAT and we're asked to rebuild missing original IATs
- if(!(*it).get_rva_to_original_iat() && import_settings.fill_missing_original_iats())
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
- else
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? (*it).get_rva_to_original_iat() : 0;
-
- descr.FirstThunk = (*it).get_rva_to_iat();
-
- original_first_thunk = descr.OriginalFirstThunk;
- first_thunk = descr.FirstThunk;
-
- if(rewrite_saved_original_iat)
- {
- if((*it).get_rva_to_original_iat())
- write_original_iat = true;
- else
- rewrite_saved_original_iat = false;
- }
-
- if(rewrite_saved_iat)
- save_iats_for_this_descriptor = false;
- }
- else
- {
- //We are creating new IAT and original IAT (if needed)
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
- descr.FirstThunk = pe.rva_from_section_offset(import_section, current_pos_for_iat);
- }
-
- //Save import descriptor
- memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
- current_pos_for_descriptors += sizeof(descr);
-
- //Save library name
- memcpy(&raw_data[current_string_pointer], (*it).get_name().c_str(), (*it).get_name().length() + 1 /* nullbyte */);
- current_string_pointer += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-
- //List all imported functions
- const import_library::imported_list& funcs = (*it).get_imported_functions();
- for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
- {
- if((*f).has_name()) //If function is imported by name
- {
- //Get RVA of IMAGE_IMPORT_BY_NAME
- typename PEClassType::BaseSize rva_of_named_import = pe.rva_from_section_offset(import_section, current_string_pointer);
-
- if(!save_iats_for_this_descriptor)
- {
- if(write_original_iat)
- {
- //We're creating original IATs - so we can write to IAT saved VA (because IMAGE_IMPORT_BY_NAME will be read
- //by PE loader from original IAT)
- typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
-
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
- first_thunk += sizeof(iat_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
- current_pos_for_iat += sizeof(rva_of_named_import);
- }
- }
- else
- {
- //Else - write to IAT RVA of IMAGE_IMPORT_BY_NAME
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
- first_thunk += sizeof(rva_of_named_import);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &rva_of_named_import, sizeof(rva_of_named_import));
- current_pos_for_iat += sizeof(rva_of_named_import);
- }
- }
- }
-
- if(write_original_iat)
- {
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
- original_first_thunk += sizeof(rva_of_named_import);
- }
- else
- {
- //We're creating original IATs
- memcpy(&raw_data[current_pos_for_original_iat], &rva_of_named_import, sizeof(rva_of_named_import));
- current_pos_for_original_iat += sizeof(rva_of_named_import);
- }
- }
-
- //Write IMAGE_IMPORT_BY_NAME (WORD hint + string function name)
- uint16_t hint = (*f).get_hint();
- memcpy(&raw_data[current_string_pointer], &hint, sizeof(hint));
- memcpy(&raw_data[current_string_pointer + sizeof(uint16_t)], (*f).get_name().c_str(), (*f).get_name().length() + 1 /* nullbyte */);
- current_string_pointer += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
- }
- else //Function is imported by ordinal
- {
- uint16_t ordinal = (*f).get_ordinal();
- typename PEClassType::BaseSize thunk_value = ordinal;
- thunk_value |= PEClassType::ImportSnapFlag; //Imported by ordinal
-
- if(!save_iats_for_this_descriptor)
- {
- if(write_original_iat)
- {
- //We're creating original IATs - so we can wtire to IAT saved VA (because ordinal will be read
- //by PE loader from original IAT)
- typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
- first_thunk += sizeof(iat_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
- current_pos_for_iat += sizeof(thunk_value);
- }
- }
- else
- {
- //Else - write ordinal to IAT
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
- }
- }
- }
-
- //We're writing ordinal to original IAT slot
- if(write_original_iat)
- {
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- original_first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_original_iat += sizeof(thunk_value);
- }
- }
- }
- }
-
- if(!save_iats_for_this_descriptor)
- {
- //Ending null thunks
- typename PEClassType::BaseSize thunk_value = 0;
-
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_iat += sizeof(thunk_value);
- }
- }
-
- if(write_original_iat)
- {
- //Ending null thunks
- typename PEClassType::BaseSize thunk_value = 0;
-
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- original_first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_original_iat += sizeof(thunk_value);
- }
- }
- }
-
- {
- //Null ending descriptor
- image_import_descriptor descr;
- memset(&descr, 0, sizeof(descr));
- memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
- }
-
- //Strip data a little, if we saved some place
- //We're allocating more space than needed, if present original IAT and IAT are saved
- raw_data.resize(current_pos_for_original_iat);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(import_section, import_settings.auto_strip_last_section_enabled());
-
- //Return information about rebuilt import directory
- image_directory ret(pe.rva_from_section_offset(import_section, import_settings.get_offset_from_section_start() + needed_size_for_strings), needed_size - needed_size_for_strings);
-
- //If auto-rewrite of PE headers is required
- if(import_settings.auto_set_to_pe_headers())
- {
- pe.set_directory_rva(image_directory_entry_import, ret.get_rva());
- pe.set_directory_size(image_directory_entry_import, ret.get_size());
-
- //If we are requested to zero IMAGE_DIRECTORY_ENTRY_IAT also
- if(import_settings.zero_directory_entry_iat())
- {
- pe.set_directory_rva(image_directory_entry_iat, 0);
- pe.set_directory_size(image_directory_entry_iat, 0);
- }
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_imports.h b/tools/pe_bliss/pe_imports.h
deleted file mode 100644
index 681b5b59bd..0000000000
--- a/tools/pe_bliss/pe_imports.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_directory.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing imported function
-class imported_function
-{
-public:
- //Default constructor
- imported_function();
-
- //Returns true if imported function has name (and hint)
- bool has_name() const;
- //Returns name of function
- const std::string& get_name() const;
- //Returns hint
- uint16_t get_hint() const;
- //Returns ordinal of function
- uint16_t get_ordinal() const;
-
- //Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
- uint64_t get_iat_va() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You also can use them to rebuild image imports
- //Sets name of function
- void set_name(const std::string& name);
- //Sets hint
- void set_hint(uint16_t hint);
- //Sets ordinal
- void set_ordinal(uint16_t ordinal);
-
- //Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
- void set_iat_va(uint64_t rva);
-
-private:
- std::string name_; //Function name
- uint16_t hint_; //Hint
- uint16_t ordinal_; //Ordinal
- uint64_t iat_va_;
-};
-
-//Class representing imported library information
-class import_library
-{
-public:
- typedef std::vector<imported_function> imported_list;
-
-public:
- //Default constructor
- import_library();
-
- //Returns name of library
- const std::string& get_name() const;
- //Returns RVA to Import Address Table (IAT)
- uint32_t get_rva_to_iat() const;
- //Returns RVA to Original Import Address Table (Original IAT)
- uint32_t get_rva_to_original_iat() const;
- //Returns timestamp
- uint32_t get_timestamp() const;
-
- //Returns imported functions list
- const imported_list& get_imported_functions() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You also can use them to rebuild image imports
- //Sets name of library
- void set_name(const std::string& name);
- //Sets RVA to Import Address Table (IAT)
- void set_rva_to_iat(uint32_t rva_to_iat);
- //Sets RVA to Original Import Address Table (Original IAT)
- void set_rva_to_original_iat(uint32_t rva_to_original_iat);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
- //Adds imported function
- void add_import(const imported_function& func);
- //Clears imported functions list
- void clear_imports();
-
-private:
- std::string name_; //Library name
- uint32_t rva_to_iat_; //RVA to IAT
- uint32_t rva_to_original_iat_; //RVA to original IAT
- uint32_t timestamp_; //DLL TimeStamp
-
- imported_list imports_;
-};
-
-//Simple import directory rebuilder
-//Class representing import rebuilder advanced settings
-class import_rebuilder_settings
-{
-public:
- //Default constructor
- //Default constructor
- //If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
- //to new value after import rebuilding
- //If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
- //IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
- //to be able to modify IAT thunks
- explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false);
-
- //Returns offset from section start where import directory data will be placed
- uint32_t get_offset_from_section_start() const;
- //Returns true if Original import address table (IAT) will be rebuilt
- bool build_original_iat() const;
-
- //Returns true if Original import address and import address tables will not be rebuilt,
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- bool save_iat_and_original_iat_rvas() const;
- //Returns true if Original import address and import address tables contents will be rewritten
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //and save_iat_and_original_iat_rvas is true
- bool rewrite_iat_and_original_iat_contents() const;
-
- //Returns true if original missing IATs will be rebuilt
- //(only if IATs are saved)
- bool fill_missing_original_iats() const;
- //Returns true if PE headers should be updated automatically after rebuilding of imports
- bool auto_set_to_pe_headers() const;
- //Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
- bool zero_directory_entry_iat() const;
-
- //Returns true if the last section should be stripped automatically, if imports are inside it
- bool auto_strip_last_section_enabled() const;
-
-public: //Setters
- //Sets offset from section start where import directory data will be placed
- void set_offset_from_section_start(uint32_t offset);
- //Sets if Original import address table (IAT) will be rebuilt
- void build_original_iat(bool enable);
- //Sets if Original import address and import address tables will not be rebuilt,
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //and save_iat_and_original_iat_rvas is true
- void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false);
- //Sets if original missing IATs will be rebuilt
- //(only if IATs are saved)
- void fill_missing_original_iats(bool enable);
- //Sets if PE headers should be updated automatically after rebuilding of imports
- void auto_set_to_pe_headers(bool enable);
- //Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
- void zero_directory_entry_iat(bool enable);
-
- //Sets if the last section should be stripped automatically, if imports are inside it, default true
- void enable_auto_strip_last_section(bool enable);
-
-private:
- uint32_t offset_from_section_start_;
- bool build_original_iat_;
- bool save_iat_and_original_iat_rvas_;
- bool fill_missing_original_iats_;
- bool set_to_pe_headers_;
- bool zero_directory_entry_iat_;
- bool rewrite_iat_and_original_iat_contents_;
- bool auto_strip_last_section_;
-};
-
-typedef std::vector<import_library> imported_functions_list;
-
-
-//Returns imported functions list with related libraries info
-const imported_functions_list get_imported_functions(const pe_base& pe);
-
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe);
-
-
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-}
diff --git a/tools/pe_bliss/pe_load_config.cpp b/tools/pe_bliss/pe_load_config.cpp
deleted file mode 100644
index c05895fecd..0000000000
--- a/tools/pe_bliss/pe_load_config.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "pe_load_config.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMAGE CONFIG
-//Default constructor
-image_config_info::image_config_info()
- :time_stamp_(0),
- major_version_(0), minor_version_(0),
- global_flags_clear_(0), global_flags_set_(0),
- critical_section_default_timeout_(0),
- decommit_free_block_threshold_(0), decommit_total_free_threshold_(0),
- lock_prefix_table_va_(0),
- max_allocation_size_(0),
- virtual_memory_threshold_(0),
- process_affinity_mask_(0),
- process_heap_flags_(0),
- service_pack_version_(0),
- edit_list_va_(0),
- security_cookie_va_(0),
- se_handler_table_va_(0),
- se_handler_count_(0)
-{}
-
-//Constructors from PE structures
-template<typename ConfigStructure>
-image_config_info::image_config_info(const ConfigStructure& info)
- :time_stamp_(info.TimeDateStamp),
- major_version_(info.MajorVersion), minor_version_(info.MinorVersion),
- global_flags_clear_(info.GlobalFlagsClear), global_flags_set_(info.GlobalFlagsSet),
- critical_section_default_timeout_(info.CriticalSectionDefaultTimeout),
- decommit_free_block_threshold_(info.DeCommitFreeBlockThreshold), decommit_total_free_threshold_(info.DeCommitTotalFreeThreshold),
- lock_prefix_table_va_(info.LockPrefixTable),
- max_allocation_size_(info.MaximumAllocationSize),
- virtual_memory_threshold_(info.VirtualMemoryThreshold),
- process_affinity_mask_(info.ProcessAffinityMask),
- process_heap_flags_(info.ProcessHeapFlags),
- service_pack_version_(info.CSDVersion),
- edit_list_va_(info.EditList),
- security_cookie_va_(info.SecurityCookie),
- se_handler_table_va_(info.SEHandlerTable),
- se_handler_count_(info.SEHandlerCount)
-{}
-
-//Instantiate template constructor with needed structures
-template image_config_info::image_config_info(const image_load_config_directory32& info);
-template image_config_info::image_config_info(const image_load_config_directory64& info);
-
-//Returns the date and time stamp value
-uint32_t image_config_info::get_time_stamp() const
-{
- return time_stamp_;
-}
-
-//Returns major version number
-uint16_t image_config_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version number
-uint16_t image_config_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns clear global flags
-uint32_t image_config_info::get_global_flags_clear() const
-{
- return global_flags_clear_;
-}
-
-//Returns set global flags
-uint32_t image_config_info::get_global_flags_set() const
-{
- return global_flags_set_;
-}
-
-//Returns critical section default timeout
-uint32_t image_config_info::get_critical_section_default_timeout() const
-{
- return critical_section_default_timeout_;
-}
-
-//Get the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_free_block_threshold() const
-{
- return decommit_free_block_threshold_;
-}
-
-//Returns the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_total_free_threshold() const
-{
- return decommit_total_free_threshold_;
-}
-
-//Returns VA of a list of addresses where the LOCK prefix is used
-uint64_t image_config_info::get_lock_prefix_table_va() const
-{
- return lock_prefix_table_va_;
-}
-
-//Returns the maximum allocation size, in bytes
-uint64_t image_config_info::get_max_allocation_size() const
-{
- return max_allocation_size_;
-}
-
-//Returns the maximum block size that can be allocated from heap segments, in bytes
-uint64_t image_config_info::get_virtual_memory_threshold() const
-{
- return virtual_memory_threshold_;
-}
-
-//Returns process affinity mask
-uint64_t image_config_info::get_process_affinity_mask() const
-{
- return process_affinity_mask_;
-}
-
-//Returns process heap flags
-uint32_t image_config_info::get_process_heap_flags() const
-{
- return process_heap_flags_;
-}
-
-//Returns service pack version (CSDVersion)
-uint16_t image_config_info::get_service_pack_version() const
-{
- return service_pack_version_;
-}
-
-//Returns VA of edit list (reserved by system)
-uint64_t image_config_info::get_edit_list_va() const
-{
- return edit_list_va_;
-}
-
-//Returns a pointer to a cookie that is used by Visual C++ or GS implementation
-uint64_t image_config_info::get_security_cookie_va() const
-{
- return security_cookie_va_;
-}
-
-//Returns VA of the sorted table of RVAs of each valid, unique handler in the image
-uint64_t image_config_info::get_se_handler_table_va() const
-{
- return se_handler_table_va_;
-}
-
-//Returns the count of unique handlers in the table
-uint64_t image_config_info::get_se_handler_count() const
-{
- return se_handler_count_;
-}
-
-//Returns SE Handler RVA list
-const image_config_info::se_handler_list& image_config_info::get_se_handler_rvas() const
-{
- return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-const image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas() const
-{
- return lock_prefixes_;
-}
-
-//Adds SE Handler RVA to list
-void image_config_info::add_se_handler_rva(uint32_t rva)
-{
- se_handlers_.push_back(rva);
-}
-
-//Clears SE Handler list
-void image_config_info::clear_se_handler_list()
-{
- se_handlers_.clear();
-}
-
-//Adds Lock Prefix RVA to list
-void image_config_info::add_lock_prefix_rva(uint32_t rva)
-{
- lock_prefixes_.push_back(rva);
-}
-
-//Clears Lock Prefix list
-void image_config_info::clear_lock_prefix_list()
-{
- lock_prefixes_.clear();
-}
-
-//Sets the date and time stamp value
-void image_config_info::set_time_stamp(uint32_t time_stamp)
-{
- time_stamp_ = time_stamp;
-}
-
-//Sets major version number
-void image_config_info::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version number
-void image_config_info::set_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Sets clear global flags
-void image_config_info::set_global_flags_clear(uint32_t global_flags_clear)
-{
- global_flags_clear_ = global_flags_clear;
-}
-
-//Sets set global flags
-void image_config_info::set_global_flags_set(uint32_t global_flags_set)
-{
- global_flags_set_ = global_flags_set;
-}
-
-//Sets critical section default timeout
-void image_config_info::set_critical_section_default_timeout(uint32_t critical_section_default_timeout)
-{
- critical_section_default_timeout_ = critical_section_default_timeout;
-}
-
-//Sets the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold)
-{
- decommit_free_block_threshold_ = decommit_free_block_threshold;
-}
-
-//Sets the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold)
-{
- decommit_total_free_threshold_ = decommit_total_free_threshold;
-}
-
-//Sets VA of a list of addresses where the LOCK prefix is used
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_lock_prefix_table_va(uint64_t lock_prefix_table_va)
-{
- lock_prefix_table_va_ = lock_prefix_table_va;
-}
-
-//Sets the maximum allocation size, in bytes
-void image_config_info::set_max_allocation_size(uint64_t max_allocation_size)
-{
- max_allocation_size_ = max_allocation_size;
-}
-
-//Sets the maximum block size that can be allocated from heap segments, in bytes
-void image_config_info::set_virtual_memory_threshold(uint64_t virtual_memory_threshold)
-{
- virtual_memory_threshold_ = virtual_memory_threshold;
-}
-
-//Sets process affinity mask
-void image_config_info::set_process_affinity_mask(uint64_t process_affinity_mask)
-{
- process_affinity_mask_ = process_affinity_mask;
-}
-
-//Sets process heap flags
-void image_config_info::set_process_heap_flags(uint32_t process_heap_flags)
-{
- process_heap_flags_ = process_heap_flags;
-}
-
-//Sets service pack version (CSDVersion)
-void image_config_info::set_service_pack_version(uint16_t service_pack_version)
-{
- service_pack_version_ = service_pack_version;
-}
-
-//Sets VA of edit list (reserved by system)
-void image_config_info::set_edit_list_va(uint64_t edit_list_va)
-{
- edit_list_va_ = edit_list_va;
-}
-
-//Sets a pointer to a cookie that is used by Visual C++ or GS implementation
-void image_config_info::set_security_cookie_va(uint64_t security_cookie_va)
-{
- security_cookie_va_ = security_cookie_va;
-}
-
-//Sets VA of the sorted table of RVAs of each valid, unique handler in the image
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_se_handler_table_va(uint64_t se_handler_table_va)
-{
- se_handler_table_va_ = se_handler_table_va;
-}
-
-//Returns SE Handler RVA list
-image_config_info::se_handler_list& image_config_info::get_se_handler_rvas()
-{
- return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas()
-{
- return lock_prefixes_;
-}
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe)
-{
- return pe.get_pe_type() == pe_type_32
- ? get_image_config_base<pe_types_class_32>(pe)
- : get_image_config_base<pe_types_class_64>(pe);
-}
-
-//Image config rebuilder
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
- return pe.get_pe_type() == pe_type_32
- ? rebuild_image_config_base<pe_types_class_32>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section)
- : rebuild_image_config_base<pe_types_class_64>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section);
-}
-
-
-//Returns image config info
-//If image does not have config info, throws an exception
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe)
-{
- //Check if image has config directory
- if(!pe.has_config())
- throw pe_exception("Image does not have load config directory", pe_exception::directory_does_not_exist);
-
- //Get load config structure
- typename PEClassType::ConfigStruct config_info = pe.section_data_from_rva<typename PEClassType::ConfigStruct>(pe.get_directory_rva(image_directory_entry_load_config), section_data_virtual);
-
- //Check size of config directory
- if(config_info.Size != sizeof(config_info))
- throw pe_exception("Incorrect (or old) load config directory", pe_exception::incorrect_config_directory);
-
- //Fill return structure
- image_config_info ret(config_info);
-
- //Check possible overflow
- if(config_info.SEHandlerCount >= pe_utils::max_dword / sizeof(uint32_t)
- || config_info.SEHandlerTable >= static_cast<typename PEClassType::BaseSize>(-1) - config_info.SEHandlerCount * sizeof(uint32_t))
- throw pe_exception("Incorrect load config directory", pe_exception::incorrect_config_directory);
-
- //Read sorted SE handler RVA list (if any)
- for(typename PEClassType::BaseSize i = 0; i != config_info.SEHandlerCount; ++i)
- ret.add_se_handler_rva(pe.section_data_from_va<uint32_t>(static_cast<typename PEClassType::BaseSize>(config_info.SEHandlerTable + i * sizeof(uint32_t))));
-
- if(config_info.LockPrefixTable)
- {
- //Read Lock Prefix VA list (if any)
- unsigned long current = 0;
- while(true)
- {
- typename PEClassType::BaseSize lock_prefix_va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(config_info.LockPrefixTable + current * sizeof(typename PEClassType::BaseSize)));
- if(!lock_prefix_va)
- break;
-
- ret.add_lock_prefix_rva(pe.va_to_rva(lock_prefix_va));
-
- ++current;
- }
- }
-
- return ret;
-}
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that image_config_section is attached to this PE image
- if(!pe.section_attached(image_config_section))
- throw pe_exception("Image Config section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t alignment = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)) - offset_from_section_start;
-
- uint32_t needed_size = sizeof(typename PEClassType::ConfigStruct); //Calculate needed size for Image Config table
-
- uint32_t image_config_data_pos = offset_from_section_start + alignment;
-
- uint32_t current_pos_of_se_handlers = 0;
- uint32_t current_pos_of_lock_prefixes = 0;
-
- if(write_se_handlers)
- {
- current_pos_of_se_handlers = needed_size + image_config_data_pos;
- needed_size += static_cast<uint32_t>(info.get_se_handler_rvas().size()) * sizeof(uint32_t); //RVAs of SE Handlers
- }
-
- if(write_lock_prefixes)
- {
- current_pos_of_lock_prefixes = needed_size + image_config_data_pos;
- needed_size += static_cast<uint32_t>((info.get_lock_prefix_rvas().size() + 1) * sizeof(typename PEClassType::BaseSize)); //VAs of Lock Prefixes (and ending null element)
- }
-
- //Check if image_config_section is last one. If it's not, check if there's enough place for Image Config data
- if(&image_config_section != &*(pe.get_image_sections().end() - 1) &&
- (image_config_section.empty() || pe_utils::align_up(image_config_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + image_config_data_pos))
- throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
- std::string& raw_data = image_config_section.get_raw_data();
-
- //This will be done only if image_config_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + image_config_data_pos)
- raw_data.resize(needed_size + image_config_data_pos); //Expand section raw data
-
- //Create and fill Image Config structure
- typename PEClassType::ConfigStruct image_config_section_struct = {0};
- image_config_section_struct.Size = sizeof(image_config_section_struct);
- image_config_section_struct.TimeDateStamp = info.get_time_stamp();
- image_config_section_struct.MajorVersion = info.get_major_version();
- image_config_section_struct.MinorVersion = info.get_minor_version();
- image_config_section_struct.GlobalFlagsClear = info.get_global_flags_clear();
- image_config_section_struct.GlobalFlagsSet = info.get_global_flags_set();
- image_config_section_struct.CriticalSectionDefaultTimeout = info.get_critical_section_default_timeout();
- image_config_section_struct.DeCommitFreeBlockThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_free_block_threshold());
- image_config_section_struct.DeCommitTotalFreeThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_total_free_threshold());
- image_config_section_struct.MaximumAllocationSize = static_cast<typename PEClassType::BaseSize>(info.get_max_allocation_size());
- image_config_section_struct.VirtualMemoryThreshold = static_cast<typename PEClassType::BaseSize>(info.get_virtual_memory_threshold());
- image_config_section_struct.ProcessHeapFlags = info.get_process_heap_flags();
- image_config_section_struct.ProcessAffinityMask = static_cast<typename PEClassType::BaseSize>(info.get_process_affinity_mask());
- image_config_section_struct.CSDVersion = info.get_service_pack_version();
- image_config_section_struct.EditList = static_cast<typename PEClassType::BaseSize>(info.get_edit_list_va());
- image_config_section_struct.SecurityCookie = static_cast<typename PEClassType::BaseSize>(info.get_security_cookie_va());
- image_config_section_struct.SEHandlerCount = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_rvas().size());
-
-
- if(write_se_handlers)
- {
- if(info.get_se_handler_rvas().empty())
- {
- write_se_handlers = false;
- image_config_section_struct.SEHandlerTable = 0;
- }
- else
- {
- typename PEClassType::BaseSize va;
- pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_se_handlers), va);
- image_config_section_struct.SEHandlerTable = va;
- }
- }
- else
- {
- image_config_section_struct.SEHandlerTable = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_table_va());
- }
-
- if(write_lock_prefixes)
- {
- if(info.get_lock_prefix_rvas().empty())
- {
- write_lock_prefixes = false;
- image_config_section_struct.LockPrefixTable = 0;
- }
- else
- {
- typename PEClassType::BaseSize va;
- pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_lock_prefixes), va);
- image_config_section_struct.LockPrefixTable = va;
- }
- }
- else
- {
- image_config_section_struct.LockPrefixTable = static_cast<typename PEClassType::BaseSize>(info.get_lock_prefix_table_va());
- }
-
- //Write image config section
- memcpy(&raw_data[image_config_data_pos], &image_config_section_struct, sizeof(image_config_section_struct));
-
- if(write_se_handlers)
- {
- //Sort SE Handlers list
- image_config_info::se_handler_list sorted_list = info.get_se_handler_rvas();
- std::sort(sorted_list.begin(), sorted_list.end());
-
- //Write SE Handlers table
- for(image_config_info::se_handler_list::const_iterator it = sorted_list.begin(); it != sorted_list.end(); ++it)
- {
- uint32_t se_handler_rva = *it;
- memcpy(&raw_data[current_pos_of_se_handlers], &se_handler_rva, sizeof(se_handler_rva));
- current_pos_of_se_handlers += sizeof(se_handler_rva);
- }
- }
-
- if(write_lock_prefixes)
- {
- //Write Lock Prefixes VA list
- for(image_config_info::lock_prefix_rva_list::const_iterator it = info.get_lock_prefix_rvas().begin(); it != info.get_lock_prefix_rvas().end(); ++it)
- {
- typename PEClassType::BaseSize lock_prefix_va;
- pe.rva_to_va(*it, lock_prefix_va);
- memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
- current_pos_of_lock_prefixes += sizeof(lock_prefix_va);
- }
-
- {
- //Ending null VA
- typename PEClassType::BaseSize lock_prefix_va = 0;
- memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
- }
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(image_config_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(image_config_section, image_config_data_pos), sizeof(typename PEClassType::ConfigStruct));
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_load_config, ret.get_rva());
- pe.set_directory_size(image_directory_entry_load_config, ret.get_size());
- }
-
- return ret;
-}
-
-}
diff --git a/tools/pe_bliss/pe_load_config.h b/tools/pe_bliss/pe_load_config.h
deleted file mode 100644
index cb24072de7..0000000000
--- a/tools/pe_bliss/pe_load_config.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing image configuration information
-class image_config_info
-{
-public:
- typedef std::vector<uint32_t> se_handler_list;
- typedef std::vector<uint32_t> lock_prefix_rva_list;
-
-public:
- //Default constructor
- image_config_info();
- //Constructors from PE structures (no checks)
- template<typename ConfigStructure>
- explicit image_config_info(const ConfigStructure& info);
-
- //Returns the date and time stamp value
- uint32_t get_time_stamp() const;
- //Returns major version number
- uint16_t get_major_version() const;
- //Returns minor version number
- uint16_t get_minor_version() const;
- //Returns clear global flags
- uint32_t get_global_flags_clear() const;
- //Returns set global flags
- uint32_t get_global_flags_set() const;
- //Returns critical section default timeout
- uint32_t get_critical_section_default_timeout() const;
- //Get the size of the minimum block that
- //must be freed before it is freed (de-committed), in bytes
- uint64_t get_decommit_free_block_threshold() const;
- //Returns the size of the minimum total memory
- //that must be freed in the process heap before it is freed (de-committed), in bytes
- uint64_t get_decommit_total_free_threshold() const;
- //Returns VA of a list of addresses where the LOCK prefix is used
- uint64_t get_lock_prefix_table_va() const;
- //Returns the maximum allocation size, in bytes
- uint64_t get_max_allocation_size() const;
- //Returns the maximum block size that can be allocated from heap segments, in bytes
- uint64_t get_virtual_memory_threshold() const;
- //Returns process affinity mask
- uint64_t get_process_affinity_mask() const;
- //Returns process heap flags
- uint32_t get_process_heap_flags() const;
- //Returns service pack version (CSDVersion)
- uint16_t get_service_pack_version() const;
- //Returns VA of edit list (reserved by system)
- uint64_t get_edit_list_va() const;
- //Returns a pointer to a cookie that is used by Visual C++ or GS implementation
- uint64_t get_security_cookie_va() const;
- //Returns VA of the sorted table of RVAs of each valid, unique handler in the image
- uint64_t get_se_handler_table_va() const;
- //Returns the count of unique handlers in the table
- uint64_t get_se_handler_count() const;
-
- //Returns SE Handler RVA list
- const se_handler_list& get_se_handler_rvas() const;
-
- //Returns Lock Prefix RVA list
- const lock_prefix_rva_list& get_lock_prefix_rvas() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Also you can use these functions to rebuild image config directory
-
- //Adds SE Handler RVA to list
- void add_se_handler_rva(uint32_t rva);
- //Clears SE Handler list
- void clear_se_handler_list();
-
- //Adds Lock Prefix RVA to list
- void add_lock_prefix_rva(uint32_t rva);
- //Clears Lock Prefix list
- void clear_lock_prefix_list();
-
- //Sets the date and time stamp value
- void set_time_stamp(uint32_t time_stamp);
- //Sets major version number
- void set_major_version(uint16_t major_version);
- //Sets minor version number
- void set_minor_version(uint16_t minor_version);
- //Sets clear global flags
- void set_global_flags_clear(uint32_t global_flags_clear);
- //Sets set global flags
- void set_global_flags_set(uint32_t global_flags_set);
- //Sets critical section default timeout
- void set_critical_section_default_timeout(uint32_t critical_section_default_timeout);
- //Sets the size of the minimum block that
- //must be freed before it is freed (de-committed), in bytes
- void set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold);
- //Sets the size of the minimum total memory
- //that must be freed in the process heap before it is freed (de-committed), in bytes
- void set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold);
- //Sets VA of a list of addresses where the LOCK prefix is used
- //If you rebuild this list, VA will be re-assigned automatically
- void set_lock_prefix_table_va(uint64_t lock_prefix_table_va);
- //Sets the maximum allocation size, in bytes
- void set_max_allocation_size(uint64_t max_allocation_size);
- //Sets the maximum block size that can be allocated from heap segments, in bytes
- void set_virtual_memory_threshold(uint64_t virtual_memory_threshold);
- //Sets process affinity mask
- void set_process_affinity_mask(uint64_t process_affinity_mask);
- //Sets process heap flags
- void set_process_heap_flags(uint32_t process_heap_flags);
- //Sets service pack version (CSDVersion)
- void set_service_pack_version(uint16_t service_pack_version);
- //Sets VA of edit list (reserved by system)
- void set_edit_list_va(uint64_t edit_list_va);
- //Sets a pointer to a cookie that is used by Visual C++ or GS implementation
- void set_security_cookie_va(uint64_t security_cookie_va);
- //Sets VA of the sorted table of RVAs of each valid, unique handler in the image
- //If you rebuild this list, VA will be re-assigned automatically
- void set_se_handler_table_va(uint64_t se_handler_table_va);
-
- //Returns SE Handler RVA list
- se_handler_list& get_se_handler_rvas();
-
- //Returns Lock Prefix RVA list
- lock_prefix_rva_list& get_lock_prefix_rvas();
-
-private:
- uint32_t time_stamp_;
- uint16_t major_version_, minor_version_;
- uint32_t global_flags_clear_, global_flags_set_;
- uint32_t critical_section_default_timeout_;
- uint64_t decommit_free_block_threshold_, decommit_total_free_threshold_;
- uint64_t lock_prefix_table_va_;
- uint64_t max_allocation_size_;
- uint64_t virtual_memory_threshold_;
- uint64_t process_affinity_mask_;
- uint32_t process_heap_flags_;
- uint16_t service_pack_version_;
- uint64_t edit_list_va_;
- uint64_t security_cookie_va_;
- uint64_t se_handler_table_va_;
- uint64_t se_handler_count_;
-
- se_handler_list se_handlers_;
- lock_prefix_rva_list lock_prefixes_;
-};
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe);
-
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe);
-
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_properties.cpp b/tools/pe_bliss/pe_properties.cpp
deleted file mode 100644
index 8d1c2eac43..0000000000
--- a/tools/pe_bliss/pe_properties.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_properties.h"
-
-namespace pe_bliss
-{
-//Destructor
-pe_properties::~pe_properties()
-{}
-
-//Clears PE characteristics flag
-void pe_properties::clear_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_properties::set_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() | flags);
-}
-}
diff --git a/tools/pe_bliss/pe_properties.h b/tools/pe_bliss/pe_properties.h
deleted file mode 100644
index 1db163e8b1..0000000000
--- a/tools/pe_bliss/pe_properties.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_properties
-{
-public: //Constructors
- virtual std::auto_ptr<pe_properties> duplicate() const = 0;
-
- //Fills properly PE structures
- virtual void create_pe(uint32_t section_alignment, uint16_t subsystem) = 0;
-
-public:
- //Destructor
- virtual ~pe_properties();
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- virtual bool directory_exists(uint32_t id) const = 0;
-
- //Removes directory
- virtual void remove_directory(uint32_t id) = 0;
-
- //Returns directory RVA
- virtual uint32_t get_directory_rva(uint32_t id) const = 0;
- //Returns directory size
- virtual uint32_t get_directory_size(uint32_t id) const = 0;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- virtual void set_directory_rva(uint32_t id, uint32_t rva) = 0;
- //Sets directory size (just a value of PE header, no moving occurs)
- virtual void set_directory_size(uint32_t id, uint32_t size) = 0;
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true) = 0;
-
-
-public: //IMAGE
- //Returns PE type of this image
- virtual pe_type get_pe_type() const = 0;
-
-
-public: //PE HEADER
- //Returns image base for PE32 and PE64 respectively
- virtual uint32_t get_image_base_32() const = 0;
- virtual uint64_t get_image_base_64() const = 0;
-
- //Sets new image base for PE32
- virtual void set_image_base(uint32_t base) = 0;
- //Sets new image base for PE32/PE+
- virtual void set_image_base_64(uint64_t base) = 0;
-
- //Returns image entry point
- virtual uint32_t get_ep() const = 0;
- //Sets image entry point
- virtual void set_ep(uint32_t new_ep) = 0;
-
- //Returns file alignment
- virtual uint32_t get_file_alignment() const = 0;
- //Returns section alignment
- virtual uint32_t get_section_alignment() const = 0;
-
- //Sets heap size commit for PE32 and PE64 respectively
- virtual void set_heap_size_commit(uint32_t size) = 0;
- virtual void set_heap_size_commit(uint64_t size) = 0;
- //Sets heap size reserve for PE32 and PE64 respectively
- virtual void set_heap_size_reserve(uint32_t size) = 0;
- virtual void set_heap_size_reserve(uint64_t size) = 0;
- //Sets stack size commit for PE32 and PE64 respectively
- virtual void set_stack_size_commit(uint32_t size) = 0;
- virtual void set_stack_size_commit(uint64_t size) = 0;
- //Sets stack size reserve for PE32 and PE64 respectively
- virtual void set_stack_size_reserve(uint32_t size) = 0;
- virtual void set_stack_size_reserve(uint64_t size) = 0;
-
- //Returns heap size commit for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_commit_32() const = 0;
- virtual uint64_t get_heap_size_commit_64() const = 0;
- //Returns heap size reserve for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_reserve_32() const = 0;
- virtual uint64_t get_heap_size_reserve_64() const = 0;
- //Returns stack size commit for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_commit_32() const = 0;
- virtual uint64_t get_stack_size_commit_64() const = 0;
- //Returns stack size reserve for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_reserve_32() const = 0;
- virtual uint64_t get_stack_size_reserve_64() const = 0;
-
- //Returns virtual size of image
- virtual uint32_t get_size_of_image() const = 0;
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual uint32_t get_number_of_rvas_and_sizes() const = 0;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual void set_number_of_rvas_and_sizes(uint32_t number) = 0;
-
- //Returns PE characteristics
- virtual uint16_t get_characteristics() const = 0;
- //Sets PE characteristics
- virtual void set_characteristics(uint16_t ch) = 0;
-
- //Clears PE characteristics flag
- void clear_characteristics_flags(uint16_t flags);
- //Sets PE characteristics flag
- void set_characteristics_flags(uint16_t flags);
-
- //Returns size of headers
- virtual uint32_t get_size_of_headers() const = 0;
-
- //Returns subsystem
- virtual uint16_t get_subsystem() const = 0;
-
- //Sets subsystem
- virtual void set_subsystem(uint16_t subsystem) = 0;
-
- //Returns size of optional header
- virtual uint16_t get_size_of_optional_header() const = 0;
-
- //Returns PE signature
- virtual uint32_t get_pe_signature() const = 0;
-
- //Returns PE magic value
- virtual uint32_t get_magic() const = 0;
-
- //Returns checksum of PE file from header
- virtual uint32_t get_checksum() const = 0;
-
- //Sets checksum of PE file
- virtual void set_checksum(uint32_t checksum) = 0;
-
- //Returns timestamp of PE file from header
- virtual uint32_t get_time_date_stamp() const = 0;
-
- //Sets timestamp of PE file
- virtual void set_time_date_stamp(uint32_t timestamp) = 0;
-
- //Returns Machine field value of PE file from header
- virtual uint16_t get_machine() const = 0;
-
- //Sets Machine field value of PE file
- virtual void set_machine(uint16_t machine) = 0;
-
- //Returns DLL Characteristics
- virtual uint16_t get_dll_characteristics() const = 0;
-
- //Sets DLL Characteristics
- virtual void set_dll_characteristics(uint16_t characteristics) = 0;
-
- //Sets required operation system version
- virtual void set_os_version(uint16_t major, uint16_t minor) = 0;
-
- //Returns required operation system version (minor word)
- virtual uint16_t get_minor_os_version() const = 0;
-
- //Returns required operation system version (major word)
- virtual uint16_t get_major_os_version() const = 0;
-
- //Sets required subsystem version
- virtual void set_subsystem_version(uint16_t major, uint16_t minor) = 0;
-
- //Returns required subsystem version (minor word)
- virtual uint16_t get_minor_subsystem_version() const = 0;
-
- //Returns required subsystem version (major word)
- virtual uint16_t get_major_subsystem_version() const = 0;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const = 0;
- virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const = 0;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- virtual uint32_t rva_to_va_32(uint32_t rva) const = 0;
- virtual uint64_t rva_to_va_64(uint32_t rva) const = 0;
-
-
-public: //SECTIONS
- //Returns number of sections
- virtual uint16_t get_number_of_sections() const = 0;
-
-public:
- //Sets number of sections
- virtual void set_number_of_sections(uint16_t number) = 0;
- //Sets virtual size of image
- virtual void set_size_of_image(uint32_t size) = 0;
- //Sets size of headers
- virtual void set_size_of_headers(uint32_t size) = 0;
- //Sets size of optional headers
- virtual void set_size_of_optional_header(uint16_t size) = 0;
- //Returns nt headers data pointer
- virtual char* get_nt_headers_ptr() = 0;
- //Returns nt headers data pointer
- virtual const char* get_nt_headers_ptr() const = 0;
- //Returns size of NT header
- virtual uint32_t get_sizeof_nt_header() const = 0;
- //Returns size of optional headers
- virtual uint32_t get_sizeof_opt_headers() const = 0;
- //Sets file alignment (no checks)
- virtual void set_file_alignment_unchecked(uint32_t alignment) = 0;
- //Sets base of code
- virtual void set_base_of_code(uint32_t base) = 0;
- //Returns base of code
- virtual uint32_t get_base_of_code() const = 0;
- //Returns needed PE magic for PE or PE+ (from template parameters)
- virtual uint32_t get_needed_magic() const = 0;
-};
-}
diff --git a/tools/pe_bliss/pe_properties_generic.cpp b/tools/pe_bliss/pe_properties_generic.cpp
deleted file mode 100644
index bcf6f2047d..0000000000
--- a/tools/pe_bliss/pe_properties_generic.cpp
+++ /dev/null
@@ -1,645 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_properties_generic.h"
-#include "pe_exception.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor
-template<typename PEClassType>
-std::auto_ptr<pe_properties> pe_properties_generic<PEClassType>::duplicate() const
-{
- return std::auto_ptr<pe_properties>(new pe_properties_generic<PEClassType>(*this));
-}
-
-//Fills properly PE structures
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::create_pe(uint32_t section_alignment, uint16_t subsystem)
-{
- memset(&nt_headers_, 0, sizeof(nt_headers_));
- nt_headers_.Signature = 0x4550; //"PE"
- nt_headers_.FileHeader.Machine = 0x14C; //i386
- nt_headers_.FileHeader.SizeOfOptionalHeader = sizeof(nt_headers_.OptionalHeader);
- nt_headers_.OptionalHeader.Magic = PEClassType::Id;
- nt_headers_.OptionalHeader.ImageBase = 0x400000;
- nt_headers_.OptionalHeader.SectionAlignment = section_alignment;
- nt_headers_.OptionalHeader.FileAlignment = 0x200;
- nt_headers_.OptionalHeader.SizeOfHeaders = 1024;
- nt_headers_.OptionalHeader.Subsystem = subsystem;
- nt_headers_.OptionalHeader.SizeOfHeapReserve = 0x100000;
- nt_headers_.OptionalHeader.SizeOfHeapCommit = 0x1000;
- nt_headers_.OptionalHeader.SizeOfStackReserve = 0x100000;
- nt_headers_.OptionalHeader.SizeOfStackCommit = 0x1000;
- nt_headers_.OptionalHeader.NumberOfRvaAndSizes = 0x10;
-}
-
-//Duplicate
-template<typename PEClassType>
-pe_properties_generic<PEClassType>::~pe_properties_generic()
-{}
-
-//Returns true if directory exists
-template<typename PEClassType>
-bool pe_properties_generic<PEClassType>::directory_exists(uint32_t id) const
-{
- return (nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1) >= id &&
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Removes directory
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::remove_directory(uint32_t id)
-{
- if(directory_exists(id))
- {
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = 0;
- nt_headers_.OptionalHeader.DataDirectory[id].Size = 0;
-
- if(id == image_directory_entry_basereloc)
- {
- set_characteristics_flags(image_file_relocs_stripped);
- set_dll_characteristics(get_dll_characteristics() & ~image_dllcharacteristics_dynamic_base);
- }
- else if(id == image_directory_entry_export)
- {
- clear_characteristics_flags(image_file_dll);
- }
- }
-}
-
-//Returns directory RVA
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_rva(uint32_t id) const
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- return nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Returns directory size
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_rva(uint32_t id, uint32_t va)
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = va;
-}
-
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_size(uint32_t id, uint32_t size)
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- nt_headers_.OptionalHeader.DataDirectory[id].Size = size;
-}
-
-//Returns directory size
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_size(uint32_t id) const
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- return nt_headers_.OptionalHeader.DataDirectory[id].Size;
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
- int i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1;
-
- //Enumerate all data directories from the end
- for(; i >= 0; i--)
- {
- //If directory exists, break
- if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && (static_cast<uint32_t>(i) != image_directory_entry_iat || !strip_iat_directory))
- break;
-
- if(i <= static_cast<int>(min_count) - 2)
- break;
- }
-
- if(i == image_numberof_directory_entries - 1)
- return image_numberof_directory_entries;
-
- //Return new number of data directories
- return nt_headers_.OptionalHeader.NumberOfRvaAndSizes = i + 1;
-}
-
-//Returns image base for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_image_base_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Returns image base for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_image_base_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base(uint32_t base)
-{
- nt_headers_.OptionalHeader.ImageBase = base;
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base_64(uint64_t base)
-{
- nt_headers_.OptionalHeader.ImageBase = static_cast<typename PEClassType::BaseSize>(base);
-}
-
-//Returns image entry point
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_ep() const
-{
- return nt_headers_.OptionalHeader.AddressOfEntryPoint;
-}
-
-//Sets image entry point
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_ep(uint32_t new_ep)
-{
- nt_headers_.OptionalHeader.AddressOfEntryPoint = new_ep;
-}
-
-//Returns file alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_file_alignment() const
-{
- return nt_headers_.OptionalHeader.FileAlignment;
-}
-
-//Returns section alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_section_alignment() const
-{
- return nt_headers_.OptionalHeader.SectionAlignment;
-}
-
-//Sets heap size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Returns heap size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_commit_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_commit_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_reserve_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns heap size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_reserve_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns stack size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_commit_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_commit_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_reserve_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns stack size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_reserve_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns virtual size of image
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_image() const
-{
- return nt_headers_.OptionalHeader.SizeOfImage;
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_number_of_rvas_and_sizes() const
-{
- return nt_headers_.OptionalHeader.NumberOfRvaAndSizes;
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_rvas_and_sizes(uint32_t number)
-{
- nt_headers_.OptionalHeader.NumberOfRvaAndSizes = number;
-}
-
-//Returns PE characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_characteristics() const
-{
- return nt_headers_.FileHeader.Characteristics;
-}
-
-//Returns checksum of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_checksum() const
-{
- return nt_headers_.OptionalHeader.CheckSum;
-}
-
-//Sets checksum of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_checksum(uint32_t checksum)
-{
- nt_headers_.OptionalHeader.CheckSum = checksum;
-}
-
-//Returns DLL Characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_dll_characteristics() const
-{
- return nt_headers_.OptionalHeader.DllCharacteristics;
-}
-
-//Returns timestamp of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_time_date_stamp() const
-{
- return nt_headers_.FileHeader.TimeDateStamp;
-}
-
-//Sets timestamp of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_time_date_stamp(uint32_t timestamp)
-{
- nt_headers_.FileHeader.TimeDateStamp = timestamp;
-}
-
-//Sets DLL Characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_dll_characteristics(uint16_t characteristics)
-{
- nt_headers_.OptionalHeader.DllCharacteristics = characteristics;
-}
-
-//Returns Machine field value of PE file from header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_machine() const
-{
- return nt_headers_.FileHeader.Machine;
-}
-
-//Sets Machine field value of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_machine(uint16_t machine)
-{
- nt_headers_.FileHeader.Machine = machine;
-}
-
-//Sets PE characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_characteristics(uint16_t ch)
-{
- nt_headers_.FileHeader.Characteristics = ch;
-}
-
-//Returns size of headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_headers() const
-{
- return nt_headers_.OptionalHeader.SizeOfHeaders;
-}
-
-//Returns subsystem
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_subsystem() const
-{
- return nt_headers_.OptionalHeader.Subsystem;
-}
-
-//Sets subsystem
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem(uint16_t subsystem)
-{
- nt_headers_.OptionalHeader.Subsystem = subsystem;
-}
-
-//Returns size of optional header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_size_of_optional_header() const
-{
- return nt_headers_.FileHeader.SizeOfOptionalHeader;
-}
-
-//Returns PE signature
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_pe_signature() const
-{
- return nt_headers_.Signature;
-}
-
-//Returns PE magic value
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_magic() const
-{
- return nt_headers_.OptionalHeader.Magic;
-}
-
-//Sets required operation system version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_os_version(uint16_t major, uint16_t minor)
-{
- nt_headers_.OptionalHeader.MinorOperatingSystemVersion = minor;
- nt_headers_.OptionalHeader.MajorOperatingSystemVersion = major;
-}
-
-//Returns required operation system version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_os_version() const
-{
- return nt_headers_.OptionalHeader.MinorOperatingSystemVersion;
-}
-
-//Returns required operation system version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_os_version() const
-{
- return nt_headers_.OptionalHeader.MajorOperatingSystemVersion;
-}
-
-//Sets required subsystem version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem_version(uint16_t major, uint16_t minor)
-{
- nt_headers_.OptionalHeader.MinorSubsystemVersion = minor;
- nt_headers_.OptionalHeader.MajorSubsystemVersion = major;
-}
-
-//Returns required subsystem version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_subsystem_version() const
-{
- return nt_headers_.OptionalHeader.MinorSubsystemVersion;
-}
-
-//Returns required subsystem version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_subsystem_version() const
-{
- return nt_headers_.OptionalHeader.MajorSubsystemVersion;
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint32_t va, bool bound_check) const
-{
- if(bound_check && static_cast<uint64_t>(va) - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32/PE64
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint64_t va, bool bound_check) const
-{
- if(bound_check && va - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::rva_to_va_32(uint32_t rva) const
-{
- if(!pe_utils::is_sum_safe(rva, static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase)))
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(rva + nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::rva_to_va_64(uint32_t rva) const
-{
- return static_cast<uint64_t>(rva) + nt_headers_.OptionalHeader.ImageBase;
-}
-
-//Returns number of sections
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_number_of_sections() const
-{
- return nt_headers_.FileHeader.NumberOfSections;
-}
-
-//Sets number of sections
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_sections(uint16_t number)
-{
- nt_headers_.FileHeader.NumberOfSections = number;
-}
-
-//Sets virtual size of image
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_image(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfImage = size;
-}
-
-//Sets size of headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_headers(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeaders = size;
-}
-
-//Sets size of optional headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_optional_header(uint16_t size)
-{
- nt_headers_.FileHeader.SizeOfOptionalHeader = size;
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-char* pe_properties_generic<PEClassType>::get_nt_headers_ptr()
-{
- return reinterpret_cast<char*>(&nt_headers_);
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-const char* pe_properties_generic<PEClassType>::get_nt_headers_ptr() const
-{
- return reinterpret_cast<const char*>(&nt_headers_);
-}
-
-//Returns size of NT header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_nt_header() const
-{
- return sizeof(typename PEClassType::NtHeaders);
-}
-
-//Returns size of optional headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_opt_headers() const
-{
- return sizeof(typename PEClassType::OptHeaders);
-}
-
-//Sets file alignment (no checks)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_file_alignment_unchecked(uint32_t alignment)
-{
- nt_headers_.OptionalHeader.FileAlignment = alignment;
-}
-
-//Sets base of code
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_base_of_code(uint32_t base)
-{
- nt_headers_.OptionalHeader.BaseOfCode = base;
-}
-
-//Returns base of code
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_base_of_code() const
-{
- return nt_headers_.OptionalHeader.BaseOfCode;
-}
-
-//Returns needed PE magic for PE or PE+ (from template parameters)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_needed_magic() const
-{
- return PEClassType::Id;
-}
-
-//Returns PE type of this image
-template<typename PEClassType>
-pe_type pe_properties_generic<PEClassType>::get_pe_type() const
-{
- return PEClassType::Id == image_nt_optional_hdr32_magic ? pe_type_32 : pe_type_64;
-}
-
-//Two used instantiations for PE32 (PE) and PE64 (PE+)
-template class pe_properties_generic<pe_types_class_32>;
-template class pe_properties_generic<pe_types_class_64>;
-}
diff --git a/tools/pe_bliss/pe_properties_generic.h b/tools/pe_bliss/pe_properties_generic.h
deleted file mode 100644
index 4ff906803c..0000000000
--- a/tools/pe_bliss/pe_properties_generic.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_properties.h"
-
-namespace pe_bliss
-{
-//Helper class to reduce code size and ease its editing
-template<
- typename NtHeadersType,
- typename OptHeadersType,
- uint16_t IdVal,
- typename BaseSizeType,
- BaseSizeType ImportSnapFlagVal,
- typename TLSStructType,
- typename ConfigStructType>
-class pe_types
-{
-public:
- typedef NtHeadersType NtHeaders; //NT HEADERS type
- typedef OptHeadersType OptHeaders; //NT OPTIONAL HEADER type
- typedef BaseSizeType BaseSize; //Base size of different values: DWORD or ULONGLONG
- typedef TLSStructType TLSStruct; //TLS structure type
- typedef ConfigStructType ConfigStruct; //Configuration structure type
-
- static const uint16_t Id = IdVal; //Magic of PE or PE+
- static const BaseSize ImportSnapFlag = ImportSnapFlagVal; //Import snap flag value
-};
-
-//Portable Executable derived class for PE and PE+
-//Describes PE/PE+ dependent things
-template<typename PEClassType>
-class pe_properties_generic : public pe_properties
-{
-public: //Constructor
- virtual std::auto_ptr<pe_properties> duplicate() const;
-
- //Fills properly PE structures
- virtual void create_pe(uint32_t section_alignment, uint16_t subsystem);
-
-public:
- //Destructor
- virtual ~pe_properties_generic();
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- virtual bool directory_exists(uint32_t id) const;
-
- //Removes directory
- virtual void remove_directory(uint32_t id);
-
- //Returns directory RVA
- virtual uint32_t get_directory_rva(uint32_t id) const;
- //Returns directory size
- virtual uint32_t get_directory_size(uint32_t id) const;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- virtual void set_directory_rva(uint32_t id, uint32_t rva);
- //Sets directory size (just a value of PE header, no moving occurs)
- virtual void set_directory_size(uint32_t id, uint32_t size);
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
-
-public: //IMAGE
- //Returns PE type of this image
- virtual pe_type get_pe_type() const;
-
-
-public: //PE HEADER
- //Returns image base for PE32 and PE64 respectively
- virtual uint32_t get_image_base_32() const;
- virtual uint64_t get_image_base_64() const;
-
- //Sets new image base for PE32
- virtual void set_image_base(uint32_t base);
- //Sets new image base for PE32/PE+
- virtual void set_image_base_64(uint64_t base);
-
- //Returns image entry point
- virtual uint32_t get_ep() const;
- //Sets image entry point
- virtual void set_ep(uint32_t new_ep);
-
- //Returns file alignment
- virtual uint32_t get_file_alignment() const;
- //Returns section alignment
- virtual uint32_t get_section_alignment() const;
-
- //Sets heap size commit for PE32 and PE64 respectively
- virtual void set_heap_size_commit(uint32_t size);
- virtual void set_heap_size_commit(uint64_t size);
- //Sets heap size reserve for PE32 and PE64 respectively
- virtual void set_heap_size_reserve(uint32_t size);
- virtual void set_heap_size_reserve(uint64_t size);
- //Sets stack size commit for PE32 and PE64 respectively
- virtual void set_stack_size_commit(uint32_t size);
- virtual void set_stack_size_commit(uint64_t size);
- //Sets stack size reserve for PE32 and PE64 respectively
- virtual void set_stack_size_reserve(uint32_t size);
- virtual void set_stack_size_reserve(uint64_t size);
-
- //Returns heap size commit for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_commit_32() const;
- virtual uint64_t get_heap_size_commit_64() const;
- //Returns heap size reserve for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_reserve_32() const;
- virtual uint64_t get_heap_size_reserve_64() const;
- //Returns stack size commit for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_commit_32() const;
- virtual uint64_t get_stack_size_commit_64() const;
- //Returns stack size reserve for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_reserve_32() const;
- virtual uint64_t get_stack_size_reserve_64() const;
-
- //Returns virtual size of image
- virtual uint32_t get_size_of_image() const;
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual uint32_t get_number_of_rvas_and_sizes() const;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual void set_number_of_rvas_and_sizes(uint32_t number);
-
- //Returns PE characteristics
- virtual uint16_t get_characteristics() const;
- //Sets PE characteristics
- virtual void set_characteristics(uint16_t ch);
-
- //Returns size of headers
- virtual uint32_t get_size_of_headers() const;
-
- //Returns subsystem
- virtual uint16_t get_subsystem() const;
-
- //Sets subsystem
- virtual void set_subsystem(uint16_t subsystem);
-
- //Returns size of optional header
- virtual uint16_t get_size_of_optional_header() const;
-
- //Returns PE signature
- virtual uint32_t get_pe_signature() const;
-
- //Returns PE magic value
- virtual uint32_t get_magic() const;
-
- //Returns checksum of PE file from header
- virtual uint32_t get_checksum() const;
-
- //Sets checksum of PE file
- virtual void set_checksum(uint32_t checksum);
-
- //Returns timestamp of PE file from header
- virtual uint32_t get_time_date_stamp() const;
-
- //Sets timestamp of PE file
- virtual void set_time_date_stamp(uint32_t timestamp);
-
- //Returns Machine field value of PE file from header
- virtual uint16_t get_machine() const;
-
- //Sets Machine field value of PE file
- virtual void set_machine(uint16_t machine);
-
- //Returns DLL Characteristics
- virtual uint16_t get_dll_characteristics() const;
-
- //Sets DLL Characteristics
- virtual void set_dll_characteristics(uint16_t characteristics);
-
- //Sets required operation system version
- virtual void set_os_version(uint16_t major, uint16_t minor);
-
- //Returns required operation system version (minor word)
- virtual uint16_t get_minor_os_version() const;
-
- //Returns required operation system version (major word)
- virtual uint16_t get_major_os_version() const;
-
- //Sets required subsystem version
- virtual void set_subsystem_version(uint16_t major, uint16_t minor);
-
- //Returns required subsystem version (minor word)
- virtual uint16_t get_minor_subsystem_version() const;
-
- //Returns required subsystem version (major word)
- virtual uint16_t get_major_subsystem_version() const;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
- virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- virtual uint32_t rva_to_va_32(uint32_t rva) const;
- virtual uint64_t rva_to_va_64(uint32_t rva) const;
-
-
-public: //SECTIONS
- //Returns number of sections
- virtual uint16_t get_number_of_sections() const;
-
-protected:
- typename PEClassType::NtHeaders nt_headers_; //NT headers (PE32 or PE64)
-
-public:
- //Sets number of sections
- virtual void set_number_of_sections(uint16_t number);
- //Sets virtual size of image
- virtual void set_size_of_image(uint32_t size);
- //Sets size of headers
- virtual void set_size_of_headers(uint32_t size);
- //Sets size of optional headers
- virtual void set_size_of_optional_header(uint16_t size);
- //Returns nt headers data pointer
- virtual char* get_nt_headers_ptr();
- //Returns nt headers data pointer
- virtual const char* get_nt_headers_ptr() const;
- //Returns size of NT header
- virtual uint32_t get_sizeof_nt_header() const;
- //Returns size of optional headers
- virtual uint32_t get_sizeof_opt_headers() const;
- //Sets file alignment (no checks)
- virtual void set_file_alignment_unchecked(uint32_t alignment);
- //Sets base of code
- virtual void set_base_of_code(uint32_t base);
- //Returns base of code
- virtual uint32_t get_base_of_code() const;
- //Returns needed PE magic for PE or PE+ (from template parameters)
- virtual uint32_t get_needed_magic() const;
-};
-
-//Two used typedefs for PE32 (PE) and PE64 (PE+)
-typedef pe_types<pe_win::image_nt_headers32,
- pe_win::image_optional_header32,
- pe_win::image_nt_optional_hdr32_magic,
- uint32_t,
- pe_win::image_ordinal_flag32,
- pe_win::image_tls_directory32,
- pe_win::image_load_config_directory32> pe_types_class_32;
-
-typedef pe_types<pe_win::image_nt_headers64,
- pe_win::image_optional_header64,
- pe_win::image_nt_optional_hdr64_magic,
- uint64_t,
- pe_win::image_ordinal_flag64,
- pe_win::image_tls_directory64,
- pe_win::image_load_config_directory64> pe_types_class_64;
-
-typedef pe_properties_generic<pe_types_class_32> pe_properties_32;
-typedef pe_properties_generic<pe_types_class_64> pe_properties_64;
-}
diff --git a/tools/pe_bliss/pe_rebuilder.cpp b/tools/pe_bliss/pe_rebuilder.cpp
deleted file mode 100644
index faf5803b8c..0000000000
--- a/tools/pe_bliss/pe_rebuilder.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_rebuilder.h"
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_exception.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Rebuilds PE image headers
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, image_dos_header& dos_header, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- dos_header = pe.get_dos_header();
-
- if(strip_dos_header)
- {
- //Strip stub overlay
- pe.strip_stub_overlay();
- //BaseOfCode NT Headers field now overlaps
- //e_lfanew field, so we're acrually setting
- //e_lfanew with this call
- pe.set_base_of_code(8 * sizeof(uint16_t));
- }
- else
- {
- //Set start of PE headers
- dos_header.e_lfanew = sizeof(image_dos_header)
- + pe_utils::align_up(static_cast<uint32_t>(pe.get_stub_overlay().size()), sizeof(uint32_t));
- }
-
- section_list& sections = pe.get_image_sections();
-
- //Calculate pointer to section data
- size_t ptr_to_section_data = (strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)) + pe.get_sizeof_nt_header()
- + pe_utils::align_up(pe.get_stub_overlay().size(), sizeof(uint32_t))
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())
- + sections.size() * sizeof(image_section_header);
-
- if(save_bound_import && pe.has_bound_import())
- {
- //It will be aligned to DWORD, because we're aligning to DWORD everything above it
- pe.set_directory_rva(image_directory_entry_bound_import, static_cast<uint32_t>(ptr_to_section_data));
- ptr_to_section_data += pe.get_directory_size(image_directory_entry_bound_import);
- }
-
- ptr_to_section_data = pe_utils::align_up(ptr_to_section_data, pe.get_file_alignment());
-
- //Set size of headers and size of optional header
- if(change_size_of_headers)
- {
- if(!pe.get_image_sections().empty())
- {
- if(static_cast<uint32_t>(ptr_to_section_data) > (*sections.begin()).get_virtual_address())
- throw pe_exception("Headers of PE file are too long. Try to strip STUB or don't build bound import", pe_exception::cannot_rebuild_image);
- }
-
- pe.set_size_of_headers(static_cast<uint32_t>(ptr_to_section_data));
- }
-
- //Set number of sections in PE header
- pe.update_number_of_sections();
-
- pe.update_image_size();
-
- pe.set_size_of_optional_header(static_cast<uint16_t>(pe.get_sizeof_opt_headers()
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())));
-
- //Recalculate pointer to raw data according to section list
- for(section_list::iterator it = sections.begin(); it != sections.end(); ++it)
- {
- //Save section headers PointerToRawData
- (*it).set_pointer_to_raw_data(static_cast<uint32_t>(ptr_to_section_data));
- ptr_to_section_data += (*it).get_aligned_raw_size(pe.get_file_alignment());
- }
-}
-
-//Rebuild PE image and write it to "out" ostream
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- if(out.bad())
- throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
- if(save_bound_import && pe.has_bound_import())
- {
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true)
- < pe.get_directory_size(image_directory_entry_bound_import))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
- }
-
- //Change ostream state
- out.exceptions(std::ios::goodbit);
- out.clear();
-
- uint32_t original_bound_import_rva = pe.has_bound_import() ? pe.get_directory_rva(image_directory_entry_bound_import) : 0;
- if(original_bound_import_rva && original_bound_import_rva > pe.get_size_of_headers())
- {
- //No need to do anything with bound import directory
- //if it is placed inside of any section, not headers
- original_bound_import_rva = 0;
- save_bound_import = false;
- }
-
- {
- image_dos_header dos_header;
-
- //Rebuild PE image headers
- rebuild_pe(pe, dos_header, strip_dos_header, change_size_of_headers, save_bound_import);
-
- //Write DOS header
- out.write(reinterpret_cast<const char*>(&dos_header), strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header));
- }
-
- //If we have stub overlay, write it too
- {
- const std::string& stub = pe.get_stub_overlay();
- if(stub.size())
- {
- out.write(stub.data(), stub.size());
- size_t aligned_size = pe_utils::align_up(stub.size(), sizeof(uint32_t));
- //Align PE header, which is right after rich overlay
- while(aligned_size > stub.size())
- {
- out.put('\0');
- --aligned_size;
- }
- }
- }
-
- //Write NT headers
- out.write(static_cast<const pe_base&>(pe).get_nt_headers_ptr(), pe.get_sizeof_nt_header()
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes()));
-
- //Write section headers
- const section_list& sections = pe.get_image_sections();
- for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
- {
- if(it == sections.end() - 1) //If last section encountered
- {
- image_section_header header((*it).get_raw_header());
- header.SizeOfRawData = static_cast<uint32_t>((*it).get_raw_data().length()); //Set non-aligned actual data length for it
- out.write(reinterpret_cast<const char*>(&header), sizeof(image_section_header));
- }
- else
- {
- out.write(reinterpret_cast<const char*>(&(*it).get_raw_header()), sizeof(image_section_header));
- }
- }
-
- //Write bound import data if requested
- if(save_bound_import && pe.has_bound_import())
- {
- out.write(pe.section_data_from_rva(original_bound_import_rva, section_data_raw, true),
- pe.get_directory_size(image_directory_entry_bound_import));
- }
-
- //Write section data finally
- for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
- {
- const section& s = *it;
-
- std::streamoff wpos = out.tellp();
-
- //Fill unused overlay data between sections with null bytes
- for(unsigned int i = 0; i < s.get_pointer_to_raw_data() - wpos; i++)
- out.put(0);
-
- //Write raw section data
- out.write(s.get_raw_data().data(), s.get_raw_data().length());
- }
-}
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- std::ofstream pe_file(out, std::ios::out | std::ios::binary | std::ios::trunc);
- if(!pe_file)
- {
- throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
- }
- rebuild_pe(pe, pe_file, strip_dos_header, change_size_of_headers, save_bound_import);
-}
-
-
-}
diff --git a/tools/pe_bliss/pe_rebuilder.h b/tools/pe_bliss/pe_rebuilder.h
deleted file mode 100644
index 319807e5c9..0000000000
--- a/tools/pe_bliss/pe_rebuilder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <ostream>
-#include <fstream>
-
-namespace pe_bliss
-{
-class pe_base;
-//Rebuilds PE image, writes resulting image to ostream "out". If strip_dos_header == true, DOS header will be stripped a little
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-}
diff --git a/tools/pe_bliss/pe_relocations.cpp b/tools/pe_bliss/pe_relocations.cpp
deleted file mode 100644
index d5357dd219..0000000000
--- a/tools/pe_bliss/pe_relocations.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_relocations.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RELOCATIONS
-//Default constructor
-relocation_entry::relocation_entry()
- :rva_(0), type_(0)
-{}
-
-//Constructor from relocation item (WORD)
-relocation_entry::relocation_entry(uint16_t relocation_value)
- :rva_(relocation_value & ((1 << 12) - 1)), type_(relocation_value >> 12)
-{}
-
-//Constructor from relative rva and relocation type
-relocation_entry::relocation_entry(uint16_t rrva, uint16_t type)
- :rva_(rrva), type_(type)
-{}
-
-//Returns RVA of relocation
-uint16_t relocation_entry::get_rva() const
-{
- return rva_;
-}
-
-//Returns type of relocation
-uint16_t relocation_entry::get_type() const
-{
- return type_;
-}
-
-//Sets RVA of relocation
-void relocation_entry::set_rva(uint16_t rva)
-{
- rva_ = rva;
-}
-
-//Sets type of relocation
-void relocation_entry::set_type(uint16_t type)
-{
- type_ = type;
-}
-
-//Returns relocation item (rrva + type)
-uint16_t relocation_entry::get_item() const
-{
- return rva_ | (type_ << 12);
-}
-
-//Sets relocation item (rrva + type)
-void relocation_entry::set_item(uint16_t item)
-{
- rva_ = item & ((1 << 12) - 1);
- type_ = item >> 12;
-}
-
-//Returns relocation list
-const relocation_table::relocation_list& relocation_table::get_relocations() const
-{
- return relocations_;
-}
-
-//Adds relocation to table
-void relocation_table::add_relocation(const relocation_entry& entry)
-{
- relocations_.push_back(entry);
-}
-
-//Default constructor
-relocation_table::relocation_table()
- :rva_(0)
-{}
-
-//Constructor from RVA of relocation table
-relocation_table::relocation_table(uint32_t rva)
- :rva_(rva)
-{}
-
-//Returns RVA of block
-uint32_t relocation_table::get_rva() const
-{
- return rva_;
-}
-
-//Sets RVA of block
-void relocation_table::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Returns changeable relocation list
-relocation_table::relocation_list& relocation_table::get_relocations()
-{
- return relocations_;
-}
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries)
-{
- relocation_table_list ret;
-
- //If image does not have relocations
- if(!pe.has_reloc())
- return ret;
-
- //Check the length in bytes of the section containing relocation directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_basereloc),
- pe.get_directory_rva(image_directory_entry_basereloc), section_data_virtual, true)
- < sizeof(image_base_relocation))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_basereloc);
- //First IMAGE_BASE_RELOCATION table
- image_base_relocation reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
-
- if(reloc_table.SizeOfBlock % 2)
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- unsigned long reloc_size = pe.get_directory_size(image_directory_entry_basereloc);
- unsigned long read_size = 0;
-
- //reloc_table.VirtualAddress is not checked (not so important)
- while(reloc_table.SizeOfBlock && read_size < reloc_size)
- {
- //Create relocation table
- relocation_table table;
- //Save RVA
- table.set_rva(reloc_table.VirtualAddress);
-
- if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- //List all relocations
- for(unsigned long i = sizeof(image_base_relocation); i < reloc_table.SizeOfBlock; i += sizeof(uint16_t))
- {
- relocation_entry entry(pe.section_data_from_rva<uint16_t>(current_pos + i, section_data_virtual, true));
- if(list_absolute_entries || entry.get_type() != image_rel_based_absolute)
- table.add_relocation(entry);
- }
-
- //Save table
- ret.push_back(table);
-
- //Go to next relocation block
- if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- current_pos += reloc_table.SizeOfBlock;
- read_size += reloc_table.SizeOfBlock;
- reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that reloc_section is attached to this PE image
- if(!pe.section_attached(reloc_section))
- throw pe_exception("Relocations section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t current_reloc_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
- uint32_t needed_size = current_reloc_data_pos - offset_from_section_start; //Calculate needed size for relocation tables
- uint32_t size_delta = needed_size;
-
- uint32_t start_reloc_pos = current_reloc_data_pos;
-
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
- {
- needed_size += static_cast<uint32_t>((*it).get_relocations().size() * sizeof(uint16_t) /* relocations */ + sizeof(image_base_relocation) /* table header */);
- //End of each table will be DWORD-aligned
- if((start_reloc_pos + needed_size - size_delta) % sizeof(uint32_t))
- needed_size += sizeof(uint16_t); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
- }
-
- //Check if reloc_section is last one. If it's not, check if there's enough place for relocations data
- if(&reloc_section != &*(pe.get_image_sections().end() - 1) &&
- (reloc_section.empty() || pe_utils::align_up(reloc_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + current_reloc_data_pos))
- throw pe_exception("Insufficient space for relocations directory", pe_exception::insufficient_space);
-
- std::string& raw_data = reloc_section.get_raw_data();
-
- //This will be done only if reloc_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + current_reloc_data_pos)
- raw_data.resize(needed_size + current_reloc_data_pos); //Expand section raw data
-
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
- {
- //Create relocation table header
- image_base_relocation reloc;
- reloc.VirtualAddress = (*it).get_rva();
- const relocation_table::relocation_list& reloc_list = (*it).get_relocations();
- reloc.SizeOfBlock = static_cast<uint32_t>(sizeof(image_base_relocation) + sizeof(uint16_t) * reloc_list.size());
- if((reloc_list.size() * sizeof(uint16_t)) % sizeof(uint32_t)) //If we must align end of relocation table
- reloc.SizeOfBlock += sizeof(uint16_t);
-
- memcpy(&raw_data[current_reloc_data_pos], &reloc, sizeof(reloc));
- current_reloc_data_pos += sizeof(reloc);
-
- //Enumerate relocations in table
- for(relocation_table::relocation_list::const_iterator r = reloc_list.begin(); r != reloc_list.end(); ++r)
- {
- //Save relocations
- uint16_t reloc_value = (*r).get_item();
- memcpy(&raw_data[current_reloc_data_pos], &reloc_value, sizeof(reloc_value));
- current_reloc_data_pos += sizeof(reloc_value);
- }
-
- if(current_reloc_data_pos % sizeof(uint32_t)) //If end of table is not DWORD-aligned
- {
- memset(&raw_data[current_reloc_data_pos], 0, sizeof(uint16_t)); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
- current_reloc_data_pos += sizeof(uint16_t);
- }
- }
-
- image_directory ret(pe.rva_from_section_offset(reloc_section, start_reloc_pos), needed_size - size_delta);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(reloc_section, auto_strip_last_section);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_basereloc, ret.get_rva());
- pe.set_directory_size(image_directory_entry_basereloc, ret.get_size());
-
- pe.clear_characteristics_flags(image_file_relocs_stripped);
- pe.set_dll_characteristics(pe.get_dll_characteristics() | image_dllcharacteristics_dynamic_base);
- }
-
- return ret;
-}
-
-//Recalculates image base with the help of relocation tables
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
- pe.get_pe_type() == pe_type_32
- ? rebase_image_base<pe_types_class_32>(pe, tables, new_base)
- : rebase_image_base<pe_types_class_64>(pe, tables, new_base);
-}
-
-//RELOCATIONS
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
- //Get current image base value
- typename PEClassType::BaseSize image_base;
- pe.get_image_base(image_base);
-
- //ImageBase difference
- typename PEClassType::BaseSize base_rel = static_cast<typename PEClassType::BaseSize>(static_cast<int64_t>(new_base) - image_base);
-
- //We need to fix addresses from relocation tables
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it)
- {
- const relocation_table::relocation_list& relocs = (*it).get_relocations();
-
- uint32_t base_rva = (*it).get_rva();
-
- //Enumerate relocations
- for(relocation_table::relocation_list::const_iterator rel = relocs.begin(); rel != relocs.end(); ++rel)
- {
- //Skip ABSOLUTE entries
- if((*rel).get_type() == pe_win::image_rel_based_absolute)
- continue;
-
- //Recalculate value by RVA and rewrite it
- uint32_t current_rva = base_rva + (*rel).get_rva();
- typename PEClassType::BaseSize value = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_rva, section_data_raw, true);
- value += base_rel;
- memcpy(pe.section_data_from_rva(current_rva, true), &value, sizeof(value));
- }
- }
-
- //Finally, save new image base
- pe.set_image_base_64(new_base);
-}
-}
diff --git a/tools/pe_bliss/pe_relocations.h b/tools/pe_bliss/pe_relocations.h
deleted file mode 100644
index 1bc8b2a405..0000000000
--- a/tools/pe_bliss/pe_relocations.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing relocation entry
-//RVA of relocation is not actually RVA, but
-//(real RVA) - (RVA of table)
-class relocation_entry
-{
-public:
- //Default constructor
- relocation_entry();
- //Constructor from relocation item (WORD)
- explicit relocation_entry(uint16_t relocation_value);
- //Constructor from relative rva and relocation type
- relocation_entry(uint16_t rrva, uint16_t type);
-
- //Returns RVA of relocation (actually, relative RVA from relocation table RVA)
- uint16_t get_rva() const;
- //Returns type of relocation
- uint16_t get_type() const;
-
- //Returns relocation item (rrva + type)
- uint16_t get_item() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild relocations using rebuild_relocations()
-
- //Sets RVA of relocation (actually, relative RVA from relocation table RVA)
- void set_rva(uint16_t rva);
- //Sets type of relocation
- void set_type(uint16_t type);
-
- //Sets relocation item (rrva + type)
- void set_item(uint16_t item);
-
-private:
- uint16_t rva_;
- uint16_t type_;
-};
-
-//Class representing relocation table
-class relocation_table
-{
-public:
- typedef std::vector<relocation_entry> relocation_list;
-
-public:
- //Default constructor
- relocation_table();
- //Constructor from RVA of relocation table
- explicit relocation_table(uint32_t rva);
-
- //Returns relocation list
- const relocation_list& get_relocations() const;
- //Returns RVA of block
- uint32_t get_rva() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild relocations using rebuild_relocations()
-
- //Adds relocation to table
- void add_relocation(const relocation_entry& entry);
- //Returns changeable relocation list
- relocation_list& get_relocations();
- //Sets RVA of block
- void set_rva(uint32_t rva);
-
-private:
- uint32_t rva_;
- relocation_list relocations_;
-};
-
-typedef std::vector<relocation_table> relocation_table_list;
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries = false);
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-}
diff --git a/tools/pe_bliss/pe_resource_manager.cpp b/tools/pe_bliss/pe_resource_manager.cpp
deleted file mode 100644
index 0ee7840ff0..0000000000
--- a/tools/pe_bliss/pe_resource_manager.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <sstream>
-#include <iomanip>
-#include <math.h>
-#include <string.h>
-#include "pe_resource_manager.h"
-#include "resource_internal.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource directory
-pe_resource_manager::pe_resource_manager(resource_directory& root_directory)
- :pe_resource_viewer(root_directory), root_dir_edit_(root_directory)
-{}
-
-resource_directory& pe_resource_manager::get_root_directory()
-{
- return root_dir_edit_;
-}
-
-//Removes all resources of given type or root name
-//If there's more than one directory entry of a given type, only the
-//first one will be deleted (that's an unusual situation)
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource_type(resource_type type)
-{
- //Search for resource type
- resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type));
- if(it != entries.end())
- {
- //Remove it, if found
- entries.erase(it);
- return true;
- }
-
- return false;
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name)
-{
- //Search for resource type
- resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name));
- if(it != entries.end())
- {
- //Remove it, if found
- entries.erase(it);
- return true;
- }
-
- return false;
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder)
-{
- //Search for resource type
- resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
- if(it_type != entries_type.end())
- {
- //Search for resource name/ID with "finder"
- resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
- if(it_name != entries_name.end())
- {
- //Erase resource, if found
- entries_name.erase(it_name);
- if(entries_name.empty())
- entries_type.erase(it_type);
-
- return true;
- }
- }
-
- return false;
-}
-
-//Removes all resource languages by resource type/root name and name
-//Deletes only one entry of given type and name
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name));
-}
-
-//Removes all resource languages by resource type/root name and ID
-//Deletes only one entry of given type and ID
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id));
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language)
-{
- //Search for resource type
- resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
- if(it_type != entries_type.end())
- {
- //Search for resource name/ID with "finder"
- resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
- if(it_name != entries_name.end())
- {
- //Search for resource language
- resource_directory::entry_list& entries_lang = (*it_name).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_lang = std::find_if(entries_lang.begin(), entries_lang.end(), resource_directory::id_entry_finder(language));
- if(it_lang != entries_lang.end())
- {
- //Erase resource, if found
- entries_lang.erase(it_lang);
- if(entries_lang.empty())
- {
- entries_name.erase(it_name);
- if(entries_name.empty())
- entries_type.erase(it_type);
- }
-
- return true;
- }
- }
- }
-
- return false;
-}
-
-//Removes resource language by resource type/root name and name
-//Deletes only one entry of given type, name and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name), language);
-}
-
-//Removes recource language by resource type/root name and ID
-//Deletes only one entry of given type, ID and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id), language);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_type_entry;
- new_type_entry.set_id(type);
-
- add_resource(data, new_type_entry, resource_directory::entry_finder(type), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_type_entry;
- new_type_entry.set_name(root_name);
-
- add_resource(data, new_type_entry, resource_directory::entry_finder(root_name), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_directory_entry& new_root_entry, const resource_directory::entry_finder& root_finder, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Search for resource type
- resource_directory::entry_list* entries = &root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries->begin(), entries->end(), root_finder);
- if(it == entries->end())
- {
- //Add resource type directory, if it was not found
- resource_directory dir;
- dir.set_timestamp(timestamp);
- new_root_entry.add_resource_directory(dir);
- entries->push_back(new_root_entry);
- it = entries->end() - 1;
- }
-
- //Search for resource name/ID directory with "finder"
- entries = &(*it).get_resource_directory().get_entry_list();
- it = std::find_if(entries->begin(), entries->end(), finder);
- if(it == entries->end())
- {
- //Add resource name/ID directory, if it was not found
- resource_directory dir;
- dir.set_timestamp(timestamp);
- new_entry.add_resource_directory(dir);
- entries->push_back(new_entry);
- it = entries->end() - 1;
- }
-
- //Search for data resource entry by language
- entries = &(*it).get_resource_directory().get_entry_list();
- it = std::find_if(entries->begin(), entries->end(), resource_directory::id_entry_finder(language));
- if(it != entries->end())
- entries->erase(it); //Erase it, if found
-
- //Add new data entry
- resource_directory_entry new_dir_data_entry;
- resource_data_entry data_dir(data, codepage);
- new_dir_data_entry.add_data_entry(data_dir);
- new_dir_data_entry.set_id(language);
- entries->push_back(new_dir_data_entry);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- add_resource(data, type, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- add_resource(data, root_name, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- add_resource(data, type, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- add_resource(data, root_name, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-}
diff --git a/tools/pe_bliss/pe_resource_manager.h b/tools/pe_bliss/pe_resource_manager.h
deleted file mode 100644
index 85d7f44a8a..0000000000
--- a/tools/pe_bliss/pe_resource_manager.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <sstream>
-#include <string>
-#include <memory>
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "file_version_info.h"
-#include "pe_resource_viewer.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
-//Derived class to edit PE resources
-class pe_resource_manager : public pe_resource_viewer
-{
-public:
- //Constructor from root resource directory
- explicit pe_resource_manager(resource_directory& root_directory);
-
- resource_directory& get_root_directory();
-
-public: //Resource editing
- //Removes all resources of given type or root name
- //If there's more than one directory entry of a given type, only the
- //first one will be deleted (that's an unusual situation)
- //Returns true if resource was deleted
- bool remove_resource_type(resource_type type);
- bool remove_resource(const std::wstring& root_name);
-
- //Removes all resource languages by resource type/root name and name
- //Deletes only one entry of given type and name
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, const std::wstring& name);
- bool remove_resource(const std::wstring& root_name, const std::wstring& name);
- //Removes all resource languages by resource type/root name and ID
- //Deletes only one entry of given type and ID
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, uint32_t id);
- bool remove_resource(const std::wstring& root_name, uint32_t id);
-
- //Removes resource language by resource type/root name and name
- //Deletes only one entry of given type, name and language
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, const std::wstring& name, uint32_t language);
- bool remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language);
- //Removes recource language by resource type/root name and ID
- //Deletes only one entry of given type, ID and language
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, uint32_t id, uint32_t language);
- bool remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language);
-
- //Adds resource. If resource already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- //Adds resource. If resource already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-public:
- //Helpers to add/replace resource
- void add_resource(const std::string& data, resource_type type,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
- void add_resource(const std::string& data, const std::wstring& root_name,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
- void add_resource(const std::string& data, resource_directory_entry& new_root_entry,
- const resource_directory::entry_finder& root_finder,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
-private:
- //Root resource directory. We're not copying it, because it might be heavy
- resource_directory& root_dir_edit_;
-
- //Helper to remove resource
- bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder);
-
- //Helper to remove resource
- bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language);
-};
-}
diff --git a/tools/pe_bliss/pe_resource_viewer.cpp b/tools/pe_bliss/pe_resource_viewer.cpp
deleted file mode 100644
index 712cc28d9b..0000000000
--- a/tools/pe_bliss/pe_resource_viewer.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <cmath>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource_directory
-pe_resource_viewer::pe_resource_viewer(const resource_directory& root_directory)
- :root_dir_(root_directory)
-{}
-
-const resource_directory& pe_resource_viewer::get_root_directory() const
-{
- return root_dir_;
-}
-
-//Finder helpers
-bool pe_resource_viewer::has_name::operator()(const resource_directory_entry& entry) const
-{
- return entry.is_named();
-}
-
-bool pe_resource_viewer::has_id::operator()(const resource_directory_entry& entry) const
-{
- return !entry.is_named();
-}
-
-//Lists resource types existing in PE file (non-named only)
-const pe_resource_viewer::resource_type_list pe_resource_viewer::list_resource_types() const
-{
- resource_type_list ret;
-
- //Get root directory entries list
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all non-named items
- if(!(*it).is_named())
- ret.push_back((*it).get_id());
- }
-
- return ret;
-}
-
-//Returns true if resource type exists
-bool pe_resource_viewer::resource_exists(resource_type type) const
-{
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- return std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type)) != entries.end();
-}
-
-//Returns true if resource name exists
-bool pe_resource_viewer::resource_exists(const std::wstring& root_name) const
-{
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- return std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name)) != entries.end();
-}
-
-//Helper function to get name list from entry list
-const pe_resource_viewer::resource_name_list pe_resource_viewer::get_name_list(const resource_directory::entry_list& entries)
-{
- resource_name_list ret;
-
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all named items
- if((*it).is_named())
- ret.push_back((*it).get_name());
- }
-
- return ret;
-}
-
-//Helper function to get ID list from entry list
-const pe_resource_viewer::resource_id_list pe_resource_viewer::get_id_list(const resource_directory::entry_list& entries)
-{
- resource_id_list ret;
-
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all non-named items
- if(!(*it).is_named())
- ret.push_back((*it).get_id());
- }
-
- return ret;
-}
-
-//Lists resource names existing in PE file by resource type
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(resource_type type) const
-{
- return get_name_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource names existing in PE file by resource name
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(const std::wstring& root_name) const
-{
- return get_name_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource type
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(resource_type type) const
-{
- return get_id_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource name
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(const std::wstring& root_name) const
-{
- return get_id_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Returns resource count by type
-unsigned long pe_resource_viewer::get_resource_count(resource_type type) const
-{
- return static_cast<unsigned long>(
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .get_entry_list()
- .size());
-}
-
-//Returns resource count by name
-unsigned long pe_resource_viewer::get_resource_count(const std::wstring& root_name) const
-{
- return static_cast<unsigned long>(
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .get_entry_list()
- .size());
-}
-
-//Returns language count of resource by resource type and name
-unsigned long pe_resource_viewer::get_language_count(resource_type type, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource names
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource type and ID
-unsigned long pe_resource_viewer::get_language_count(resource_type type, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource name and ID
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Lists resource languages by resource type and name
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource names
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource type and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource name and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Returns raw resource data by type, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-}
diff --git a/tools/pe_bliss/pe_resource_viewer.h b/tools/pe_bliss/pe_resource_viewer.h
deleted file mode 100644
index e585da6a87..0000000000
--- a/tools/pe_bliss/pe_resource_viewer.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
- //PE resource manager allows to read resources from PE files
-class pe_resource_viewer
-{
-public:
- //Resource type enumeration
- enum resource_type
- {
- resource_cursor = 1,
- resource_bitmap = 2,
- resource_icon = 3,
- resource_menu = 4,
- resource_dialog = 5,
- resource_string = 6,
- resource_fontdir = 7,
- resource_font = 8,
- resource_accelerator = 9,
- resource_rcdata = 10,
- resource_message_table = 11,
- resource_cursor_group = 12,
- resource_icon_group = 14,
- resource_version = 16,
- resource_dlginclude = 17,
- resource_plugplay = 19,
- resource_vxd = 20,
- resource_anicursor = 21,
- resource_aniicon = 22,
- resource_html = 23,
- resource_manifest = 24
- };
-
-public:
- //Some useful typedefs
- typedef std::vector<uint32_t> resource_type_list;
- typedef std::vector<uint32_t> resource_id_list;
- typedef std::vector<std::wstring> resource_name_list;
- typedef std::vector<uint32_t> resource_language_list;
-
-public:
- //Constructor from root resource_directory from PE file
- explicit pe_resource_viewer(const resource_directory& root_directory);
-
- const resource_directory& get_root_directory() const;
-
- //Lists resource types existing in PE file (non-named only)
- const resource_type_list list_resource_types() const;
- //Returns true if resource type exists
- bool resource_exists(resource_type type) const;
- //Returns true if resource name exists
- bool resource_exists(const std::wstring& root_name) const;
-
- //Lists resource names existing in PE file by resource type
- const resource_name_list list_resource_names(resource_type type) const;
- //Lists resource names existing in PE file by resource name
- const resource_name_list list_resource_names(const std::wstring& root_name) const;
- //Lists resource IDs existing in PE file by resource type
- const resource_id_list list_resource_ids(resource_type type) const;
- //Lists resource IDs existing in PE file by resource name
- const resource_id_list list_resource_ids(const std::wstring& root_name) const;
- //Returns resource count by type
- unsigned long get_resource_count(resource_type type) const;
- //Returns resource count by name
- unsigned long get_resource_count(const std::wstring& root_name) const;
-
- //Returns language count of resource by resource type and name
- unsigned long get_language_count(resource_type type, const std::wstring& name) const;
- //Returns language count of resource by resource names
- unsigned long get_language_count(const std::wstring& root_name, const std::wstring& name) const;
- //Returns language count of resource by resource type and ID
- unsigned long get_language_count(resource_type type, uint32_t id) const;
- //Returns language count of resource by resource name and ID
- unsigned long get_language_count(const std::wstring& root_name, uint32_t id) const;
- //Lists resource languages by resource type and name
- const resource_language_list list_resource_languages(resource_type type, const std::wstring& name) const;
- //Lists resource languages by resource names
- const resource_language_list list_resource_languages(const std::wstring& root_name, const std::wstring& name) const;
- //Lists resource languages by resource type and ID
- const resource_language_list list_resource_languages(resource_type type, uint32_t id) const;
- //Lists resource languages by resource name and ID
- const resource_language_list list_resource_languages(const std::wstring& root_name, uint32_t id) const;
-
- //Returns raw resource data by type, name and language
- const resource_data_info get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const;
- //Returns raw resource data by root name, name and language
- const resource_data_info get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const;
- //Returns raw resource data by type, ID and language
- const resource_data_info get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const;
- //Returns raw resource data by root name, ID and language
- const resource_data_info get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const;
- //Returns raw resource data by type, name and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index = 0) const;
- //Returns raw resource data by root name, name and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index = 0) const;
- //Returns raw resource data by type, ID and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index = 0) const;
- //Returns raw resource data by root name, ID and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index = 0) const;
-
-protected:
- //Root resource directory. We're not copying it, because it might be heavy
- const resource_directory& root_dir_;
-
- //Helper function to get ID list from entry list
- static const resource_id_list get_id_list(const resource_directory::entry_list& entries);
- //Helper function to get name list from entry list
- static const resource_name_list get_name_list(const resource_directory::entry_list& entries);
-
-protected:
- //Helper structure - finder of resource_directory_entry that is named
- struct has_name
- {
- public:
- bool operator()(const resource_directory_entry& entry) const;
- };
-
- //Helper structure - finder of resource_directory_entry that is not named (has id)
- struct has_id
- {
- public:
- bool operator()(const resource_directory_entry& entry) const;
- };
-};
-}
diff --git a/tools/pe_bliss/pe_resources.cpp b/tools/pe_bliss/pe_resources.cpp
deleted file mode 100644
index 189aba1f76..0000000000
--- a/tools/pe_bliss/pe_resources.cpp
+++ /dev/null
@@ -1,726 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "pe_resources.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RESOURCES
-//Default constructor
-resource_data_entry::resource_data_entry()
- :codepage_(0)
-{}
-
-//Constructor from data
-resource_data_entry::resource_data_entry(const std::string& data, uint32_t codepage)
- :codepage_(codepage), data_(data)
-{}
-
-//Returns resource data codepage
-uint32_t resource_data_entry::get_codepage() const
-{
- return codepage_;
-}
-
-//Returns resource data
-const std::string& resource_data_entry::get_data() const
-{
- return data_;
-}
-
-//Sets resource data codepage
-void resource_data_entry::set_codepage(uint32_t codepage)
-{
- codepage_ = codepage;
-}
-
-//Sets resource data
-void resource_data_entry::set_data(const std::string& data)
-{
- data_ = data;
-}
-
-//Default constructor
-resource_directory_entry::includes::includes()
- :data_(0)
-{}
-
-//Default constructor
-resource_directory_entry::resource_directory_entry()
- :id_(0), includes_data_(false), named_(false)
-{}
-
-//Copy constructor
-resource_directory_entry::resource_directory_entry(const resource_directory_entry& other)
- :id_(other.id_), name_(other.name_), includes_data_(other.includes_data_), named_(other.named_)
-{
- //If union'ed pointer is not zero
- if(other.ptr_.data_)
- {
- if(other.includes_data())
- ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
- else
- ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
- }
-}
-
-//Copy assignment operator
-resource_directory_entry& resource_directory_entry::operator=(const resource_directory_entry& other)
-{
- release();
-
- id_ = other.id_;
- name_ = other.name_;
- includes_data_ = other.includes_data_;
- named_ = other.named_;
-
- //If other union'ed pointer is not zero
- if(other.ptr_.data_)
- {
- if(other.includes_data())
- ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
- else
- ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
- }
-
- return *this;
-}
-
-//Destroys included data
-void resource_directory_entry::release()
-{
- //If union'ed pointer is not zero
- if(ptr_.data_)
- {
- if(includes_data())
- delete ptr_.data_;
- else
- delete ptr_.dir_;
-
- ptr_.data_ = 0;
- }
-}
-
-//Destructor
-resource_directory_entry::~resource_directory_entry()
-{
- release();
-}
-
-//Returns entry ID
-uint32_t resource_directory_entry::get_id() const
-{
- return id_;
-}
-
-//Returns entry name
-const std::wstring& resource_directory_entry::get_name() const
-{
- return name_;
-}
-
-//Returns true, if entry has name
-//Returns false, if entry has ID
-bool resource_directory_entry::is_named() const
-{
- return named_;
-}
-
-//Returns true, if entry includes resource_data_entry
-//Returns false, if entry includes resource_directory
-bool resource_directory_entry::includes_data() const
-{
- return includes_data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-const resource_directory& resource_directory_entry::get_resource_directory() const
-{
- if(!ptr_.dir_ || includes_data_)
- throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
- return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-const resource_data_entry& resource_directory_entry::get_data_entry() const
-{
- if(!ptr_.data_ || !includes_data_)
- throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
- return *ptr_.data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-resource_directory& resource_directory_entry::get_resource_directory()
-{
- if(!ptr_.dir_ || includes_data_)
- throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
- return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-resource_data_entry& resource_directory_entry::get_data_entry()
-{
- if(!ptr_.data_ || !includes_data_)
- throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
- return *ptr_.data_;
-}
-
-//Sets entry name
-void resource_directory_entry::set_name(const std::wstring& name)
-{
- name_ = name;
- named_ = true;
- id_ = 0;
-}
-
-//Sets entry ID
-void resource_directory_entry::set_id(uint32_t id)
-{
- id_ = id;
- named_ = false;
- name_.clear();
-}
-
-//Adds resource_data_entry
-void resource_directory_entry::add_data_entry(const resource_data_entry& entry)
-{
- release();
- ptr_.data_ = new resource_data_entry(entry);
- includes_data_ = true;
-}
-
-//Adds resource_directory
-void resource_directory_entry::add_resource_directory(const resource_directory& dir)
-{
- release();
- ptr_.dir_ = new resource_directory(dir);
- includes_data_ = false;
-}
-
-//Default constructor
-resource_directory::resource_directory()
- :characteristics_(0),
- timestamp_(0),
- major_version_(0), minor_version_(0),
- number_of_named_entries_(0), number_of_id_entries_(0)
-{}
-
-//Constructor from data
-resource_directory::resource_directory(const image_resource_directory& dir)
- :characteristics_(dir.Characteristics),
- timestamp_(dir.TimeDateStamp),
- major_version_(dir.MajorVersion), minor_version_(dir.MinorVersion),
- number_of_named_entries_(0), number_of_id_entries_(0) //Set to zero here, calculate on add
-{}
-
-//Returns characteristics of directory
-uint32_t resource_directory::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns date and time stamp of directory
-uint32_t resource_directory::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns major version of directory
-uint16_t resource_directory::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version of directory
-uint16_t resource_directory::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns number of named entries
-uint32_t resource_directory::get_number_of_named_entries() const
-{
- return number_of_named_entries_;
-}
-
-//Returns number of ID entries
-uint32_t resource_directory::get_number_of_id_entries() const
-{
- return number_of_id_entries_;
-}
-
-//Returns resource_directory_entry array
-const resource_directory::entry_list& resource_directory::get_entry_list() const
-{
- return entries_;
-}
-
-//Returns resource_directory_entry array
-resource_directory::entry_list& resource_directory::get_entry_list()
-{
- return entries_;
-}
-
-//Adds resource_directory_entry
-void resource_directory::add_resource_directory_entry(const resource_directory_entry& entry)
-{
- entries_.push_back(entry);
- if(entry.is_named())
- ++number_of_named_entries_;
- else
- ++number_of_id_entries_;
-}
-
-//Clears resource_directory_entry array
-void resource_directory::clear_resource_directory_entry_list()
-{
- entries_.clear();
- number_of_named_entries_ = 0;
- number_of_id_entries_ = 0;
-}
-
-//Sets characteristics of directory
-void resource_directory::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets date and time stamp of directory
-void resource_directory::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Sets number of named entries
-void resource_directory::set_number_of_named_entries(uint32_t number)
-{
- number_of_named_entries_ = number;
-}
-
-//Sets number of ID entries
-void resource_directory::set_number_of_id_entries(uint32_t number)
-{
- number_of_id_entries_ = number;
-}
-
-//Sets major version of directory
-void resource_directory::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version of directory
-void resource_directory::get_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Processes resource directory
-const resource_directory process_resource_directory(const pe_base& pe, uint32_t res_rva, uint32_t offset_to_directory, std::set<uint32_t>& processed)
-{
- resource_directory ret;
-
- //Check for resource loops
- if(!processed.insert(offset_to_directory).second)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- if(!pe_utils::is_sum_safe(res_rva, offset_to_directory))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //Get root IMAGE_RESOURCE_DIRECTORY
- image_resource_directory directory = pe.section_data_from_rva<image_resource_directory>(res_rva + offset_to_directory, section_data_virtual, true);
-
- ret = resource_directory(directory);
-
- //Check DWORDs for possible overflows
- if(!pe_utils::is_sum_safe(directory.NumberOfIdEntries, directory.NumberOfNamedEntries)
- || directory.NumberOfIdEntries + directory.NumberOfNamedEntries >= pe_utils::max_dword / sizeof(image_resource_directory_entry) + sizeof(image_resource_directory))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- if(!pe_utils::is_sum_safe(offset_to_directory, sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry))
- || !pe_utils::is_sum_safe(res_rva, offset_to_directory + sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry)))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- for(unsigned long i = 0; i != static_cast<unsigned long>(directory.NumberOfIdEntries) + directory.NumberOfNamedEntries; ++i)
- {
- //Read directory entries one by one
- image_resource_directory_entry dir_entry = pe.section_data_from_rva<image_resource_directory_entry>(
- res_rva + sizeof(image_resource_directory) + i * sizeof(image_resource_directory_entry) + offset_to_directory, section_data_virtual, true);
-
- //Create directory entry structure
- resource_directory_entry entry;
-
- //If directory is named
- if(dir_entry.NameIsString)
- {
- if(!pe_utils::is_sum_safe(res_rva + sizeof(uint16_t) /* safe */, dir_entry.NameOffset))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //get directory name length
- uint16_t directory_name_length = pe.section_data_from_rva<uint16_t>(res_rva + dir_entry.NameOffset, section_data_virtual, true);
-
- //Check name length
- if(pe.section_data_length_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)
- < directory_name_length)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-#ifdef PE_BLISS_WINDOWS
- //Set entry UNICODE name
- entry.set_name(std::wstring(
- reinterpret_cast<const wchar_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
- directory_name_length));
-#else
- //Set entry UNICODE name
- entry.set_name(pe_utils::from_ucs2(u16string(
- reinterpret_cast<const unicode16_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
- directory_name_length)));
-#endif
- }
- else
- {
- //Else - set directory ID
- entry.set_id(dir_entry.Id);
- }
-
- //If directory entry has another resource directory
- if(dir_entry.DataIsDirectory)
- {
- entry.add_resource_directory(process_resource_directory(pe, res_rva, dir_entry.OffsetToDirectory, processed));
- }
- else
- {
- //If directory entry has data
- image_resource_data_entry data_entry = pe.section_data_from_rva<image_resource_data_entry>(
- res_rva + dir_entry.OffsetToData, section_data_virtual, true);
-
- //Check byte count that stated by data entry
- if(pe.section_data_length_from_rva(data_entry.OffsetToData, data_entry.OffsetToData, section_data_virtual, true) < data_entry.Size)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //Add data entry to directory entry
- entry.add_data_entry(resource_data_entry(
- std::string(pe.section_data_from_rva(data_entry.OffsetToData, section_data_virtual, true), data_entry.Size),
- data_entry.CodePage));
- }
-
- //Save directory entry
- ret.add_resource_directory_entry(entry);
- }
-
- //Return resource directory
- return ret;
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings)
-{
- needed_size_for_structures += sizeof(image_resource_directory);
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- needed_size_for_structures += sizeof(image_resource_directory_entry);
-
- if((*it).is_named())
- needed_size_for_strings += static_cast<uint32_t>(((*it).get_name().length() + 1) * 2 /* unicode */ + sizeof(uint16_t) /* for string length */);
-
- if(!(*it).includes_data())
- calculate_resource_data_space((*it).get_resource_directory(), aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
- }
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos)
-{
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- if((*it).includes_data())
- {
- uint32_t data_size = static_cast<uint32_t>((*it).get_data_entry().get_data().length()
- + sizeof(image_resource_data_entry)
- + (pe_utils::align_up(current_data_pos, sizeof(uint32_t)) - current_data_pos) /* alignment */);
- needed_size_for_data += data_size;
- current_data_pos += data_size;
- }
- else
- {
- calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
- }
- }
-}
-
-//Helper: sorts resource directory entries
-struct entry_sorter
-{
-public:
- bool operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const;
-};
-
-//Helper function to rebuild resource directory
-void rebuild_resource_directory(pe_base& pe, section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start)
-{
- //Create resource directory
- image_resource_directory dir = {0};
- dir.Characteristics = root.get_characteristics();
- dir.MajorVersion = root.get_major_version();
- dir.MinorVersion = root.get_minor_version();
- dir.TimeDateStamp = root.get_timestamp();
-
- {
- resource_directory::entry_list& entries = root.get_entry_list();
- std::sort(entries.begin(), entries.end(), entry_sorter());
- }
-
- //Calculate number of named and ID entries
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- if((*it).is_named())
- ++dir.NumberOfNamedEntries;
- else
- ++dir.NumberOfIdEntries;
- }
-
- std::string& raw_data = resource_section.get_raw_data();
-
- //Save resource directory
- memcpy(&raw_data[current_structures_pos], &dir, sizeof(dir));
- current_structures_pos += sizeof(dir);
-
- uint32_t this_current_structures_pos = current_structures_pos;
-
- current_structures_pos += sizeof(image_resource_directory_entry) * (dir.NumberOfNamedEntries + dir.NumberOfIdEntries);
-
- //Create all resource directory entries
- for(resource_directory::entry_list::iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- image_resource_directory_entry entry;
- if((*it).is_named())
- {
- entry.Name = 0x80000000 | (current_strings_pos - offset_from_section_start);
- uint16_t unicode_length = static_cast<uint16_t>((*it).get_name().length());
- memcpy(&raw_data[current_strings_pos], &unicode_length, sizeof(unicode_length));
- current_strings_pos += sizeof(unicode_length);
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&raw_data[current_strings_pos], (*it).get_name().c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).get_name()));
- memcpy(&raw_data[current_strings_pos], str.c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
- }
-#endif
-
- current_strings_pos += static_cast<unsigned long>((*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
- }
- else
- {
- entry.Name = (*it).get_id();
- }
-
- if((*it).includes_data())
- {
- current_data_pos = pe_utils::align_up(current_data_pos, sizeof(uint32_t));
- image_resource_data_entry data_entry = {0};
- data_entry.CodePage = (*it).get_data_entry().get_codepage();
- data_entry.Size = static_cast<uint32_t>((*it).get_data_entry().get_data().length());
- data_entry.OffsetToData = pe.rva_from_section_offset(resource_section, current_data_pos + sizeof(data_entry));
-
- entry.OffsetToData = current_data_pos - offset_from_section_start;
-
- memcpy(&raw_data[current_data_pos], &data_entry, sizeof(data_entry));
- current_data_pos += sizeof(data_entry);
-
- memcpy(&raw_data[current_data_pos], (*it).get_data_entry().get_data().data(), data_entry.Size);
- current_data_pos += data_entry.Size;
-
- memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
- this_current_structures_pos += sizeof(entry);
- }
- else
- {
- entry.OffsetToData = 0x80000000 | (current_structures_pos - offset_from_section_start);
-
- memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
- this_current_structures_pos += sizeof(entry);
-
- rebuild_resource_directory(pe, resource_section, (*it).get_resource_directory(), current_structures_pos, current_data_pos, current_strings_pos, offset_from_section_start);
- }
- }
-}
-
-//Helper function to rebuild resource directory
-bool entry_sorter::operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const
-{
- if(entry1.is_named() && entry2.is_named())
- return entry1.get_name() < entry2.get_name();
- else if(!entry1.is_named() && !entry2.is_named())
- return entry1.get_id() < entry2.get_id();
- else
- return entry1.is_named();
-}
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from resources_section raw data start
-//resource_directory is non-constant, because it will be sorted
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that resources_section is attached to this PE image
- if(!pe.section_attached(resources_section))
- throw pe_exception("Resource section must be attached to PE file", pe_exception::section_is_not_attached);
-
- //Check resource directory correctness
- if(info.get_entry_list().empty())
- throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory);
-
- uint32_t aligned_offset_from_section_start = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
- uint32_t needed_size_for_structures = aligned_offset_from_section_start - offset_from_section_start; //Calculate needed size for resource tables and data
- uint32_t needed_size_for_strings = 0;
- uint32_t needed_size_for_data = 0;
-
- calculate_resource_data_space(info, aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
-
- {
- uint32_t current_data_pos = aligned_offset_from_section_start + needed_size_for_structures + needed_size_for_strings;
- calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
- }
-
- uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data;
-
- //Check if resources_section is last one. If it's not, check if there's enough place for resource data
- if(&resources_section != &*(pe.get_image_sections().end() - 1) &&
- (resources_section.empty() || pe_utils::align_up(resources_section.get_size_of_raw_data(), pe.get_file_alignment())
- < needed_size + aligned_offset_from_section_start))
- throw pe_exception("Insufficient space for resource directory", pe_exception::insufficient_space);
-
- std::string& raw_data = resources_section.get_raw_data();
-
- //This will be done only if resources_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + aligned_offset_from_section_start)
- raw_data.resize(needed_size + aligned_offset_from_section_start); //Expand section raw data
-
- uint32_t current_structures_pos = aligned_offset_from_section_start;
- uint32_t current_strings_pos = current_structures_pos + needed_size_for_structures;
- uint32_t current_data_pos = current_strings_pos + needed_size_for_strings;
- rebuild_resource_directory(pe, resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(resources_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(resources_section, aligned_offset_from_section_start), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_resource, ret.get_rva());
- pe.set_directory_size(image_directory_entry_resource, ret.get_size());
- }
-
- return ret;
-}
-
-//Returns resources from PE file
-const resource_directory get_resources(const pe_base& pe)
-{
- resource_directory ret;
-
- if(!pe.has_resources())
- return ret;
-
- //Get resource directory RVA
- uint32_t res_rva = pe.get_directory_rva(image_directory_entry_resource);
-
- //Store already processed directories to avoid resource loops
- std::set<uint32_t> processed;
-
- //Process all directories (recursion)
- ret = process_resource_directory(pe, res_rva, 0, processed);
-
- return ret;
-}
-
-//Finds resource_directory_entry by ID
-resource_directory::id_entry_finder::id_entry_finder(uint32_t id)
- :id_(id)
-{}
-
-bool resource_directory::id_entry_finder::operator()(const resource_directory_entry& entry) const
-{
- return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Finds resource_directory_entry by name
-resource_directory::name_entry_finder::name_entry_finder(const std::wstring& name)
- :name_(name)
-{}
-
-bool resource_directory::name_entry_finder::operator()(const resource_directory_entry& entry) const
-{
- return entry.is_named() && entry.get_name() == name_;
-}
-
-//Finds resource_directory_entry by name or ID (universal)
-resource_directory::entry_finder::entry_finder(const std::wstring& name)
- :name_(name), named_(true)
-{}
-
-resource_directory::entry_finder::entry_finder(uint32_t id)
- :id_(id), named_(false)
-{}
-
-bool resource_directory::entry_finder::operator()(const resource_directory_entry& entry) const
-{
- if(named_)
- return entry.is_named() && entry.get_name() == name_;
- else
- return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Returns resource_directory_entry by ID. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_id(uint32_t id) const
-{
- entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), id_entry_finder(id));
- if(i == entries_.end())
- throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
- return *i;
-}
-
-//Returns resource_directory_entry by name. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_name(const std::wstring& name) const
-{
- entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), name_entry_finder(name));
- if(i == entries_.end())
- throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
- return *i;
-}
-}
diff --git a/tools/pe_bliss/pe_resources.h b/tools/pe_bliss/pe_resources.h
deleted file mode 100644
index 1eb6437563..0000000000
--- a/tools/pe_bliss/pe_resources.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include <set>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing resource data entry
-class resource_data_entry
-{
-public:
- //Default constructor
- resource_data_entry();
- //Constructor from data
- resource_data_entry(const std::string& data, uint32_t codepage);
-
- //Returns resource data codepage
- uint32_t get_codepage() const;
- //Returns resource data
- const std::string& get_data() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Sets resource data codepage
- void set_codepage(uint32_t codepage);
- //Sets resource data
- void set_data(const std::string& data);
-
-private:
- uint32_t codepage_; //Resource data codepage
- std::string data_; //Resource data
-};
-
-//Forward declaration
-class resource_directory;
-
-//Class representing resource directory entry
-class resource_directory_entry
-{
-public:
- //Default constructor
- resource_directory_entry();
- //Copy constructor
- resource_directory_entry(const resource_directory_entry& other);
- //Copy assignment operator
- resource_directory_entry& operator=(const resource_directory_entry& other);
-
- //Returns entry ID
- uint32_t get_id() const;
- //Returns entry name
- const std::wstring& get_name() const;
- //Returns true, if entry has name
- //Returns false, if entry has ID
- bool is_named() const;
-
- //Returns true, if entry includes resource_data_entry
- //Returns false, if entry includes resource_directory
- bool includes_data() const;
- //Returns resource_directory if entry includes it, otherwise throws an exception
- const resource_directory& get_resource_directory() const;
- //Returns resource_data_entry if entry includes it, otherwise throws an exception
- const resource_data_entry& get_data_entry() const;
-
- //Destructor
- ~resource_directory_entry();
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Sets entry name
- void set_name(const std::wstring& name);
- //Sets entry ID
- void set_id(uint32_t id);
-
- //Returns resource_directory if entry includes it, otherwise throws an exception
- resource_directory& get_resource_directory();
- //Returns resource_data_entry if entry includes it, otherwise throws an exception
- resource_data_entry& get_data_entry();
-
- //Adds resource_data_entry
- void add_data_entry(const resource_data_entry& entry);
- //Adds resource_directory
- void add_resource_directory(const resource_directory& dir);
-
-private:
- //Destroys included data
- void release();
-
-private:
- uint32_t id_;
- std::wstring name_;
-
- union includes
- {
- //Default constructor
- includes();
-
- //We use pointers, we're doing manual copying here
- class resource_data_entry* data_;
- class resource_directory* dir_; //We use pointer, because structs include each other
- };
-
- includes ptr_;
-
- bool includes_data_, named_;
-};
-
-//Class representing resource directory
-class resource_directory
-{
-public:
- typedef std::vector<resource_directory_entry> entry_list;
-
-public:
- //Default constructor
- resource_directory();
- //Constructor from data
- explicit resource_directory(const pe_win::image_resource_directory& dir);
-
- //Returns characteristics of directory
- uint32_t get_characteristics() const;
- //Returns date and time stamp of directory
- uint32_t get_timestamp() const;
- //Returns number of named entries
- uint32_t get_number_of_named_entries() const;
- //Returns number of ID entries
- uint32_t get_number_of_id_entries() const;
- //Returns major version of directory
- uint16_t get_major_version() const;
- //Returns minor version of directory
- uint16_t get_minor_version() const;
- //Returns resource_directory_entry array
- const entry_list& get_entry_list() const;
- //Returns resource_directory_entry by ID. If not found - throws an exception
- const resource_directory_entry& entry_by_id(uint32_t id) const;
- //Returns resource_directory_entry by name. If not found - throws an exception
- const resource_directory_entry& entry_by_name(const std::wstring& name) const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Adds resource_directory_entry
- void add_resource_directory_entry(const resource_directory_entry& entry);
- //Clears resource_directory_entry array
- void clear_resource_directory_entry_list();
-
- //Sets characteristics of directory
- void set_characteristics(uint32_t characteristics);
- //Sets date and time stamp of directory
- void set_timestamp(uint32_t timestamp);
- //Sets number of named entries
- void set_number_of_named_entries(uint32_t number);
- //Sets number of ID entries
- void set_number_of_id_entries(uint32_t number);
- //Sets major version of directory
- void set_major_version(uint16_t major_version);
- //Sets minor version of directory
- void get_minor_version(uint16_t minor_version);
-
- //Returns resource_directory_entry array
- entry_list& get_entry_list();
-
-private:
- uint32_t characteristics_;
- uint32_t timestamp_;
- uint16_t major_version_, minor_version_;
- uint32_t number_of_named_entries_, number_of_id_entries_;
- entry_list entries_;
-
-public: //Finder helpers
- //Finds resource_directory_entry by ID
- struct id_entry_finder
- {
- public:
- explicit id_entry_finder(uint32_t id);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- uint32_t id_;
- };
-
- //Finds resource_directory_entry by name
- struct name_entry_finder
- {
- public:
- explicit name_entry_finder(const std::wstring& name);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- std::wstring name_;
- };
-
- //Finds resource_directory_entry by name or ID (universal)
- struct entry_finder
- {
- public:
- explicit entry_finder(const std::wstring& name);
- explicit entry_finder(uint32_t id);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- std::wstring name_;
- uint32_t id_;
- bool named_;
- };
-};
-
-//Returns resources (root resource_directory) from PE file
-const resource_directory get_resources(const pe_base& pe);
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//resource_directory is non-constant, because it will be sorted
-//offset_from_section_start - offset from resources_section raw data start
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_rich_data.cpp b/tools/pe_bliss/pe_rich_data.cpp
deleted file mode 100644
index e92f7ddc1b..0000000000
--- a/tools/pe_bliss/pe_rich_data.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "pe_rich_data.h"
-
-namespace pe_bliss
-{
-//STUB OVERLAY
-//Default constructor
-rich_data::rich_data()
- :number_(0), version_(0), times_(0)
-{}
-
-//Who knows, what these fields mean...
-uint32_t rich_data::get_number() const
-{
- return number_;
-}
-
-uint32_t rich_data::get_version() const
-{
- return version_;
-}
-
-uint32_t rich_data::get_times() const
-{
- return times_;
-}
-
-void rich_data::set_number(uint32_t number)
-{
- number_ = number;
-}
-
-void rich_data::set_version(uint32_t version)
-{
- version_ = version;
-}
-
-void rich_data::set_times(uint32_t times)
-{
- times_ = times;
-}
-
-//Returns MSVC rich data
-const rich_data_list get_rich_data(const pe_base& pe)
-{
- //Returned value
- rich_data_list ret;
-
- const std::string& rich_overlay = pe.get_stub_overlay();
-
- //If there's no rich overlay, return empty vector
- if(rich_overlay.size() < sizeof(uint32_t))
- return ret;
-
- //True if rich data was found
- bool found = false;
-
- //Rich overlay ID ("Rich" word)
- static const uint32_t rich_overlay_id = 0x68636952;
-
- //Search for rich data overlay ID
- const char* begin = &rich_overlay[0];
- const char* end = begin + rich_overlay.length();
- for(; begin != end; ++begin)
- {
- if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
- {
- found = true; //We've found it!
- break;
- }
- }
-
- //If we found it
- if(found)
- {
- //Check remaining length
- if(static_cast<size_t>(end - begin) < sizeof(uint32_t))
- return ret;
-
- //The XOR key is after "Rich" word, we should get it
- uint32_t xorkey = *reinterpret_cast<const uint32_t*>(begin + sizeof(uint32_t));
-
- //True if rich data was found
- found = false;
-
- //Second search for signature "DanS"
- begin = &rich_overlay[0];
- for(; begin != end; ++begin)
- {
- if((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) == 0x536e6144) //"DanS"
- {
- found = true;
- break;
- }
- }
-
- //If second signature is found
- if(found)
- {
- begin += sizeof(uint32_t) * 3;
- //List all rich data structures
- while(begin < end)
- {
- begin += sizeof(uint32_t);
- if(begin >= end)
- break;
-
- //Check for rich overlay data end ("Rich" word reached)
- if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
- break;
-
- //Create rich_data structure
- rich_data data;
- data.set_number((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) >> 16);
- data.set_version((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) & 0xFFFF);
-
- begin += sizeof(uint32_t);
- if(begin >= end)
- break;
-
- data.set_times(*reinterpret_cast<const uint32_t*>(begin) ^ xorkey);
-
- //Save rich data structure
- ret.push_back(data);
- }
- }
- }
-
- //Return rich data structures list
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_rich_data.h b/tools/pe_bliss/pe_rich_data.h
deleted file mode 100644
index 3e01d3c011..0000000000
--- a/tools/pe_bliss/pe_rich_data.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Rich data overlay class of Microsoft Visual Studio
-class rich_data
-{
-public:
- //Default constructor
- rich_data();
-
-public: //Getters
- //Who knows, what these fields mean...
- uint32_t get_number() const;
- uint32_t get_version() const;
- uint32_t get_times() const;
-
-public: //Setters, used by PE library only
- void set_number(uint32_t number);
- void set_version(uint32_t version);
- void set_times(uint32_t times);
-
-private:
- uint32_t number_;
- uint32_t version_;
- uint32_t times_;
-};
-
-//Rich data list typedef
-typedef std::vector<rich_data> rich_data_list;
-
-//Returns a vector with rich data (stub overlay)
-const rich_data_list get_rich_data(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_section.cpp b/tools/pe_bliss/pe_section.cpp
deleted file mode 100644
index 72127e22e2..0000000000
--- a/tools/pe_bliss/pe_section.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "utils.h"
-#include "pe_section.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Section structure default constructor
-section::section()
- :old_size_(static_cast<size_t>(-1))
-{
- memset(&header_, 0, sizeof(image_section_header));
-}
-
-//Sets the name of section (8 characters maximum)
-void section::set_name(const std::string& name)
-{
- memset(header_.Name, 0, sizeof(header_.Name));
- memcpy(header_.Name, name.c_str(), std::min<size_t>(name.length(), sizeof(header_.Name)));
-}
-
-//Returns section name
-const std::string section::get_name() const
-{
- char buf[9] = {0};
- memcpy(buf, header_.Name, 8);
- return std::string(buf);
-}
-
-//Set flag (attribute) of section
-section& section::set_flag(uint32_t flag, bool setflag)
-{
- if(setflag)
- header_.Characteristics |= flag;
- else
- header_.Characteristics &= ~flag;
-
- return *this;
-}
-
-//Sets "readable" attribute of section
-section& section::readable(bool readable)
-{
- return set_flag(image_scn_mem_read, readable);
-}
-
-//Sets "writeable" attribute of section
-section& section::writeable(bool writeable)
-{
- return set_flag(image_scn_mem_write, writeable);
-}
-
-//Sets "executable" attribute of section
-section& section::executable(bool executable)
-{
- return set_flag(image_scn_mem_execute, executable);
-}
-
-//Sets "shared" attribute of section
-section& section::shared(bool shared)
-{
- return set_flag(image_scn_mem_shared, shared);
-}
-
-//Sets "discardable" attribute of section
-section& section::discardable(bool discardable)
-{
- return set_flag(image_scn_mem_discardable, discardable);
-}
-
-//Returns true if section is readable
-bool section::readable() const
-{
- return (header_.Characteristics & image_scn_mem_read) != 0;
-}
-
-//Returns true if section is writeable
-bool section::writeable() const
-{
- return (header_.Characteristics & image_scn_mem_write) != 0;
-}
-
-//Returns true if section is executable
-bool section::executable() const
-{
- return (header_.Characteristics & image_scn_mem_execute) != 0;
-}
-
-bool section::shared() const
-{
- return (header_.Characteristics & image_scn_mem_shared) != 0;
-}
-
-bool section::discardable() const
-{
- return (header_.Characteristics & image_scn_mem_discardable) != 0;
-}
-
-//Returns true if section has no RAW data
-bool section::empty() const
-{
- if(old_size_ != static_cast<size_t>(-1)) //If virtual memory is mapped, check raw data length (old_size_)
- return old_size_ == 0;
- else
- return raw_data_.empty();
-}
-
-//Returns raw section data from file image
-std::string& section::get_raw_data()
-{
- unmap_virtual();
- return raw_data_;
-}
-
-//Sets raw section data from file image
-void section::set_raw_data(const std::string& data)
-{
- old_size_ = static_cast<size_t>(-1);
- raw_data_ = data;
-}
-
-//Returns raw section data from file image
-const std::string& section::get_raw_data() const
-{
- unmap_virtual();
- return raw_data_;
-}
-
-//Returns mapped virtual section data
-const std::string& section::get_virtual_data(uint32_t section_alignment) const
-{
- map_virtual(section_alignment);
- return raw_data_;
-}
-
-//Returns mapped virtual section data
-std::string& section::get_virtual_data(uint32_t section_alignment)
-{
- map_virtual(section_alignment);
- return raw_data_;
-}
-
-//Maps virtual section data
-void section::map_virtual(uint32_t section_alignment) const
-{
- uint32_t aligned_virtual_size = get_aligned_virtual_size(section_alignment);
- if(old_size_ == static_cast<size_t>(-1) && aligned_virtual_size && aligned_virtual_size > raw_data_.length())
- {
- old_size_ = raw_data_.length();
- raw_data_.resize(aligned_virtual_size, 0);
- }
-}
-
-//Unmaps virtual section data
-void section::unmap_virtual() const
-{
- if(old_size_ != static_cast<size_t>(-1))
- {
- raw_data_.resize(old_size_, 0);
- old_size_ = static_cast<size_t>(-1);
- }
-}
-
-//Returns section virtual size
-uint32_t section::get_virtual_size() const
-{
- return header_.Misc.VirtualSize;
-}
-
-//Returns section virtual address
-uint32_t section::get_virtual_address() const
-{
- return header_.VirtualAddress;
-}
-
-//Returns size of section raw data
-uint32_t section::get_size_of_raw_data() const
-{
- return header_.SizeOfRawData;
-}
-
-//Returns pointer to raw section data in PE file
-uint32_t section::get_pointer_to_raw_data() const
-{
- return header_.PointerToRawData;
-}
-
-//Returns section characteristics
-uint32_t section::get_characteristics() const
-{
- return header_.Characteristics;
-}
-
-//Returns raw image section header
-const pe_win::image_section_header& section::get_raw_header() const
-{
- return header_;
-}
-
-//Returns raw image section header
-pe_win::image_section_header& section::get_raw_header()
-{
- return header_;
-}
-
-//Calculates aligned virtual section size
-uint32_t section::get_aligned_virtual_size(uint32_t section_alignment) const
-{
- if(get_size_of_raw_data())
- {
- if(!get_virtual_size())
- {
- //If section virtual size is zero
- //Set aligned virtual size of section as aligned raw size
- return pe_utils::align_up(get_size_of_raw_data(), section_alignment);
- }
- }
-
- return pe_utils::align_up(get_virtual_size(), section_alignment);
-}
-
-//Calculates aligned raw section size
-uint32_t section::get_aligned_raw_size(uint32_t file_alignment) const
-{
- if(get_size_of_raw_data())
- return pe_utils::align_up(get_size_of_raw_data(), file_alignment);
- else
- return 0;
-}
-
-//Sets size of raw section data
-void section::set_size_of_raw_data(uint32_t size_of_raw_data)
-{
- header_.SizeOfRawData = size_of_raw_data;
-}
-
-//Sets pointer to section raw data
-void section::set_pointer_to_raw_data(uint32_t pointer_to_raw_data)
-{
- header_.PointerToRawData = pointer_to_raw_data;
-}
-
-//Sets section characteristics
-void section::set_characteristics(uint32_t characteristics)
-{
- header_.Characteristics = characteristics;
-}
-
-//Sets section virtual size
-void section::set_virtual_size(uint32_t virtual_size)
-{
- header_.Misc.VirtualSize = virtual_size;
-}
-
-//Sets section virtual address
-void section::set_virtual_address(uint32_t virtual_address)
-{
- header_.VirtualAddress = virtual_address;
-}
-
-//Section by file offset finder helper (4gb max)
-section_by_raw_offset::section_by_raw_offset(uint32_t offset)
- :offset_(offset)
-{}
-
-bool section_by_raw_offset::operator()(const section& s) const
-{
- return (s.get_pointer_to_raw_data() <= offset_)
- && (s.get_pointer_to_raw_data() + s.get_size_of_raw_data() > offset_);
-}
-
-section_ptr_finder::section_ptr_finder(const section& s)
- :s_(s)
-{}
-
-bool section_ptr_finder::operator()(const section& s) const
-{
- return &s == &s_;
-}
-}
diff --git a/tools/pe_bliss/pe_section.h b/tools/pe_bliss/pe_section.h
deleted file mode 100644
index 617ecebe26..0000000000
--- a/tools/pe_bliss/pe_section.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Enumeration of section data types, used in functions below
-enum section_data_type
-{
- section_data_raw,
- section_data_virtual
-};
-
-//Class representing image section
-class section
-{
-public:
- //Default constructor
- section();
-
- //Sets the name of section (stripped to 8 characters)
- void set_name(const std::string& name);
-
- //Returns the name of section
- const std::string get_name() const;
-
- //Changes attributes of section
- section& readable(bool readable);
- section& writeable(bool writeable);
- section& executable(bool executable);
- section& shared(bool shared);
- section& discardable(bool discardable);
-
- //Returns attributes of section
- bool readable() const;
- bool writeable() const;
- bool executable() const;
- bool shared() const;
- bool discardable() const;
-
- //Returns true if section has no RAW data
- bool empty() const;
-
- //Returns raw section data from file image
- std::string& get_raw_data();
- //Returns raw section data from file image
- const std::string& get_raw_data() const;
- //Returns mapped virtual section data
- const std::string& get_virtual_data(uint32_t section_alignment) const;
- //Returns mapped virtual section data
- std::string& get_virtual_data(uint32_t section_alignment);
-
-public: //Header getters
- //Returns section virtual size
- uint32_t get_virtual_size() const;
- //Returns section virtual address (RVA)
- uint32_t get_virtual_address() const;
- //Returns size of section raw data
- uint32_t get_size_of_raw_data() const;
- //Returns pointer to raw section data in PE file
- uint32_t get_pointer_to_raw_data() const;
- //Returns section characteristics
- uint32_t get_characteristics() const;
-
- //Returns raw image section header
- const pe_win::image_section_header& get_raw_header() const;
-
-public: //Aligned sizes calculation
- //Calculates aligned virtual section size
- uint32_t get_aligned_virtual_size(uint32_t section_alignment) const;
- //Calculates aligned raw section size
- uint32_t get_aligned_raw_size(uint32_t file_alignment) const;
-
-public: //Setters
- //Sets size of raw section data
- void set_size_of_raw_data(uint32_t size_of_raw_data);
- //Sets pointer to section raw data
- void set_pointer_to_raw_data(uint32_t pointer_to_raw_data);
- //Sets section characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets raw section data from file image
- void set_raw_data(const std::string& data);
-
-public: //Setters, be careful
- //Sets section virtual size (doesn't set internal aligned virtual size, changes only header value)
- //Better use pe_base::set_section_virtual_size
- void set_virtual_size(uint32_t virtual_size);
- //Sets section virtual address
- void set_virtual_address(uint32_t virtual_address);
- //Returns raw image section header
- pe_win::image_section_header& get_raw_header();
-
-private:
- //Section header
- pe_win::image_section_header header_;
-
- //Maps virtual section data
- void map_virtual(uint32_t section_alignment) const;
-
- //Unmaps virtual section data
- void unmap_virtual() const;
-
- //Set flag (attribute) of section
- section& set_flag(uint32_t flag, bool setflag);
-
- //Old size of section (stored after mapping of virtual section memory)
- mutable std::size_t old_size_;
-
- //Section raw/virtual data
- mutable std::string raw_data_;
-};
-
-//Section by file offset finder helper (4gb max)
-struct section_by_raw_offset
-{
-public:
- explicit section_by_raw_offset(uint32_t offset);
- bool operator()(const section& s) const;
-
-private:
- uint32_t offset_;
-};
-
-//Helper: finder of section* in sections list
-struct section_ptr_finder
-{
-public:
- explicit section_ptr_finder(const section& s);
- bool operator()(const section& s) const;
-
-private:
- const section& s_;
-};
-
-typedef std::vector<section> section_list;
-}
diff --git a/tools/pe_bliss/pe_structures.h b/tools/pe_bliss/pe_structures.h
deleted file mode 100644
index efc99103b2..0000000000
--- a/tools/pe_bliss/pe_structures.h
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <sstream>
-#include "stdint_defs.h"
-#if defined(_MSC_VER) or defined(__MINGW32__)
-#define PE_BLISS_WINDOWS
-#endif
-
-namespace pe_bliss
-{
-//Enumeration of PE types
-enum pe_type
-{
- pe_type_32,
- pe_type_64
-};
-
-namespace pe_win
-{
-const uint32_t image_numberof_directory_entries = 16;
-const uint32_t image_nt_optional_hdr32_magic = 0x10b;
-const uint32_t image_nt_optional_hdr64_magic = 0x20b;
-const uint32_t image_resource_name_is_string = 0x80000000;
-const uint32_t image_resource_data_is_directory = 0x80000000;
-
-const uint32_t image_dllcharacteristics_dynamic_base = 0x0040; // DLL can move.
-const uint32_t image_dllcharacteristics_force_integrity = 0x0080; // Code Integrity Image
-const uint32_t image_dllcharacteristics_nx_compat = 0x0100; // Image is NX compatible
-const uint32_t image_dllcharacteristics_no_isolation = 0x0200; // Image understands isolation and doesn't want it
-const uint32_t image_dllcharacteristics_no_seh = 0x0400; // Image does not use SEH. No SE handler may reside in this image
-const uint32_t image_dllcharacteristics_no_bind = 0x0800; // Do not bind this image.
-const uint32_t image_dllcharacteristics_wdm_driver = 0x2000; // Driver uses WDM model
-const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000;
-
-const uint32_t image_sizeof_file_header = 20;
-
-const uint32_t image_file_relocs_stripped = 0x0001; // Relocation info stripped from file.
-const uint32_t image_file_executable_image = 0x0002; // File is executable (i.e. no unresolved externel references).
-const uint32_t image_file_line_nums_stripped = 0x0004; // Line nunbers stripped from file.
-const uint32_t image_file_local_syms_stripped = 0x0008; // Local symbols stripped from file.
-const uint32_t image_file_aggresive_ws_trim = 0x0010; // Agressively trim working set
-const uint32_t image_file_large_address_aware = 0x0020; // App can handle >2gb addresses
-const uint32_t image_file_bytes_reversed_lo = 0x0080; // Bytes of machine word are reversed.
-const uint32_t image_file_32bit_machine = 0x0100; // 32 bit word machine.
-const uint32_t image_file_debug_stripped = 0x0200; // Debugging info stripped from file in .DBG file
-const uint32_t image_file_removable_run_from_swap = 0x0400; // If Image is on removable media, copy and run from the swap file.
-const uint32_t image_file_net_run_from_swap = 0x0800; // If Image is on Net, copy and run from the swap file.
-const uint32_t image_file_system = 0x1000; // System File.
-const uint32_t image_file_dll = 0x2000; // File is a DLL.
-const uint32_t image_file_up_system_only = 0x4000; // File should only be run on a UP machine
-const uint32_t image_file_bytes_reversed_hi = 0x8000; // Bytes of machine word are reversed.
-
-const uint32_t image_scn_lnk_nreloc_ovfl = 0x01000000; // Section contains extended relocations.
-const uint32_t image_scn_mem_discardable = 0x02000000; // Section can be discarded.
-const uint32_t image_scn_mem_not_cached = 0x04000000; // Section is not cachable.
-const uint32_t image_scn_mem_not_paged = 0x08000000; // Section is not pageable.
-const uint32_t image_scn_mem_shared = 0x10000000; // Section is shareable.
-const uint32_t image_scn_mem_execute = 0x20000000; // Section is executable.
-const uint32_t image_scn_mem_read = 0x40000000; // Section is readable.
-const uint32_t image_scn_mem_write = 0x80000000; // Section is writeable.
-
-const uint32_t image_scn_cnt_code = 0x00000020; // Section contains code.
-const uint32_t image_scn_cnt_initialized_data = 0x00000040; // Section contains initialized data.
-const uint32_t image_scn_cnt_uninitialized_data = 0x00000080; // Section contains uninitialized data.
-
-//Directory Entries
-const uint32_t image_directory_entry_export = 0; // Export Directory
-const uint32_t image_directory_entry_import = 1; // Import Directory
-const uint32_t image_directory_entry_resource = 2; // Resource Directory
-const uint32_t image_directory_entry_exception = 3; // Exception Directory
-const uint32_t image_directory_entry_security = 4; // Security Directory
-const uint32_t image_directory_entry_basereloc = 5; // Base Relocation Table
-const uint32_t image_directory_entry_debug = 6; // Debug Directory
-const uint32_t image_directory_entry_architecture = 7; // Architecture Specific Data
-const uint32_t image_directory_entry_globalptr = 8; // RVA of GP
-const uint32_t image_directory_entry_tls = 9; // TLS Directory
-const uint32_t image_directory_entry_load_config = 10; // Load Configuration Directory
-const uint32_t image_directory_entry_bound_import = 11; // Bound Import Directory in headers
-const uint32_t image_directory_entry_iat = 12; // Import Address Table
-const uint32_t image_directory_entry_delay_import = 13; // Delay Load Import Descriptors
-const uint32_t image_directory_entry_com_descriptor = 14; // COM Runtime descriptor
-
-//Subsystem Values
-const uint32_t image_subsystem_unknown = 0; // Unknown subsystem.
-const uint32_t image_subsystem_native = 1; // Image doesn't require a subsystem.
-const uint32_t image_subsystem_windows_gui = 2; // Image runs in the Windows GUI subsystem.
-const uint32_t image_subsystem_windows_cui = 3; // Image runs in the Windows character subsystem.
-const uint32_t image_subsystem_os2_cui = 5; // image runs in the OS/2 character subsystem.
-const uint32_t image_subsystem_posix_cui = 7; // image runs in the Posix character subsystem.
-const uint32_t image_subsystem_native_windows = 8; // image is a native Win9x driver.
-const uint32_t image_subsystem_windows_ce_gui = 9; // Image runs in the Windows CE subsystem.
-const uint32_t image_subsystem_efi_application = 10; //
-const uint32_t image_subsystem_efi_boot_service_driver = 11; //
-const uint32_t image_subsystem_efi_runtime_driver = 12; //
-const uint32_t image_subsystem_efi_rom = 13;
-const uint32_t image_subsystem_xbox = 14;
-const uint32_t image_subsystem_windows_boot_application = 16;
-
-//Imports
-const uint64_t image_ordinal_flag64 = 0x8000000000000000ull;
-const uint32_t image_ordinal_flag32 = 0x80000000;
-
-//Based relocation types
-const uint32_t image_rel_based_absolute = 0;
-const uint32_t image_rel_based_high = 1;
-const uint32_t image_rel_based_low = 2;
-const uint32_t image_rel_based_highlow = 3;
-const uint32_t image_rel_based_highadj = 4;
-const uint32_t image_rel_based_mips_jmpaddr = 5;
-const uint32_t image_rel_based_mips_jmpaddr16 = 9;
-const uint32_t image_rel_based_ia64_imm64 = 9;
-const uint32_t image_rel_based_dir64 = 10;
-
-//Exception directory
-//The function has an exception handler that should be called when looking for functions that need to examine exceptions
-const uint32_t unw_flag_ehandler = 0x01;
-//The function has a termination handler that should be called when unwinding an exception
-const uint32_t unw_flag_uhandler = 0x02;
-//This unwind info structure is not the primary one for the procedure.
-//Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry.
-//If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared.
-//Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info
-const uint32_t unw_flag_chaininfo = 0x04;
-
-//Debug
-const uint32_t image_debug_misc_exename = 1;
-const uint32_t image_debug_type_unknown = 0;
-const uint32_t image_debug_type_coff = 1;
-const uint32_t image_debug_type_codeview = 2;
-const uint32_t image_debug_type_fpo = 3;
-const uint32_t image_debug_type_misc = 4;
-const uint32_t image_debug_type_exception = 5;
-const uint32_t image_debug_type_fixup = 6;
-const uint32_t image_debug_type_omap_to_src = 7;
-const uint32_t image_debug_type_omap_from_src = 8;
-const uint32_t image_debug_type_borland = 9;
-const uint32_t image_debug_type_reserved10 = 10;
-const uint32_t image_debug_type_clsid = 11;
-
-
-//Storage classes
-const uint32_t image_sym_class_end_of_function = static_cast<uint8_t>(-1);
-const uint32_t image_sym_class_null = 0x0000;
-const uint32_t image_sym_class_automatic = 0x0001;
-const uint32_t image_sym_class_external = 0x0002;
-const uint32_t image_sym_class_static = 0x0003;
-const uint32_t image_sym_class_register = 0x0004;
-const uint32_t image_sym_class_external_def = 0x0005;
-const uint32_t image_sym_class_label = 0x0006;
-const uint32_t image_sym_class_undefined_label = 0x0007;
-const uint32_t image_sym_class_member_of_struct = 0x0008;
-const uint32_t image_sym_class_argument = 0x0009;
-const uint32_t image_sym_class_struct_tag = 0x000a;
-const uint32_t image_sym_class_member_of_union = 0x000b;
-const uint32_t image_sym_class_union_tag = 0x000c;
-const uint32_t image_sym_class_type_definition = 0x000d;
-const uint32_t image_sym_class_undefined_static = 0x000e;
-const uint32_t image_sym_class_enum_tag = 0x000f;
-const uint32_t image_sym_class_member_of_enum = 0x0010;
-const uint32_t image_sym_class_register_param = 0x0011;
-const uint32_t image_sym_class_bit_field = 0x0012;
-
-const uint32_t image_sym_class_far_external = 0x0044;
-
-const uint32_t image_sym_class_block = 0x0064;
-const uint32_t image_sym_class_function = 0x0065;
-const uint32_t image_sym_class_end_of_struct = 0x0066;
-const uint32_t image_sym_class_file = 0x0067;
-
-const uint32_t image_sym_class_section = 0x0068;
-const uint32_t image_sym_class_weak_external = 0x0069;
-
-const uint32_t image_sym_class_clr_token = 0x006b;
-
-//type packing constants
-const uint32_t n_btmask = 0x000f;
-const uint32_t n_tmask = 0x0030;
-const uint32_t n_tmask1 = 0x00c0;
-const uint32_t n_tmask2 = 0x00f0;
-const uint32_t n_btshft = 4;
-const uint32_t n_tshift = 2;
-
-//Type (derived) values.
-const uint32_t image_sym_dtype_null = 0; // no derived type.
-const uint32_t image_sym_dtype_pointer = 1; // pointer.
-const uint32_t image_sym_dtype_function = 2; // function.
-const uint32_t image_sym_dtype_array = 3; // array.
-
-// Is x a function?
-//TODO
-#ifndef ISFCN
-#define ISFCN(x) (((x) & n_tmask) == (image_sym_dtype_function << n_btshft))
-#endif
-
-//Version info
-const uint32_t vs_ffi_fileflagsmask = 0x0000003FL;
-
-const uint32_t vs_ffi_signature = 0xFEEF04BDL;
-const uint32_t vs_ffi_strucversion = 0x00010000L;
-
-/* ----- VS_VERSION.dwFileFlags ----- */
-const uint32_t vs_ff_debug = 0x00000001L;
-const uint32_t vs_ff_prerelease = 0x00000002L;
-const uint32_t vs_ff_patched = 0x00000004L;
-const uint32_t vs_ff_privatebuild = 0x00000008L;
-const uint32_t vs_ff_infoinferred = 0x00000010L;
-const uint32_t vs_ff_specialbuild = 0x00000020L;
-
-/* ----- VS_VERSION.dwFileOS ----- */
-const uint32_t vos_unknown = 0x00000000L;
-const uint32_t vos_dos = 0x00010000L;
-const uint32_t vos_os216 = 0x00020000L;
-const uint32_t vos_os232 = 0x00030000L;
-const uint32_t vos_nt = 0x00040000L;
-const uint32_t vos_wince = 0x00050000L;
-
-const uint32_t vos__base = 0x00000000L;
-const uint32_t vos__windows16 = 0x00000001L;
-const uint32_t vos__pm16 = 0x00000002L;
-const uint32_t vos__pm32 = 0x00000003L;
-const uint32_t vos__windows32 = 0x00000004L;
-
-const uint32_t vos_dos_windows16 = 0x00010001L;
-const uint32_t vos_dos_windows32 = 0x00010004L;
-const uint32_t vos_os216_pm16 = 0x00020002L;
-const uint32_t vos_os232_pm32 = 0x00030003L;
-const uint32_t vos_nt_windows32 = 0x00040004L;
-
-/* ----- VS_VERSION.dwFileType ----- */
-const uint32_t vft_unknown = 0x00000000L;
-const uint32_t vft_app = 0x00000001L;
-const uint32_t vft_dll = 0x00000002L;
-const uint32_t vft_drv = 0x00000003L;
-const uint32_t vft_font = 0x00000004L;
-const uint32_t vft_vxd = 0x00000005L;
-const uint32_t vft_static_lib = 0x00000007L;
-
-const uint32_t message_resource_unicode = 0x0001;
-
-#pragma pack(push, 1)
-
-//Windows GUID structure
-struct guid
-{
- uint32_t Data1;
- uint16_t Data2;
- uint16_t Data3;
- uint8_t Data4[8];
-};
-
-//DOS .EXE header
-struct image_dos_header
-{
- uint16_t e_magic; // Magic number
- uint16_t e_cblp; // Bytes on last page of file
- uint16_t e_cp; // Pages in file
- uint16_t e_crlc; // Relocations
- uint16_t e_cparhdr; // Size of header in paragraphs
- uint16_t e_minalloc; // Minimum extra paragraphs needed
- uint16_t e_maxalloc; // Maximum extra paragraphs needed
- uint16_t e_ss; // Initial (relative) SS value
- uint16_t e_sp; // Initial SP value
- uint16_t e_csum; // Checksum
- uint16_t e_ip; // Initial IP value
- uint16_t e_cs; // Initial (relative) CS value
- uint16_t e_lfarlc; // File address of relocation table
- uint16_t e_ovno; // Overlay number
- uint16_t e_res[4]; // Reserved words
- uint16_t e_oemid; // OEM identifier (for e_oeminfo)
- uint16_t e_oeminfo; // OEM information; e_oemid specific
- uint16_t e_res2[10]; // Reserved words
- int32_t e_lfanew; // File address of new exe header
-};
-
-//Directory format
-struct image_data_directory
-{
- uint32_t VirtualAddress;
- uint32_t Size;
-};
-
-//Optional header format
-struct image_optional_header32
-{
- //Standard fields
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint32_t BaseOfData;
-
- //NT additional fields
- uint32_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Win32VersionValue;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- uint16_t DllCharacteristics;
- uint32_t SizeOfStackReserve;
- uint32_t SizeOfStackCommit;
- uint32_t SizeOfHeapReserve;
- uint32_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- uint32_t NumberOfRvaAndSizes;
- image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_optional_header64
-{
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint64_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Win32VersionValue;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- uint16_t DllCharacteristics;
- uint64_t SizeOfStackReserve;
- uint64_t SizeOfStackCommit;
- uint64_t SizeOfHeapReserve;
- uint64_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- uint32_t NumberOfRvaAndSizes;
- image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_file_header
-{
- uint16_t Machine;
- uint16_t NumberOfSections;
- uint32_t TimeDateStamp;
- uint32_t PointerToSymbolTable;
- uint32_t NumberOfSymbols;
- uint16_t SizeOfOptionalHeader;
- uint16_t Characteristics;
-};
-
-struct image_nt_headers64
-{
- uint32_t Signature;
- image_file_header FileHeader;
- image_optional_header64 OptionalHeader;
-};
-
-struct image_nt_headers32
-{
- uint32_t Signature;
- image_file_header FileHeader;
- image_optional_header32 OptionalHeader;
-};
-
-//Section header format
-struct image_section_header
-{
- uint8_t Name[8];
- union
- {
- uint32_t PhysicalAddress;
- uint32_t VirtualSize;
- } Misc;
-
- uint32_t VirtualAddress;
- uint32_t SizeOfRawData;
- uint32_t PointerToRawData;
- uint32_t PointerToRelocations;
- uint32_t PointerToLinenumbers;
- uint16_t NumberOfRelocations;
- uint16_t NumberOfLinenumbers;
- uint32_t Characteristics;
-};
-
-
-/// RESOURCES ///
-struct image_resource_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint16_t NumberOfNamedEntries;
- uint16_t NumberOfIdEntries;
- // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
-};
-
-struct vs_fixedfileinfo
-{
- uint32_t dwSignature; /* e.g. 0xfeef04bd */
- uint32_t dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
- uint32_t dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
- uint32_t dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
- uint32_t dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
- uint32_t dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
- uint32_t dwFileFlagsMask; /* = 0x3F for version "0.42" */
- uint32_t dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
- uint32_t dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
- uint32_t dwFileType; /* e.g. VFT_DRIVER */
- uint32_t dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
- uint32_t dwFileDateMS; /* e.g. 0 */
- uint32_t dwFileDateLS; /* e.g. 0 */
-};
-
-struct bitmapinfoheader
-{
- uint32_t biSize;
- int32_t biWidth;
- int32_t biHeight;
- uint16_t biPlanes;
- uint16_t biBitCount;
- uint32_t biCompression;
- uint32_t biSizeImage;
- int32_t biXPelsPerMeter;
- int32_t biYPelsPerMeter;
- uint32_t biClrUsed;
- uint32_t biClrImportant;
-};
-
-struct message_resource_entry
-{
- uint16_t Length;
- uint16_t Flags;
- uint8_t Text[1];
-};
-
-struct message_resource_block
-{
- uint32_t LowId;
- uint32_t HighId;
- uint32_t OffsetToEntries;
-};
-
-struct message_resource_data
-{
- uint32_t NumberOfBlocks;
- message_resource_block Blocks[1];
-};
-
-struct image_resource_directory_entry
-{
- union
- {
- struct
- {
- uint32_t NameOffset:31;
- uint32_t NameIsString:1;
- };
- uint32_t Name;
- uint16_t Id;
- };
-
- union
- {
- uint32_t OffsetToData;
- struct
- {
- uint32_t OffsetToDirectory:31;
- uint32_t DataIsDirectory:1;
- };
- };
-};
-
-struct image_resource_data_entry
-{
- uint32_t OffsetToData;
- uint32_t Size;
- uint32_t CodePage;
- uint32_t Reserved;
-};
-
-#pragma pack(push, 2)
-struct bitmapfileheader
-{
- uint16_t bfType;
- uint32_t bfSize;
- uint16_t bfReserved1;
- uint16_t bfReserved2;
- uint32_t bfOffBits;
-};
-#pragma pack(pop)
-
-
-
-//Structure representing ICON file header
-struct ico_header
-{
- uint16_t Reserved;
- uint16_t Type; //1
- uint16_t Count; //Count of icons included in icon group
-};
-
-//Structure that is stored in icon group directory in PE resources
-struct icon_group
-{
- uint8_t Width;
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing ICON directory entry inside ICON file
-struct icondirentry
-{
- uint8_t Width;
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing CURSOR file header
-struct cursor_header
-{
- uint16_t Reserved;
- uint16_t Type; //2
- uint16_t Count; //Count of cursors included in cursor group
-};
-
-struct cursor_group
-{
- uint16_t Width;
- uint16_t Height; //Divide by 2 to get the actual height.
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing CURSOR directory entry inside CURSOR file
-struct cursordirentry
-{
- uint8_t Width; //Set to CURSOR_GROUP::Height/2.
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t HotspotX;
- uint16_t HotspotY;
- uint32_t SizeInBytes;
- uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing BLOCK in version info resource
-struct version_info_block //(always aligned on 32-bit (DWORD) boundary)
-{
- uint16_t Length; //Length of this block (doesn't include padding)
- uint16_t ValueLength; //Value length (if any)
- uint16_t Type; //Value type (0 = binary, 1 = text)
- uint16_t Key[1]; //Value name (block key) (always NULL terminated)
-
- //////////
- //WORD padding1[]; //Padding, if any (ALIGNMENT)
- //xxxxx Value[]; //Value data, if any (*ALIGNED*)
- //WORD padding2[]; //Padding, if any (ALIGNMENT)
- //xxxxx Child[]; //Child block(s), if any (*ALIGNED*)
- //////////
-};
-
-
-/// IMPORTS ///
-#pragma pack(push, 8)
-struct image_thunk_data64
-{
- union
- {
- uint64_t ForwarderString; // PBYTE
- uint64_t Function; // PDWORD
- uint64_t Ordinal;
- uint64_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
- } u1;
-};
-#pragma pack(pop)
-
-struct image_thunk_data32
-{
- union
- {
- uint32_t ForwarderString; // PBYTE
- uint32_t Function; // PDWORD
- uint32_t Ordinal;
- uint32_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
- } u1;
-};
-
-struct image_import_descriptor
-{
- union
- {
- uint32_t Characteristics; // 0 for terminating null import descriptor
- uint32_t OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
- };
-
- uint32_t TimeDateStamp; // 0 if not bound,
- // -1 if bound, and real date\time stamp
- // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
- // O.W. date/time stamp of DLL bound to (Old BIND)
-
- uint32_t ForwarderChain; // -1 if no forwarders
- uint32_t Name;
- uint32_t FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
-};
-
-
-/// TLS ///
-struct image_tls_directory64
-{
- uint64_t StartAddressOfRawData;
- uint64_t EndAddressOfRawData;
- uint64_t AddressOfIndex; // PDWORD
- uint64_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
- uint32_t SizeOfZeroFill;
- uint32_t Characteristics;
-};
-
-struct image_tls_directory32
-{
- uint32_t StartAddressOfRawData;
- uint32_t EndAddressOfRawData;
- uint32_t AddressOfIndex; // PDWORD
- uint32_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
- uint32_t SizeOfZeroFill;
- uint32_t Characteristics;
-};
-
-
-/// Export Format ///
-struct image_export_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t Name;
- uint32_t Base;
- uint32_t NumberOfFunctions;
- uint32_t NumberOfNames;
- uint32_t AddressOfFunctions; // RVA from base of image
- uint32_t AddressOfNames; // RVA from base of image
- uint32_t AddressOfNameOrdinals; // RVA from base of image
-};
-
-
-/// Based relocation format ///
-struct image_base_relocation
-{
- uint32_t VirtualAddress;
- uint32_t SizeOfBlock;
- // uint16_t TypeOffset[1];
-};
-
-
-/// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] ///
-struct image_bound_import_descriptor
-{
- uint32_t TimeDateStamp;
- uint16_t OffsetModuleName;
- uint16_t NumberOfModuleForwarderRefs;
- // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
-};
-
-struct image_bound_forwarder_ref
-{
- uint32_t TimeDateStamp;
- uint16_t OffsetModuleName;
- uint16_t Reserved;
-};
-
-
-/// Exception directory ///
-struct image_runtime_function_entry
-{
- uint32_t BeginAddress;
- uint32_t EndAddress;
- uint32_t UnwindInfoAddress;
-};
-
-enum unwind_op_codes
-{
- uwop_push_nonvol = 0, /* info == register number */
- uwop_alloc_large, /* no info, alloc size in next 2 slots */
- uwop_alloc_small, /* info == size of allocation / 8 - 1 */
- uwop_set_fpreg, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
- uwop_save_nonvol, /* info == register number, offset in next slot */
- uwop_save_nonvol_far, /* info == register number, offset in next 2 slots */
- uwop_save_xmm128, /* info == XMM reg number, offset in next slot */
- uwop_save_xmm128_far, /* info == XMM reg number, offset in next 2 slots */
- uwop_push_machframe /* info == 0: no error-code, 1: error-code */
-};
-
-union unwind_code
-{
- struct s
- {
- uint8_t CodeOffset;
- uint8_t UnwindOp : 4;
- uint8_t OpInfo : 4;
- };
-
- uint16_t FrameOffset;
-};
-
-struct unwind_info
-{
- uint8_t Version : 3;
- uint8_t Flags : 5;
- uint8_t SizeOfProlog;
- uint8_t CountOfCodes;
- uint8_t FrameRegister : 4;
- uint8_t FrameOffset : 4;
- unwind_code UnwindCode[1];
- /* unwind_code MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
- * union {
- * OPTIONAL ULONG ExceptionHandler;
- * OPTIONAL ULONG FunctionEntry;
- * };
- * OPTIONAL ULONG ExceptionData[]; */
-};
-
-
-
-/// Debug ///
-struct image_debug_misc
-{
- uint32_t DataType; // type of misc data, see defines
- uint32_t Length; // total length of record, rounded to four
- // byte multiple.
- uint8_t Unicode; // TRUE if data is unicode string
- uint8_t Reserved[3];
- uint8_t Data[1]; // Actual data
-};
-
-struct image_coff_symbols_header
-{
- uint32_t NumberOfSymbols;
- uint32_t LvaToFirstSymbol;
- uint32_t NumberOfLinenumbers;
- uint32_t LvaToFirstLinenumber;
- uint32_t RvaToFirstByteOfCode;
- uint32_t RvaToLastByteOfCode;
- uint32_t RvaToFirstByteOfData;
- uint32_t RvaToLastByteOfData;
-};
-
-struct image_debug_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t Type;
- uint32_t SizeOfData;
- uint32_t AddressOfRawData;
- uint32_t PointerToRawData;
-};
-
-
-#pragma pack(push, 2)
-struct image_symbol
-{
- union
- {
- uint8_t ShortName[8];
- struct
- {
- uint32_t Short; // if 0, use LongName
- uint32_t Long; // offset into string table
- } Name;
- uint32_t LongName[2]; // PBYTE [2]
- } N;
- uint32_t Value;
- int16_t SectionNumber;
- uint16_t Type;
- uint8_t StorageClass;
- uint8_t NumberOfAuxSymbols;
-};
-#pragma pack(pop)
-
-//CodeView Debug OMF signature. The signature at the end of the file is
-//a negative offset from the end of the file to another signature. At
-//the negative offset (base address) is another signature whose filepos
-//field points to the first OMFDirHeader in a chain of directories.
-//The NB05 signature is used by the link utility to indicated a completely
-//unpacked file. The NB06 signature is used by ilink to indicate that the
-//executable has had CodeView information from an incremental link appended
-//to the executable. The NB08 signature is used by cvpack to indicate that
-//the CodeView Debug OMF has been packed. CodeView will only process
-//executables with the NB08 signature.
-struct OMFSignature
-{
- char Signature[4]; // "NBxx"
- uint32_t filepos; // offset in file
-};
-
-struct CV_INFO_PDB20
-{
- OMFSignature CvHeader;
- uint32_t Signature;
- uint32_t Age;
- uint8_t PdbFileName[1];
-};
-
-struct CV_INFO_PDB70
-{
- uint32_t CvSignature;
- guid Signature;
- uint32_t Age;
- uint8_t PdbFileName[1];
-};
-
-// directory information structure
-// This structure contains the information describing the directory.
-// It is pointed to by the signature at the base address or the directory
-// link field of a preceeding directory. The directory entries immediately
-// follow this structure.
-struct OMFDirHeader
-{
- uint16_t cbDirHeader; // length of this structure
- uint16_t cbDirEntry; // number of bytes in each directory entry
- uint32_t cDir; // number of directorie entries
- int32_t lfoNextDir; // offset from base of next directory
- uint32_t flags; // status flags
-};
-
-// directory structure
-// The data in this structure is used to reference the data for each
-// subsection of the CodeView Debug OMF information. Tables that are
-// not associated with a specific module will have a module index of
-// oxffff. These tables are the global types table, the global symbol
-// table, the global public table and the library table.
-struct OMFDirEntry
-{
- uint16_t SubSection; // subsection type (sst...)
- uint16_t iMod; // module index
- int32_t lfo; // large file offset of subsection
- uint32_t cb; // number of bytes in subsection
-};
-
-
-/// CLR 2.0 header structure ///
-struct image_cor20_header
-{
- //Header versioning
- uint32_t cb;
- uint16_t MajorRuntimeVersion;
- uint16_t MinorRuntimeVersion;
-
- // Symbol table and startup information
- image_data_directory MetaData;
- uint32_t Flags;
-
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
- union
- {
- uint32_t EntryPointToken;
- uint32_t EntryPointRVA;
- };
-
- // Binding information
- image_data_directory Resources;
- image_data_directory StrongNameSignature;
-
- // Regular fixup and binding information
- image_data_directory CodeManagerTable;
- image_data_directory VTableFixups;
- image_data_directory ExportAddressTableJumps;
-
- // Precompiled image info (internal use only - set to zero)
- image_data_directory ManagedNativeHeader;
-};
-
-enum replaces_cor_hdr_numeric_defines
-{
- // COM+ Header entry point flags.
- comimage_flags_ilonly =0x00000001,
- comimage_flags_32bitrequired =0x00000002,
- comimage_flags_il_library =0x00000004,
- comimage_flags_strongnamesigned =0x00000008,
- comimage_flags_native_entrypoint =0x00000010,
- comimage_flags_trackdebugdata =0x00010000,
-
- // Version flags for image.
- cor_version_major_v2 =2,
- cor_version_major =cor_version_major_v2,
- cor_version_minor =0,
- cor_deleted_name_length =8,
- cor_vtablegap_name_length =8,
-
- // Maximum size of a NativeType descriptor.
- native_type_max_cb =1,
- cor_ilmethod_sect_small_max_datasize=0xff,
-
- // #defines for the MIH FLAGS
- image_cor_mih_methodrva =0x01,
- image_cor_mih_ehrva =0x02,
- image_cor_mih_basicblock =0x08,
-
- // V-table constants
- cor_vtable_32bit =0x01, // V-table slots are 32-bits in size.
- cor_vtable_64bit =0x02, // V-table slots are 64-bits in size.
- cor_vtable_from_unmanaged =0x04, // If set, transition from unmanaged.
- cor_vtable_from_unmanaged_retain_appdomain =0x08, // If set, transition from unmanaged with keeping the current appdomain.
- cor_vtable_call_most_derived =0x10, // Call most derived method described by
-
- // EATJ constants
- image_cor_eatj_thunk_size =32, // Size of a jump thunk reserved range.
-
- // Max name lengths
- //@todo: Change to unlimited name lengths.
- max_class_name =1024,
- max_package_name =1024
-};
-
-/// Load Configuration Directory Entry ///
-struct image_load_config_directory32
-{
- uint32_t Size;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t GlobalFlagsClear;
- uint32_t GlobalFlagsSet;
- uint32_t CriticalSectionDefaultTimeout;
- uint32_t DeCommitFreeBlockThreshold;
- uint32_t DeCommitTotalFreeThreshold;
- uint32_t LockPrefixTable; // VA
- uint32_t MaximumAllocationSize;
- uint32_t VirtualMemoryThreshold;
- uint32_t ProcessHeapFlags;
- uint32_t ProcessAffinityMask;
- uint16_t CSDVersion;
- uint16_t Reserved1;
- uint32_t EditList; // VA
- uint32_t SecurityCookie; // VA
- uint32_t SEHandlerTable; // VA
- uint32_t SEHandlerCount;
-};
-
-struct image_load_config_directory64
-{
- uint32_t Size;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t GlobalFlagsClear;
- uint32_t GlobalFlagsSet;
- uint32_t CriticalSectionDefaultTimeout;
- uint64_t DeCommitFreeBlockThreshold;
- uint64_t DeCommitTotalFreeThreshold;
- uint64_t LockPrefixTable; // VA
- uint64_t MaximumAllocationSize;
- uint64_t VirtualMemoryThreshold;
- uint64_t ProcessAffinityMask;
- uint32_t ProcessHeapFlags;
- uint16_t CSDVersion;
- uint16_t Reserved1;
- uint64_t EditList; // VA
- uint64_t SecurityCookie; // VA
- uint64_t SEHandlerTable; // VA
- uint64_t SEHandlerCount;
-};
-
-#pragma pack(pop)
-} //namespace pe_win
-
-#ifdef PE_BLISS_WINDOWS
-typedef wchar_t unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#else
-//Instead of wchar_t for windows
-typedef unsigned short unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#endif
-
-} //namespace pe_bliss
diff --git a/tools/pe_bliss/pe_tls.cpp b/tools/pe_bliss/pe_tls.cpp
deleted file mode 100644
index 5ec68e3f10..0000000000
--- a/tools/pe_bliss/pe_tls.cpp
+++ /dev/null
@@ -1,396 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//TLS
-//Default constructor
-tls_info::tls_info()
- :start_rva_(0), end_rva_(0), index_rva_(0), callbacks_rva_(0),
- size_of_zero_fill_(0), characteristics_(0)
-{}
-
-//Returns start RVA of TLS raw data
-uint32_t tls_info::get_raw_data_start_rva() const
-{
- return start_rva_;
-}
-
-//Returns end RVA of TLS raw data
-uint32_t tls_info::get_raw_data_end_rva() const
-{
- return end_rva_;
-}
-
-//Returns TLS index RVA
-uint32_t tls_info::get_index_rva() const
-{
- return index_rva_;
-}
-
-//Returns TLS callbacks RVA
-uint32_t tls_info::get_callbacks_rva() const
-{
- return callbacks_rva_;
-}
-
-//Returns size of zero fill
-uint32_t tls_info::get_size_of_zero_fill() const
-{
- return size_of_zero_fill_;
-}
-
-//Returns characteristics
-uint32_t tls_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns raw TLS data
-const std::string& tls_info::get_raw_data() const
-{
- return raw_data_;
-}
-
-//Returns TLS callbacks addresses
-const tls_info::tls_callback_list& tls_info::get_tls_callbacks() const
-{
- return callbacks_;
-}
-
-//Returns TLS callbacks addresses
-tls_info::tls_callback_list& tls_info::get_tls_callbacks()
-{
- return callbacks_;
-}
-
-//Adds TLS callback
-void tls_info::add_tls_callback(uint32_t rva)
-{
- callbacks_.push_back(rva);
-}
-
-//Clears TLS callbacks list
-void tls_info::clear_tls_callbacks()
-{
- callbacks_.clear();
-}
-
-//Recalculates end address of raw TLS data
-void tls_info::recalc_raw_data_end_rva()
-{
- end_rva_ = static_cast<uint32_t>(start_rva_ + raw_data_.length());
-}
-
-//Sets start RVA of TLS raw data
-void tls_info::set_raw_data_start_rva(uint32_t rva)
-{
- start_rva_ = rva;
-}
-
-//Sets end RVA of TLS raw data
-void tls_info::set_raw_data_end_rva(uint32_t rva)
-{
- end_rva_ = rva;
-}
-
-//Sets TLS index RVA
-void tls_info::set_index_rva(uint32_t rva)
-{
- index_rva_ = rva;
-}
-
-//Sets TLS callbacks RVA
-void tls_info::set_callbacks_rva(uint32_t rva)
-{
- callbacks_rva_ = rva;
-}
-
-//Sets size of zero fill
-void tls_info::set_size_of_zero_fill(uint32_t size)
-{
- size_of_zero_fill_ = size;
-}
-
-//Sets characteristics
-void tls_info::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets raw TLS data
-void tls_info::set_raw_data(const std::string& data)
-{
- raw_data_ = data;
-}
-
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe)
-{
- return pe.get_pe_type() == pe_type_32
- ? get_tls_info_base<pe_types_class_32>(pe)
- : get_tls_info_base<pe_types_class_64>(pe);
-}
-
-//TLS Rebuilder
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
- return pe.get_pe_type() == pe_type_32
- ? rebuild_tls_base<pe_types_class_32>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section)
- : rebuild_tls_base<pe_types_class_64>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section);
-}
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe)
-{
- tls_info ret;
-
- //If there's no TLS directory, throw an exception
- if(!pe.has_tls())
- throw pe_exception("Image does not have TLS directory", pe_exception::directory_does_not_exist);
-
- //Get TLS directory data
- typename PEClassType::TLSStruct tls_directory_data = pe.section_data_from_rva<typename PEClassType::TLSStruct>(pe.get_directory_rva(image_directory_entry_tls), section_data_virtual, true);
-
- //Check data addresses
- if(tls_directory_data.EndAddressOfRawData == tls_directory_data.StartAddressOfRawData)
- {
- try
- {
- pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData));
- }
- catch(const pe_exception&)
- {
- //Fix addressess on incorrect conversion
- tls_directory_data.EndAddressOfRawData = tls_directory_data.StartAddressOfRawData = 0;
- }
- }
-
- if(tls_directory_data.StartAddressOfRawData &&
- pe.section_data_length_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData),
- static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true)
- < (tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData))
- throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
- //Fill TLS info
- //VAs are not checked
- ret.set_raw_data_start_rva(tls_directory_data.StartAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData)) : 0);
- ret.set_raw_data_end_rva(tls_directory_data.EndAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData)) : 0);
- ret.set_index_rva(tls_directory_data.AddressOfIndex ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfIndex)) : 0);
- ret.set_callbacks_rva(tls_directory_data.AddressOfCallBacks ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks)) : 0);
- ret.set_size_of_zero_fill(tls_directory_data.SizeOfZeroFill);
- ret.set_characteristics(tls_directory_data.Characteristics);
-
- if(tls_directory_data.StartAddressOfRawData && tls_directory_data.StartAddressOfRawData != tls_directory_data.EndAddressOfRawData)
- {
- //Read and save TLS RAW data
- ret.set_raw_data(std::string(
- pe.section_data_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true),
- static_cast<uint32_t>(tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData)));
- }
-
- //If file has TLS callbacks
- if(ret.get_callbacks_rva())
- {
- //Read callbacks VAs
- uint32_t current_tls_callback = 0;
-
- while(true)
- {
- //Read TLS callback VA
- typename PEClassType::BaseSize va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks + current_tls_callback), section_data_virtual, true);
- if(va == 0)
- break;
-
- //Save it
- ret.add_tls_callback(pe.va_to_rva(va, false));
-
- //Move to next callback VA
- current_tls_callback += sizeof(va);
- }
- }
-
- return ret;
-}
-
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//Note/TODO: TLS Callbacks array is not DWORD-aligned (seems to work on WinXP - Win7)
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that tls_section is attached to this PE image
- if(!pe.section_attached(tls_section))
- throw pe_exception("TLS section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t tls_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize));
- uint32_t needed_size = sizeof(typename PEClassType::TLSStruct); //Calculate needed size for TLS table
-
- //Check if tls_section is last one. If it's not, check if there's enough place for TLS data
- if(&tls_section != &*(pe.get_image_sections().end() - 1) &&
- (tls_section.empty() || pe_utils::align_up(tls_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + tls_data_pos))
- throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
- //Check raw data positions
- if(info.get_raw_data_end_rva() < info.get_raw_data_start_rva() || info.get_index_rva() == 0)
- throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
- std::string& raw_data = tls_section.get_raw_data();
-
- //This will be done only if tls_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + tls_data_pos)
- raw_data.resize(needed_size + tls_data_pos); //Expand section raw data
-
- //Create and fill TLS structure
- typename PEClassType::TLSStruct tls_struct = {0};
-
- typename PEClassType::BaseSize va;
- if(info.get_raw_data_start_rva())
- {
- pe.rva_to_va(info.get_raw_data_start_rva(), va);
- tls_struct.StartAddressOfRawData = va;
- tls_struct.SizeOfZeroFill = info.get_size_of_zero_fill();
- }
-
- if(info.get_raw_data_end_rva())
- {
- pe.rva_to_va(info.get_raw_data_end_rva(), va);
- tls_struct.EndAddressOfRawData = va;
- }
-
- pe.rva_to_va(info.get_index_rva(), va);
- tls_struct.AddressOfIndex = va;
-
- if(info.get_callbacks_rva())
- {
- pe.rva_to_va(info.get_callbacks_rva(), va);
- tls_struct.AddressOfCallBacks = va;
- }
-
- tls_struct.Characteristics = info.get_characteristics();
-
- //Save TLS structure
- memcpy(&raw_data[tls_data_pos], &tls_struct, sizeof(tls_struct));
-
- //If we are asked to rewrite TLS raw data
- if(write_tls_data && info.get_raw_data_start_rva() && info.get_raw_data_start_rva() != info.get_raw_data_end_rva())
- {
- try
- {
- //Check if we're going to write TLS raw data to an existing section (not to PE headers)
- section& raw_data_section = pe.section_from_rva(info.get_raw_data_start_rva());
- pe.expand_section(raw_data_section, info.get_raw_data_start_rva(), info.get_raw_data_end_rva() - info.get_raw_data_start_rva(), expand == tls_data_expand_raw ? pe_base::expand_section_raw : pe_base::expand_section_virtual);
- }
- catch(const pe_exception&)
- {
- //If no section is presented by StartAddressOfRawData, just go to next step
- }
-
- unsigned long write_raw_data_size = info.get_raw_data_end_rva() - info.get_raw_data_start_rva();
- unsigned long available_raw_length = 0;
-
- //Check if there's enough RAW space to write raw TLS data...
- if((available_raw_length = pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_raw, true))
- < info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
- {
- //Check if there's enough virtual space for it...
- if(pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_virtual, true)
- < info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
- throw pe_exception("Insufficient space for TLS raw data", pe_exception::insufficient_space);
- else
- write_raw_data_size = available_raw_length; //We'll write just a part of full raw data
- }
-
- //Write raw TLS data, if any
- if(write_raw_data_size != 0)
- memcpy(pe.section_data_from_rva(info.get_raw_data_start_rva(), true), info.get_raw_data().data(), write_raw_data_size);
- }
-
- //If we are asked to rewrite TLS callbacks addresses
- if(write_tls_callbacks && info.get_callbacks_rva())
- {
- unsigned long needed_callback_size = static_cast<unsigned long>((info.get_tls_callbacks().size() + 1 /* last null element */) * sizeof(typename PEClassType::BaseSize));
-
- try
- {
- //Check if we're going to write TLS callbacks VAs to an existing section (not to PE headers)
- section& raw_data_section = pe.section_from_rva(info.get_callbacks_rva());
- pe.expand_section(raw_data_section, info.get_callbacks_rva(), needed_callback_size, pe_base::expand_section_raw);
- }
- catch(const pe_exception&)
- {
- //If no section is presented by RVA of callbacks, just go to next step
- }
-
- //Check if there's enough space to write callbacks TLS data...
- if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_raw, true)
- < needed_callback_size - sizeof(typename PEClassType::BaseSize) /* last zero element can be virtual only */)
- throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-
- if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_virtual, true)
- < needed_callback_size /* check here full virtual data length available */)
- throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-
- std::vector<typename PEClassType::BaseSize> callbacks_virtual_addresses;
- callbacks_virtual_addresses.reserve(info.get_tls_callbacks().size() + 1 /* last null element */);
-
- //Convert TLS RVAs to VAs
- for(tls_info::tls_callback_list::const_iterator it = info.get_tls_callbacks().begin(); it != info.get_tls_callbacks().end(); ++it)
- {
- typename PEClassType::BaseSize cb_va = 0;
- pe.rva_to_va(*it, cb_va);
- callbacks_virtual_addresses.push_back(cb_va);
- }
-
- //Ending null element
- callbacks_virtual_addresses.push_back(0);
-
- //Write callbacks TLS data
- memcpy(pe.section_data_from_rva(info.get_callbacks_rva(), true), &callbacks_virtual_addresses[0], needed_callback_size);
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(tls_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(tls_section, tls_data_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_tls, ret.get_rva());
- pe.set_directory_size(image_directory_entry_tls, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_tls.h b/tools/pe_bliss/pe_tls.h
deleted file mode 100644
index 316e208147..0000000000
--- a/tools/pe_bliss/pe_tls.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing TLS info
-//We use "DWORD" type to represent RVAs, because RVA is
-//always 32bit even in PE+
-class tls_info
-{
-public:
- typedef std::vector<uint32_t> tls_callback_list;
-
-public:
- //Default constructor
- tls_info();
-
- //Returns start RVA of TLS raw data
- uint32_t get_raw_data_start_rva() const;
- //Returns end RVA of TLS raw data
- uint32_t get_raw_data_end_rva() const;
- //Returns TLS index RVA
- uint32_t get_index_rva() const;
- //Returns TLS callbacks RVA
- uint32_t get_callbacks_rva() const;
- //Returns size of zero fill
- uint32_t get_size_of_zero_fill() const;
- //Returns characteristics
- uint32_t get_characteristics() const;
- //Returns raw TLS data
- const std::string& get_raw_data() const;
- //Returns TLS callbacks addresses
- const tls_callback_list& get_tls_callbacks() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild TLS directory
-
- //Sets start RVA of TLS raw data
- void set_raw_data_start_rva(uint32_t rva);
- //Sets end RVA of TLS raw data
- void set_raw_data_end_rva(uint32_t rva);
- //Sets TLS index RVA
- void set_index_rva(uint32_t rva);
- //Sets TLS callbacks RVA
- void set_callbacks_rva(uint32_t rva);
- //Sets size of zero fill
- void set_size_of_zero_fill(uint32_t size);
- //Sets characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets raw TLS data
- void set_raw_data(const std::string& data);
- //Returns TLS callbacks addresses
- tls_callback_list& get_tls_callbacks();
- //Adds TLS callback
- void add_tls_callback(uint32_t rva);
- //Clears TLS callbacks list
- void clear_tls_callbacks();
- //Recalculates end address of raw TLS data
- void recalc_raw_data_end_rva();
-
-private:
- uint32_t start_rva_, end_rva_, index_rva_, callbacks_rva_;
- uint32_t size_of_zero_fill_, characteristics_;
-
- //Raw TLS data
- std::string raw_data_;
-
- //TLS callback RVAs
- tls_callback_list callbacks_;
-};
-
-//Represents type of expanding of TLS section containing raw data
-//(Works only if you are writing TLS raw data to tls_section and it is the last one in the PE image on the moment of TLS rebuild)
-enum tls_data_expand_type
-{
- tls_data_expand_raw, //If there is not enough raw space for raw TLS data, it can be expanded
- tls_data_expand_virtual //If there is not enough virtual place for raw TLS data, it can be expanded
-};
-
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe);
-
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe);
-
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/resource_bitmap_reader.cpp b/tools/pe_bliss/resource_bitmap_reader.cpp
deleted file mode 100644
index 3546461f53..0000000000
--- a/tools/pe_bliss/resource_bitmap_reader.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <cmath>
-#include "resource_bitmap_reader.h"
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_reader::resource_bitmap_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(const std::wstring& name, uint32_t index) const
-{
- return create_bitmap(res_.get_resource_data_by_name(pe_resource_viewer::resource_bitmap, name, index).get_data());
-}
-
-//Returns bitmap data by name and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(uint32_t language, const std::wstring& name) const
-{
- return create_bitmap(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_bitmap, name).get_data());
-}
-
-//Returns bitmap data by ID and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const
-{
- return create_bitmap(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_bitmap, id).get_data());
-}
-
-//Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id(uint32_t id, uint32_t index) const
-{
- return create_bitmap(res_.get_resource_data_by_id(pe_resource_viewer::resource_bitmap, id, index).get_data());
-}
-
-//Helper function of creating bitmap header
-const std::string resource_bitmap_reader::create_bitmap(const std::string& resource_data)
-{
- //Create bitmap file header
- bitmapfileheader header = {0};
- header.bfType = 0x4d42; //Signature "BM"
- header.bfOffBits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader); //Offset to bitmap bits
- header.bfSize = static_cast<uint32_t>(sizeof(bitmapfileheader) + resource_data.length()); //Size of bitmap
-
- //Check size of resource data
- if(resource_data.length() < sizeof(bitmapinfoheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- {
- //Get bitmap info header
- const bitmapinfoheader* info = reinterpret_cast<const bitmapinfoheader*>(resource_data.data());
-
- //If color table is present, skip it
- if(info->biClrUsed != 0)
- header.bfOffBits += 4 * info->biClrUsed; //Add this size to offset to bitmap bits
- else if(info->biBitCount <= 8)
- header.bfOffBits += 4 * static_cast<uint32_t>(std::pow(2.f, info->biBitCount)); //Add this size to offset to bitmap bits
- }
-
- //Return final bitmap data
- return std::string(reinterpret_cast<const char*>(&header), sizeof(bitmapfileheader)) + resource_data;
-}
-}
diff --git a/tools/pe_bliss/resource_bitmap_reader.h b/tools/pe_bliss/resource_bitmap_reader.h
deleted file mode 100644
index f2b92bbde7..0000000000
--- a/tools/pe_bliss/resource_bitmap_reader.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_bitmap_reader
-{
-public:
- resource_bitmap_reader(const pe_resource_viewer& res);
-
- //Returns bitmap data by name and language (minimum checks of format correctness)
- const std::string get_bitmap_by_name(uint32_t language, const std::wstring& name) const;
- //Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_bitmap_by_name(const std::wstring& name, uint32_t index = 0) const;
- //Returns bitmap data by ID and language (minimum checks of format correctness)
- const std::string get_bitmap_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_bitmap_by_id(uint32_t id, uint32_t index = 0) const;
-
-private:
- //Helper function of creating bitmap header
- static const std::string create_bitmap(const std::string& resource_data);
-
- const pe_resource_viewer& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_bitmap_writer.cpp b/tools/pe_bliss/resource_bitmap_writer.cpp
deleted file mode 100644
index 3445a08445..0000000000
--- a/tools/pe_bliss/resource_bitmap_writer.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "resource_bitmap_writer.h"
-#include "pe_resource_manager.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_writer::resource_bitmap_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Check bitmap data a little
- if(bitmap_file.length() < sizeof(bitmapfileheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- //Add bitmap
- res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Check bitmap data a little
- if(bitmap_file.length() < sizeof(bitmapfileheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- //Add bitmap
- res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(const std::wstring& name, uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_bitmap, name, language);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(uint32_t id, uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_bitmap, id, language);
-}
-}
diff --git a/tools/pe_bliss/resource_bitmap_writer.h b/tools/pe_bliss/resource_bitmap_writer.h
deleted file mode 100644
index 4b8ea72705..0000000000
--- a/tools/pe_bliss/resource_bitmap_writer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_bitmap_writer
-{
-public:
- resource_bitmap_writer(pe_resource_manager& res);
-
- //Adds bitmap from bitmap file data. If bitmap already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
- //Removes bitmap by name/ID and language
- bool remove_bitmap(const std::wstring& name, uint32_t language);
- bool remove_bitmap(uint32_t id, uint32_t language);
-
-private:
- pe_resource_manager& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_reader.cpp b/tools/pe_bliss/resource_cursor_icon_reader.cpp
deleted file mode 100644
index 28a259163e..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_reader.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include "resource_cursor_icon_reader.h"
-#include "pe_structures.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_reader::resource_cursor_icon_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Helper function of creating icon headers from ICON_GROUP resource data
-//Returns icon count
-uint16_t resource_cursor_icon_reader::format_icon_headers(std::string& ico_data, const std::string& resource_data)
-{
- //Check resource data size
- if(resource_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(resource_data.data());
-
- //Check resource data size
- if(resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Reserve memory to speed up a little
- ico_data.reserve(sizeof(ico_header) + info->Count * sizeof(icondirentry));
- ico_data.append(reinterpret_cast<const char*>(info), sizeof(ico_header));
-
- //Iterate over all listed icons
- uint32_t offset = sizeof(ico_header) + sizeof(icondirentry) * info->Count;
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-
- //Fill icon data
- icondirentry direntry;
- direntry.BitCount = group->BitCount;
- direntry.ColorCount = group->ColorCount;
- direntry.Height = group->Height;
- direntry.Planes = group->Planes;
- direntry.Reserved = group->Reserved;
- direntry.SizeInBytes = group->SizeInBytes;
- direntry.Width = group->Width;
- direntry.ImageOffset = offset;
-
- //Add icon header to returned value
- ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(icondirentry));
-
- offset += group->SizeInBytes;
- }
-
- //Return icon count
- return info->Count;
-}
-
-//Returns single icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
- //Get icon headers
- std::string icon_data(lookup_icon_group_data_by_icon(id, language));
- //Append icon data
- icon_data.append(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, id).get_data());
- return icon_data;
-}
-
-//Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id(uint32_t id, uint32_t index) const
-{
- pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_icon, id));
- if(languages.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- //Get icon headers
- std::string icon_data(lookup_icon_group_data_by_icon(id, languages.at(index)));
- //Append icon data
- icon_data.append(res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, id, index).get_data());
- return icon_data;
-}
-
-//Returns icon data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(const std::wstring& name, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by name and index
- const std::string data = res_.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, name, index).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(uint32_t language, const std::wstring& name) const
-{
- std::string ret;
-
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, name).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string ret;
-
- //Get resource by language and id
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, id).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id(uint32_t id, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by id and index
- const std::string data = res_.get_resource_data_by_id(pe_resource_viewer::resource_icon_group, id, index).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
- }
-
- return ret;
-}
-
-//Checks for icon presence inside icon group, fills icon headers if found
-bool resource_cursor_icon_reader::check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data)
-{
- //Check resource data size
- if(icon_group_resource_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_resource_data.data());
-
- //Check resource data size
- if(icon_group_resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- if(group->Number == icon_id)
- {
- //Reserve memory to speed up a little
- ico_data.reserve(sizeof(ico_header) + sizeof(icondirentry));
- //Write single-icon icon header
- ico_header new_header = *info;
- new_header.Count = 1;
- ico_data.append(reinterpret_cast<const char*>(&new_header), sizeof(ico_header));
-
- //Fill icon data
- icondirentry direntry;
- direntry.BitCount = group->BitCount;
- direntry.ColorCount = group->ColorCount;
- direntry.Height = group->Height;
- direntry.Planes = group->Planes;
- direntry.Reserved = group->Reserved;
- direntry.SizeInBytes = group->SizeInBytes;
- direntry.Width = group->Width;
- direntry.ImageOffset = sizeof(ico_header) + sizeof(icondirentry);
- ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(direntry));
-
- return true;
- }
- }
-
- return false;
-}
-
-//Looks up icon group by icon id and returns full icon headers if found
-const std::string resource_cursor_icon_reader::lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const
-{
- std::string icon_header_data;
-
- {
- //List all ID-resources
- pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_icon_group));
-
- for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_icon_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
- return icon_header_data;
- }
- }
-
- {
- //List all named resources
- pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_icon_group));
- for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_icon_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
- return icon_header_data;
- }
- }
-
- throw pe_exception("No icon group find for requested icon", pe_exception::no_icon_group_found);
-}
-
-//Returns single cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string raw_cursor_data(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, id).get_data());
- //Get cursor headers
- std::string cursor_data(lookup_cursor_group_data_by_cursor(id, language, raw_cursor_data));
- //Append cursor data
- cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
- return cursor_data;
-}
-
-//Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id(uint32_t id, uint32_t index) const
-{
- pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor, id));
- if(languages.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- std::string raw_cursor_data(res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, id, index).get_data());
- //Get cursor headers
- std::string cursor_data(lookup_cursor_group_data_by_cursor(id, languages.at(index), raw_cursor_data));
- //Append cursor data
- cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
- return cursor_data;
-}
-
-//Helper function of creating cursor headers
-//Returns cursor count
-uint16_t resource_cursor_icon_reader::format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index) const
-{
- //Check resource data length
- if(resource_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* info = reinterpret_cast<const cursor_header*>(resource_data.data());
-
- //Check resource data length
- if(resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group) * info->Count)
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Reserve needed space to speed up a little
- cur_data.reserve(sizeof(cursor_header) + info->Count * sizeof(cursordirentry));
- //Add cursor header
- cur_data.append(reinterpret_cast<const char*>(info), sizeof(cursor_header));
-
- //Iterate over all cursors listed in cursor group
- uint32_t offset = sizeof(cursor_header) + sizeof(cursordirentry) * info->Count;
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
- //Fill cursor info
- cursordirentry direntry;
- direntry.ColorCount = 0; //OK
- direntry.Width = static_cast<uint8_t>(group->Width);
- direntry.Height = static_cast<uint8_t>(group->Height) / 2;
- direntry.Reserved = 0;
-
- //Now read hotspot data from cursor data directory
- const std::string cursor = index == 0xFFFFFFFF
- ? res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data()
- : res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data();
- if(cursor.length() < 2 * sizeof(uint16_t))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Here it is - two words in the very beginning of cursor data
- direntry.HotspotX = *reinterpret_cast<const uint16_t*>(cursor.data());
- direntry.HotspotY = *reinterpret_cast<const uint16_t*>(cursor.data() + sizeof(uint16_t));
-
- //Fill the rest data
- direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
- direntry.ImageOffset = offset;
-
- //Add cursor header
- cur_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
- offset += direntry.SizeInBytes;
- }
-
- //Return cursor count
- return info->Count;
-}
-
-//Returns cursor data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(uint32_t language, const std::wstring& name) const
-{
- std::string ret;
-
- //Get resource by name and language
- const std::string resource_data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, name).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(const std::wstring& name, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by name and index
- const std::string resource_data = res_.get_resource_data_by_name(pe_resource_viewer::resource_cursor_group, name, index).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string ret;
-
- //Get resource by ID and language
- const std::string resource_data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, id).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id(uint32_t id, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by ID and index
- const std::string resource_data = res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor_group, id, index).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Checks for cursor presence inside cursor group, fills cursor headers if found
-bool resource_cursor_icon_reader::check_cursor_presence(const std::string& cursor_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data)
-{
- //Check resource data length
- if(cursor_group_resource_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_resource_data.data());
-
- //Check resource data length
- if(cursor_group_resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Iterate over all cursors listed in cursor group
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(cursor_group_resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
- if(group->Number == cursor_id)
- {
- //Reserve needed space to speed up a little
- cur_header_data.reserve(sizeof(cursor_header) + sizeof(cursordirentry));
- //Write single-cursor cursor header
- cursor_header new_header = *info;
- new_header.Count = 1;
- cur_header_data.append(reinterpret_cast<const char*>(&new_header), sizeof(cursor_header));
-
- //Fill cursor info
- cursordirentry direntry;
- direntry.ColorCount = 0; //OK
- direntry.Width = static_cast<uint8_t>(group->Width);
- direntry.Height = static_cast<uint8_t>(group->Height) / 2;
- direntry.Reserved = 0;
-
- if(raw_cursor_data.length() < 2 * sizeof(uint16_t))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Here it is - two words in the very beginning of cursor data
- direntry.HotspotX = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data());
- direntry.HotspotY = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data() + sizeof(uint16_t));
-
- //Fill the rest data
- direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
- direntry.ImageOffset = sizeof(cursor_header) + sizeof(cursordirentry);
-
- //Add cursor header
- cur_header_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
- return true;
- }
- }
-
- return false;
-}
-
-//Looks up cursor group by cursor id and returns full cursor headers if found
-const std::string resource_cursor_icon_reader::lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const
-{
- std::string cursor_header_data;
-
- {
- //List all ID-resources
- pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_cursor_group));
-
- for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_cursor_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
- return cursor_header_data;
- }
- }
-
- {
- //List all named resources
- pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_cursor_group));
- for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_cursor_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
- return cursor_header_data;
- }
- }
-
- throw pe_exception("No cursor group find for requested icon", pe_exception::no_cursor_group_found);
-}
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_reader.h b/tools/pe_bliss/resource_cursor_icon_reader.h
deleted file mode 100644
index e34fff419b..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_reader.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_cursor_icon_reader
-{
-public:
- resource_cursor_icon_reader(const pe_resource_viewer& res);
-
- //Returns single icon data by ID and language (minimum checks of format correctness)
- const std::string get_single_icon_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_single_icon_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Returns icon data of group of icons by name and language (minimum checks of format correctness)
- const std::string get_icon_by_name(uint32_t language, const std::wstring& icon_group_name) const;
- //Returns icon data of group of icons by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_icon_by_name(const std::wstring& icon_group_name, uint32_t index = 0) const;
- //Returns icon data of group of icons by ID and language (minimum checks of format correctness)
- const std::string get_icon_by_id_lang(uint32_t language, uint32_t icon_group_id) const;
- //Returns icon data of group of icons by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_icon_by_id(uint32_t icon_group_id, uint32_t index = 0) const;
-
- //Returns single cursor data by ID and language (minimum checks of format correctness)
- const std::string get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_single_cursor_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Returns cursor data by name and language (minimum checks of format correctness)
- const std::string get_cursor_by_name(uint32_t language, const std::wstring& cursor_group_name) const;
- //Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_cursor_by_name(const std::wstring& cursor_group_name, uint32_t index = 0) const;
- //Returns cursor data by ID and language (minimum checks of format correctness)
- const std::string get_cursor_by_id_lang(uint32_t language, uint32_t cursor_group_id) const;
- //Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_cursor_by_id(uint32_t cursor_group_id, uint32_t index = 0) const;
-
-private:
- const pe_resource_viewer& res_;
-
- //Helper function of creating icon headers from ICON_GROUP resource data
- //Returns icon count
- static uint16_t format_icon_headers(std::string& ico_data, const std::string& resource_data);
-
- //Helper function of creating cursor headers from CURSOR_GROUP resource data
- //Returns cursor count
- uint16_t format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index = 0xFFFFFFFF) const;
-
- //Looks up icon group by icon id and returns full icon headers if found
- const std::string lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const;
- //Checks for icon presence inside icon group, fills icon headers if found
- static bool check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data);
-
- //Looks up cursor group by cursor id and returns full cursor headers if found
- const std::string lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const;
- //Checks for cursor presence inside cursor group, fills cursor headers if found
- static bool check_cursor_presence(const std::string& icon_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data);
-};
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_writer.cpp b/tools/pe_bliss/resource_cursor_icon_writer.cpp
deleted file mode 100644
index 2f1c4363c4..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_writer.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "resource_cursor_icon_writer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_writer::resource_cursor_icon_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Add icon helper
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- //Check icon for correctness
- if(icon_file.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- const ico_header* icon_header = reinterpret_cast<const ico_header*>(&icon_file[0]);
-
- unsigned long size_of_headers = sizeof(ico_header) + icon_header->Count * sizeof(icondirentry);
- if(icon_file.length() < size_of_headers || icon_header->Count == 0)
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Enumerate all icons in file
- for(uint16_t i = 0; i != icon_header->Count; ++i)
- {
- //Check icon entries
- const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
- if(icon_entry->SizeInBytes == 0
- || icon_entry->ImageOffset < size_of_headers
- || !pe_utils::is_sum_safe(icon_entry->ImageOffset, icon_entry->SizeInBytes)
- || icon_entry->ImageOffset + icon_entry->SizeInBytes > icon_file.length())
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
- }
-
- std::string icon_group_data;
- ico_header* info = 0;
-
- if(group_icon_info)
- {
- //If icon group already exists
- {
- icon_group_data = group_icon_info->get_data();
- codepage = group_icon_info->get_codepage(); //Don't change codepage of icon group entry
- }
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- info = reinterpret_cast<ico_header*>(&icon_group_data[0]);
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- icon_group_data.resize(sizeof(ico_header) + (info->Count + icon_header->Count) * sizeof(icon_group));
- info = reinterpret_cast<ico_header*>(&icon_group_data[0]); //In case if memory was reallocated
- }
- else //Entry not found - icon group doesn't exist
- {
- icon_group_data.resize(sizeof(ico_header) + icon_header->Count * sizeof(icon_group));
- memcpy(&icon_group_data[0], icon_header, sizeof(ico_header));
- }
-
- //Search for available icon IDs
- std::vector<uint16_t> icon_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_icon, mode, icon_header->Count));
-
- //Enumerate all icons in file
- for(uint16_t i = 0; i != icon_header->Count; ++i)
- {
- const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
- icon_group group = {0};
-
- //Fill icon resource header
- group.BitCount = icon_entry->BitCount;
- group.ColorCount = icon_entry->ColorCount;
- group.Height = icon_entry->Height;
- group.Planes = icon_entry->Planes;
- group.Reserved = icon_entry->Reserved;
- group.SizeInBytes = icon_entry->SizeInBytes;
- group.Width = icon_entry->Width;
- group.Number = icon_id_list.at(i);
-
- memcpy(&icon_group_data[sizeof(ico_header) + ((info ? info->Count : 0) + i) * sizeof(icon_group)], &group, sizeof(group));
-
- //Add icon to resources
- resource_directory_entry new_entry;
- new_entry.set_id(group.Number);
- res_.add_resource(icon_file.substr(icon_entry->ImageOffset, icon_entry->SizeInBytes), pe_resource_viewer::resource_icon, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
- }
-
- if(info)
- info->Count += icon_header->Count; //Increase icon count, if we're adding icon to existing group
-
- {
- //Add or replace icon group data entry
- res_.add_resource(icon_group_data, pe_resource_viewer::resource_icon_group, new_icon_group_entry, finder, language, codepage, timestamp);
- }
-}
-
-//Returns free icon or cursor ID list depending on icon_place_mode
-const std::vector<uint16_t> resource_cursor_icon_writer::get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_type type, icon_place_mode mode, uint32_t count)
-{
- //Search for available icon/cursor IDs
- std::vector<uint16_t> icon_cursor_id_list;
-
- try
- {
- //If any icon exists
- //List icon IDs
- std::vector<uint32_t> id_list(res_.list_resource_ids(type));
- std::sort(id_list.begin(), id_list.end());
-
- //If we are placing icon on free spaces
- //I.e., icon IDs 1, 3, 4, 7, 8 already exist
- //We'll place five icons on IDs 2, 5, 6, 9, 10
- if(mode != icon_place_after_max_icon_id)
- {
- if(!id_list.empty())
- {
- //Determine and list free icon IDs
- for(std::vector<uint32_t>::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
- {
- if(it == id_list.begin())
- {
- if(*it > 1)
- {
- for(uint16_t i = 1; i != *it; ++i)
- {
- icon_cursor_id_list.push_back(i);
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
- }
- else if(*(it - 1) - *it > 1)
- {
- for(uint16_t i = static_cast<uint16_t>(*(it - 1) + 1); i != static_cast<uint16_t>(*it); ++i)
- {
- icon_cursor_id_list.push_back(i);
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
-
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
- }
-
- uint32_t max_id = id_list.empty() ? 0 : *std::max_element(id_list.begin(), id_list.end());
- for(uint32_t i = static_cast<uint32_t>(icon_cursor_id_list.size()); i != count; ++i)
- icon_cursor_id_list.push_back(static_cast<uint16_t>(++max_id));
- }
- catch(const pe_exception&) //Entry not found
- {
- for(uint16_t i = 1; i != count + 1; ++i)
- icon_cursor_id_list.push_back(i);
- }
-
- return icon_cursor_id_list;
-}
-
-//Add cursor helper
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- //Check cursor for correctness
- if(cursor_file.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* cur_header = reinterpret_cast<const cursor_header*>(&cursor_file[0]);
-
- unsigned long size_of_headers = sizeof(cursor_header) + cur_header->Count * sizeof(cursordirentry);
- if(cursor_file.length() < size_of_headers || cur_header->Count == 0)
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Enumerate all cursors in file
- for(uint16_t i = 0; i != cur_header->Count; ++i)
- {
- //Check cursor entries
- const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
- if(cursor_entry->SizeInBytes == 0
- || cursor_entry->ImageOffset < size_of_headers
- || !pe_utils::is_sum_safe(cursor_entry->ImageOffset, cursor_entry->SizeInBytes)
- || cursor_entry->ImageOffset + cursor_entry->SizeInBytes > cursor_file.length())
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
- }
-
- std::string cursor_group_data;
- cursor_header* info = 0;
-
- if(group_cursor_info)
- {
- //If cursor group already exists
- {
- cursor_group_data = group_cursor_info->get_data();
- codepage = group_cursor_info->get_codepage(); //Don't change codepage of cursor group entry
- }
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Get cursor header
- info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]);
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header) + info->Count * sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- cursor_group_data.resize(sizeof(cursor_header) + (info->Count + cur_header->Count) * sizeof(cursor_group));
- info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]); //In case if memory was reallocated
- }
- else //Entry not found - cursor group doesn't exist
- {
- cursor_group_data.resize(sizeof(cursor_header) + cur_header->Count * sizeof(cursor_group));
- memcpy(&cursor_group_data[0], cur_header, sizeof(cursor_header));
- }
-
- //Search for available cursor IDs
- std::vector<uint16_t> cursor_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_cursor, mode, cur_header->Count));
-
- //Enumerate all cursors in file
- for(uint16_t i = 0; i != cur_header->Count; ++i)
- {
- const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
- cursor_group group = {0};
-
- //Fill cursor resource header
- group.Height = cursor_entry->Height * 2;
- group.SizeInBytes = cursor_entry->SizeInBytes + 2 * sizeof(uint16_t) /* hotspot coordinates */;
- group.Width = cursor_entry->Width;
- group.Number = cursor_id_list.at(i);
-
- memcpy(&cursor_group_data[sizeof(cursor_header) + ((info ? info->Count : 0) + i) * sizeof(cursor_group)], &group, sizeof(group));
-
- //Add cursor to resources
- resource_directory_entry new_entry;
- new_entry.set_id(group.Number);
-
- //Fill resource data (two WORDs for hotspot of cursor, and cursor bitmap data)
- std::string cur_data;
- cur_data.resize(sizeof(uint16_t) * 2);
- memcpy(&cur_data[0], &cursor_entry->HotspotX, sizeof(uint16_t));
- memcpy(&cur_data[sizeof(uint16_t)], &cursor_entry->HotspotY, sizeof(uint16_t));
- cur_data.append(cursor_file.substr(cursor_entry->ImageOffset, cursor_entry->SizeInBytes));
-
- res_.add_resource(cur_data, pe_resource_viewer::resource_cursor, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
- }
-
- if(info)
- info->Count += cur_header->Count; //Increase cursor count, if we're adding cursor to existing group
-
- {
- //Add or replace cursor group data entry
- res_.add_resource(cursor_group_data, pe_resource_viewer::resource_cursor_group, new_cursor_group_entry, finder, language, codepage, timestamp);
- }
-}
-
-//Adds icon(s) from icon file data
-//timestamp will be used for directories that will be added
-//If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
-//(Codepage of icon group and icons will not be changed in this case)
-//icon_place_mode determines, how new icon(s) will be placed
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const std::wstring& icon_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_icon_group_entry;
- new_icon_group_entry.set_name(icon_group_name);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, uint32_t icon_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_icon_group_entry;
- new_icon_group_entry.set_id(icon_group_id);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_id), language, mode, codepage, timestamp);
-}
-
-//Adds cursor(s) from cursor file data
-//timestamp will be used for directories that will be added
-//If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
-//(Codepage of cursor group and cursors will not be changed in this case)
-//icon_place_mode determines, how new cursor(s) will be placed
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_cursor_group_entry;
- new_cursor_group_entry.set_name(cursor_group_name);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_cursor_group_entry;
- new_cursor_group_entry.set_id(cursor_group_id);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_id), language, mode, codepage, timestamp);
-}
-
-//Remove icon group helper
-void resource_cursor_icon_writer::remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language)
-{
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_data.data());
-
- uint16_t icon_count = info->Count;
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header) + icon_count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Remove icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- res_.remove_resource(pe_resource_viewer::resource_icon, group->Number, language);
- }
-}
-
-//Remove cursor group helper
-void resource_cursor_icon_writer::remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language)
-{
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Get icon header
- const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_data.data());
-
- uint16_t cursor_count = info->Count;
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header) + cursor_count * sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Remove icon data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(cursor_group_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- res_.remove_resource(pe_resource_viewer::resource_cursor, group->Number, language);
- }
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name).get_data();
- remove_cursors_from_cursor_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_name, language);
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(uint32_t cursor_group_id, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id).get_data();
- remove_cursors_from_cursor_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_id, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(const std::wstring& icon_group_name, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name).get_data();
- remove_icons_from_icon_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_name, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(uint32_t icon_group_id, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id).get_data();
- remove_icons_from_icon_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_id, language);
-}
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_writer.h b/tools/pe_bliss/resource_cursor_icon_writer.h
deleted file mode 100644
index e73ac6a093..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_writer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "stdint_defs.h"
-#include "pe_resource_manager.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_cursor_icon_writer
-{
-public:
- //Determines, how new icon(s) or cursor(s) will be placed
- enum icon_place_mode
- {
- icon_place_after_max_icon_id, //Icon(s) will be placed after all existing
- icon_place_free_ids //New icon(s) will take all free IDs between existing icons
- };
-
-public:
- resource_cursor_icon_writer(pe_resource_manager& res);
-
- //Removes icon group and all its icons by name/ID and language
- bool remove_icon_group(const std::wstring& icon_group_name, uint32_t language);
- bool remove_icon_group(uint32_t icon_group_id, uint32_t language);
-
- //Adds icon(s) from icon file data
- //timestamp will be used for directories that will be added
- //If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
- //(Codepage of icon group and icons will not be changed in this case)
- //icon_place_mode determines, how new icon(s) will be placed
- void add_icon(const std::string& icon_file,
- const std::wstring& icon_group_name,
- uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
- uint32_t codepage = 0, uint32_t timestamp = 0);
-
- void add_icon(const std::string& icon_file,
- uint32_t icon_group_id,
- uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
- uint32_t codepage = 0, uint32_t timestamp = 0);
-
- //Removes cursor group and all its cursors by name/ID and language
- bool remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language);
- bool remove_cursor_group(uint32_t cursor_group_id, uint32_t language);
-
- //Adds cursor(s) from cursor file data
- //timestamp will be used for directories that will be added
- //If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
- //(Codepage of cursor group and cursors will not be changed in this case)
- //icon_place_mode determines, how new cursor(s) will be placed
- void add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-private:
- pe_resource_manager& res_;
-
- //Add icon helper
- void add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-
- //Remove icon group helper
- void remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language);
-
- //Add cursor helper
- void add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-
- //Remove cursor group helper
- void remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language);
-
- //Returns free icon or cursor ID list depending on icon_place_mode
- const std::vector<uint16_t> get_icon_or_cursor_free_id_list(pe_resource_manager::resource_type type, icon_place_mode mode, uint32_t count);
-};
-}
diff --git a/tools/pe_bliss/resource_data_info.cpp b/tools/pe_bliss/resource_data_info.cpp
deleted file mode 100644
index 75bb060eae..0000000000
--- a/tools/pe_bliss/resource_data_info.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "resource_data_info.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-resource_data_info::resource_data_info(const std::string& data, uint32_t codepage)
- :data_(data), codepage_(codepage)
-{}
-
-//Constructor from data
-resource_data_info::resource_data_info(const resource_data_entry& data)
- :data_(data.get_data()), codepage_(data.get_codepage())
-{}
-
-//Returns resource data
-const std::string& resource_data_info::get_data() const
-{
- return data_;
-}
-
-//Returns resource codepage
-uint32_t resource_data_info::get_codepage() const
-{
- return codepage_;
-}
-}
diff --git a/tools/pe_bliss/resource_data_info.h b/tools/pe_bliss/resource_data_info.h
deleted file mode 100644
index e2275ebbf5..0000000000
--- a/tools/pe_bliss/resource_data_info.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class resource_data_entry;
-
-//Class representing resource data
-class resource_data_info
-{
-public:
- //Constructor from data
- resource_data_info(const std::string& data, uint32_t codepage);
- //Constructor from data
- explicit resource_data_info(const resource_data_entry& data);
-
- //Returns resource data
- const std::string& get_data() const;
- //Returns resource codepage
- uint32_t get_codepage() const;
-
-private:
- std::string data_;
- uint32_t codepage_;
-};
-}
diff --git a/tools/pe_bliss/resource_internal.h b/tools/pe_bliss/resource_internal.h
deleted file mode 100644
index 64a5bf3903..0000000000
--- a/tools/pe_bliss/resource_internal.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-
-#define U16TEXT(t) reinterpret_cast<const unicode16_t*>( t )
-
-#define StringFileInfo U16TEXT("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define SizeofStringFileInfo sizeof("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define VarFileInfo U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define Translation U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0")
-
-#define VarFileInfoAligned U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define TranslationAligned U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")
-#define SizeofVarFileInfoAligned sizeof("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define SizeofTranslationAligned sizeof("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")
diff --git a/tools/pe_bliss/resource_message_list_reader.cpp b/tools/pe_bliss/resource_message_list_reader.cpp
deleted file mode 100644
index f2ea142bee..0000000000
--- a/tools/pe_bliss/resource_message_list_reader.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "resource_message_list_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_message_list_reader::resource_message_list_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Helper function of parsing message list table
-const resource_message_list resource_message_list_reader::parse_message_list(const std::string& resource_data)
-{
- resource_message_list ret;
-
- //Check resource data length
- if(resource_data.length() < sizeof(message_resource_data))
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- const message_resource_data* message_data = reinterpret_cast<const message_resource_data*>(resource_data.data());
-
- //Check resource data length more carefully and some possible overflows
- if(message_data->NumberOfBlocks >= pe_utils::max_dword / sizeof(message_resource_block)
- || !pe_utils::is_sum_safe(message_data->NumberOfBlocks * sizeof(message_resource_block), sizeof(message_resource_data))
- || resource_data.length() < message_data->NumberOfBlocks * sizeof(message_resource_block) + sizeof(message_resource_data))
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Iterate over all message resource blocks
- for(unsigned long i = 0; i != message_data->NumberOfBlocks; ++i)
- {
- //Get block
- const message_resource_block* block =
- reinterpret_cast<const message_resource_block*>(resource_data.data() + sizeof(message_resource_data) - sizeof(message_resource_block) + sizeof(message_resource_block) * i);
-
- //Check resource data length and IDs
- if(resource_data.length() < block->OffsetToEntries || block->LowId > block->HighId)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- unsigned long current_pos = 0;
- static const unsigned long size_of_entry_headers = 4;
- //List all message resource entries in block
- for(uint32_t curr_id = block->LowId; curr_id <= block->HighId; curr_id++)
- {
- //Check resource data length and some possible overflows
- if(!pe_utils::is_sum_safe(block->OffsetToEntries, current_pos)
- || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, size_of_entry_headers)
- || resource_data.length() < block->OffsetToEntries + current_pos + size_of_entry_headers)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Get entry
- const message_resource_entry* entry = reinterpret_cast<const message_resource_entry*>(resource_data.data() + block->OffsetToEntries + current_pos);
-
- //Check resource data length and entry length and some possible overflows
- if(entry->Length < size_of_entry_headers
- || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, entry->Length)
- || resource_data.length() < block->OffsetToEntries + current_pos + entry->Length
- || entry->Length < size_of_entry_headers)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- if(entry->Flags & message_resource_unicode)
- {
- //If string is UNICODE
- //Check its length
- if(entry->Length % 2)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Add ID and string to message table
-#ifdef PE_BLISS_WINDOWS
- ret.insert(std::make_pair(curr_id, message_table_item(
- std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
- (entry->Length - size_of_entry_headers) / 2)
- )));
-#else
- ret.insert(std::make_pair(curr_id, message_table_item(
- pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
- (entry->Length - size_of_entry_headers) / 2))
- )));
-#endif
- }
- else
- {
- //If string is ANSI
- //Add ID and string to message table
- ret.insert(std::make_pair(curr_id, message_table_item(
- std::string(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers,
- entry->Length - size_of_entry_headers)
- )));
- }
-
- //Go to next entry
- current_pos += entry->Length;
- }
- }
-
- return ret;
-}
-
-//Returns message table data by ID and index in language directory (instead of language)
-const resource_message_list resource_message_list_reader::get_message_table_by_id(uint32_t id, uint32_t index) const
-{
- return parse_message_list(res_.get_resource_data_by_id(pe_resource_viewer::resource_message_table, id, index).get_data());
-}
-
-//Returns message table data by ID and language
-const resource_message_list resource_message_list_reader::get_message_table_by_id_lang(uint32_t language, uint32_t id) const
-{
- return parse_message_list(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_message_table, id).get_data());
-}
-}
diff --git a/tools/pe_bliss/resource_message_list_reader.h b/tools/pe_bliss/resource_message_list_reader.h
deleted file mode 100644
index a0ac96eb8c..0000000000
--- a/tools/pe_bliss/resource_message_list_reader.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "message_table.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; message_table_item
-typedef std::map<uint32_t, message_table_item> resource_message_list;
-
-class resource_message_list_reader
-{
-public:
- resource_message_list_reader(const pe_resource_viewer& res);
-
- //Returns message table data by ID and language
- const resource_message_list get_message_table_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns message table data by ID and index in language directory (instead of language)
- const resource_message_list get_message_table_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Helper function of parsing message list table
- //resource_data - raw message table resource data
- static const resource_message_list parse_message_list(const std::string& resource_data);
-
-private:
- const pe_resource_viewer& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_string_table_reader.cpp b/tools/pe_bliss/resource_string_table_reader.cpp
deleted file mode 100644
index 8a51720e6a..0000000000
--- a/tools/pe_bliss/resource_string_table_reader.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "resource_string_table_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-resource_string_table_reader::resource_string_table_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns string table data by ID and index in language directory (instead of language)
-const resource_string_list resource_string_table_reader::get_string_table_by_id(uint32_t id, uint32_t index) const
-{
- return parse_string_list(id, res_.get_resource_data_by_id(pe_resource_viewer::resource_string, id, index).get_data());
-}
-
-//Returns string table data by ID and language
-const resource_string_list resource_string_table_reader::get_string_table_by_id_lang(uint32_t language, uint32_t id) const
-{
- return parse_string_list(id, res_.get_resource_data_by_id(language, pe_resource_viewer::resource_string, id).get_data());
-}
-
-//Helper function of parsing string list table
-const resource_string_list resource_string_table_reader::parse_string_list(uint32_t id, const std::string& resource_data)
-{
- resource_string_list ret;
-
- //16 is maximum count of strings in a string table
- static const unsigned long max_string_list_entries = 16;
- unsigned long passed_bytes = 0;
- for(unsigned long i = 0; i != max_string_list_entries; ++i)
- {
- //Check resource data length
- if(resource_data.length() < sizeof(uint16_t) + passed_bytes)
- throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
- //Get string length - the first WORD
- uint16_t string_length = *reinterpret_cast<const uint16_t*>(resource_data.data() + passed_bytes);
- passed_bytes += sizeof(uint16_t); //WORD containing string length
-
- //Check resource data length again
- if(resource_data.length() < string_length + passed_bytes)
- throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
- if(string_length)
- {
- //Create and save string (UNICODE)
-#ifdef PE_BLISS_WINDOWS
- ret.insert(
- std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
- std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + passed_bytes), string_length)));
-#else
- ret.insert(
- std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
- pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + passed_bytes), string_length))));
-#endif
- }
-
- //Go to next string
- passed_bytes += string_length * 2;
- }
-
- return ret;
-}
-
-//Returns string from string table by ID and language
-const std::wstring resource_string_table_reader::get_string_by_id_lang(uint32_t language, uint16_t id) const
-{
- //List strings by string table id and language
- const resource_string_list strings(get_string_table_by_id_lang(language, (id >> 4) + 1));
- resource_string_list::const_iterator it = strings.find(id); //Find string by id
- if(it == strings.end())
- throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
- return (*it).second;
-}
-
-//Returns string from string table by ID and index in language directory (instead of language)
-const std::wstring resource_string_table_reader::get_string_by_id(uint16_t id, uint32_t index) const
-{
- //List strings by string table id and index
- const resource_string_list strings(get_string_table_by_id((id >> 4) + 1, index));
- resource_string_list::const_iterator it = strings.find(id); //Find string by id
- if(it == strings.end())
- throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
- return (*it).second;
-}
-}
diff --git a/tools/pe_bliss/resource_string_table_reader.h b/tools/pe_bliss/resource_string_table_reader.h
deleted file mode 100644
index e3ded1da85..0000000000
--- a/tools/pe_bliss/resource_string_table_reader.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; string
-typedef std::map<uint16_t, std::wstring> resource_string_list;
-
-class resource_string_table_reader
-{
-public:
- resource_string_table_reader(const pe_resource_viewer& res);
-
-public:
- //Returns string table data by ID and language
- const resource_string_list get_string_table_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns string table data by ID and index in language directory (instead of language)
- const resource_string_list get_string_table_by_id(uint32_t id, uint32_t index = 0) const;
- //Returns string from string table by ID and language
- const std::wstring get_string_by_id_lang(uint32_t language, uint16_t id) const;
- //Returns string from string table by ID and index in language directory (instead of language)
- const std::wstring get_string_by_id(uint16_t id, uint32_t index = 0) const;
-
-private:
- const pe_resource_viewer& res_;
-
- //Helper function of parsing string list table
- //Id of resource is needed to calculate string IDs correctly
- //resource_data is raw string table resource data
- static const resource_string_list parse_string_list(uint32_t id, const std::string& resource_data);
-};
-}
diff --git a/tools/pe_bliss/resource_version_info_reader.cpp b/tools/pe_bliss/resource_version_info_reader.cpp
deleted file mode 100644
index 8ad44c6856..0000000000
--- a/tools/pe_bliss/resource_version_info_reader.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "resource_version_info_reader.h"
-#include "utils.h"
-#include "pe_exception.h"
-#include "resource_internal.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Root version info block key value
-const u16string resource_version_info_reader::version_info_key(U16TEXT("V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0"));
-
-resource_version_info_reader::resource_version_info_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns aligned version block value position
-uint32_t resource_version_info_reader::get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key)
-{
- uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
- uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
- + base_pos
- + (string_length + 1 /* nullbyte */) * 2),
- sizeof(uint32_t));
-
- //Check possible overflows
- if(ret < base_pos || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
- throw_incorrect_version_info();
-
- return ret;
-}
-
-//Returns aligned version block first child position
-uint32_t resource_version_info_reader::get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key)
-{
- uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
- uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
- + base_pos
- + (string_length + 1 /* nullbyte */) * 2),
- sizeof(uint32_t))
- + pe_utils::align_up(value_length, sizeof(uint32_t));
-
- //Check possible overflows
- if(ret < base_pos || ret < value_length || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
- throw_incorrect_version_info();
-
- return ret;
-}
-
-//Throws an exception (id = resource_incorrect_version_info)
-void resource_version_info_reader::throw_incorrect_version_info()
-{
- throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const
-{
- //Fixed file version info
- file_version_info ret;
-
- //Check resource data length
- if(resource_data.length() < sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Root version info block
- const version_info_block* root_block = reinterpret_cast<const version_info_block*>(resource_data.data());
-
- //Check root block key for null-termination and its name
- if(!pe_utils::is_null_terminated(root_block->Key, resource_data.length() - sizeof(uint16_t) * 3 /* headers before Key data */)
- || version_info_key != reinterpret_cast<const unicode16_t*>(root_block->Key))
- throw_incorrect_version_info();
-
- //If file has fixed version info
- if(root_block->ValueLength)
- {
- //Get root block value position
- uint32_t value_pos = get_version_block_value_pos(0, reinterpret_cast<const unicode16_t*>(root_block->Key));
- //Check value length
- if(resource_data.length() < value_pos + sizeof(vs_fixedfileinfo))
- throw_incorrect_version_info();
-
- //Get VS_FIXEDFILEINFO structure pointer
- const vs_fixedfileinfo* file_info = reinterpret_cast<const vs_fixedfileinfo*>(resource_data.data() + value_pos);
- //Check its signature and some other fields
- if(file_info->dwSignature != vs_ffi_signature || file_info->dwStrucVersion != vs_ffi_strucversion) //Don't check if file_info->dwFileFlagsMask == VS_FFI_FILEFLAGSMASK
- throw_incorrect_version_info();
-
- //Save fixed version info
- ret = file_version_info(*file_info);
- }
-
- //Iterate over child elements of VS_VERSIONINFO (StringFileInfo or VarFileInfo)
- for(uint32_t child_pos = get_version_block_first_child_pos(0, root_block->ValueLength, reinterpret_cast<const unicode16_t*>(root_block->Key));
- child_pos < root_block->Length;)
- {
- //Check block position
- if(!pe_utils::is_sum_safe(child_pos, sizeof(version_info_block))
- || resource_data.length() < child_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer
- const version_info_block* block = reinterpret_cast<const version_info_block*>(resource_data.data() + child_pos);
-
- //Check its length
- if(block->Length == 0)
- throw_incorrect_version_info();
-
- //Check block key for null-termination
- if(!pe_utils::is_null_terminated(block->Key, resource_data.length() - child_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- u16string info_type(reinterpret_cast<const unicode16_t*>(block->Key));
- //If we encountered StringFileInfo...
- if(info_type == StringFileInfo)
- {
- //Enumerate all string tables
- for(uint32_t string_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
- string_table_pos - child_pos < block->Length;)
- {
- //Check string table block position
- if(resource_data.length() < string_table_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for string table
- const version_info_block* string_table = reinterpret_cast<const version_info_block*>(resource_data.data() + string_table_pos);
-
- //Check its length
- if(string_table->Length == 0)
- throw_incorrect_version_info();
-
- //Check string table key for null-termination
- if(!pe_utils::is_null_terminated(string_table->Key, resource_data.length() - string_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- string_values_map new_values;
-
- //Enumerate all strings in the string table
- for(uint32_t string_pos = get_version_block_first_child_pos(string_table_pos, string_table->ValueLength, reinterpret_cast<const unicode16_t*>(string_table->Key));
- string_pos - string_table_pos < string_table->Length;)
- {
- //Check string block position
- if(resource_data.length() < string_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for string block
- const version_info_block* string_block = reinterpret_cast<const version_info_block*>(resource_data.data() + string_pos);
-
- //Check its length
- if(string_block->Length == 0)
- throw_incorrect_version_info();
-
- //Check string block key for null-termination
- if(!pe_utils::is_null_terminated(string_block->Key, resource_data.length() - string_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- u16string data;
- //If string block has value
- if(string_block->ValueLength != 0)
- {
- //Get value position
- uint32_t value_pos = get_version_block_value_pos(string_pos, reinterpret_cast<const unicode16_t*>(string_block->Key));
- //Check it
- if(resource_data.length() < value_pos + string_block->ValueLength)
- throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-
- //Get UNICODE string value
- data = u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + value_pos), string_block->ValueLength);
- pe_utils::strip_nullbytes(data);
- }
-
- //Save name-value pair
-#ifdef PE_BLISS_WINDOWS
- new_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_block->Key), data));
-#else
- new_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_block->Key)),
- pe_utils::from_ucs2(data)));
-#endif
-
- //Navigate to next string block
- string_pos += pe_utils::align_up(string_block->Length, sizeof(uint32_t));
- }
-
-#ifdef PE_BLISS_WINDOWS
- string_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_table->Key), new_values));
-#else
- string_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_table->Key)), new_values));
-#endif
-
- //Navigate to next string table block
- string_table_pos += pe_utils::align_up(string_table->Length, sizeof(uint32_t));
- }
- }
- else if(info_type == VarFileInfo) //If we encountered VarFileInfo
- {
- for(uint32_t var_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
- var_table_pos - child_pos < block->Length;)
- {
- //Check var block position
- if(resource_data.length() < var_table_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for var block
- const version_info_block* var_table = reinterpret_cast<const version_info_block*>(resource_data.data() + var_table_pos);
-
- //Check its length
- if(var_table->Length == 0)
- throw_incorrect_version_info();
-
- //Check its key for null-termination
- if(!pe_utils::is_null_terminated(var_table->Key, resource_data.length() - var_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- //If block is "Translation" (actually, there's no other types possible in VarFileInfo) and it has value
- if(u16string(reinterpret_cast<const unicode16_t*>(var_table->Key)) == Translation && var_table->ValueLength)
- {
- //Get its value position
- uint32_t value_pos = get_version_block_value_pos(var_table_pos, reinterpret_cast<const unicode16_t*>(var_table->Key));
- //Cherck value length
- if(resource_data.length() < value_pos + var_table->ValueLength)
- throw_incorrect_version_info();
-
- //Get list of translations: pairs of LANGUAGE_ID - CODEPAGE_ID
- for(unsigned long i = 0; i < var_table->ValueLength; i += sizeof(uint16_t) * 2)
- {
- //Pair of WORDs
- uint16_t lang_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + i);
- uint16_t codepage_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + sizeof(uint16_t) + i);
- //Save translation
- translations.insert(std::make_pair(lang_id, codepage_id));
- }
- }
-
- //Navigate to next var block
- var_table_pos += pe_utils::align_up(var_table->Length, sizeof(uint32_t));
- }
- }
- else
- {
- throw_incorrect_version_info();
- }
-
- //Navigate to next element in root block
- child_pos += pe_utils::align_up(block->Length, sizeof(uint32_t));
- }
-
- return ret;
-}
-
-//Returns full version information:
-//file_version info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const
-{
- const std::string& resource_data = res_.get_root_directory() //Type directory
- .entry_by_id(pe_resource_viewer::resource_version)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(1)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry() //Data directory
- .get_data();
-
- return get_version_info(string_values, translations, resource_data);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index) const
-{
- const resource_directory::entry_list& entries = res_.get_root_directory() //Type directory
- .entry_by_id(pe_resource_viewer::resource_version)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(1)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return get_version_info(string_values, translations, entries.at(index).get_data_entry().get_data()); //Data directory
-}
-}
diff --git a/tools/pe_bliss/resource_version_info_reader.h b/tools/pe_bliss/resource_version_info_reader.h
deleted file mode 100644
index c1dfbffdc2..0000000000
--- a/tools/pe_bliss/resource_version_info_reader.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include "file_version_info.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_version_info_reader
-{
-public: //VERSION INFO
- resource_version_info_reader(const pe_resource_viewer& res);
-
- //Returns full version information:
- //file_version_info: versions and file info
- //lang_lang_string_values_map: map of version info strings with encodings with encodings
- //translation_values_map: map of translations
- const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index = 0) const;
- const file_version_info get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const;
-
-public:
- //L"VS_VERSION_INFO" key of root version info block
- static const u16string version_info_key;
-
-private:
- const pe_resource_viewer& res_;
-
- //VERSION INFO helpers
- //Returns aligned version block value position
- static uint32_t get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key);
-
- //Returns aligned version block first child position
- static uint32_t get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key);
-
- //Returns full version information:
- //file_version_info: versions and file info
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const;
-
- //Throws an exception (id = resource_incorrect_version_info)
- static void throw_incorrect_version_info();
-};
-}
diff --git a/tools/pe_bliss/resource_version_info_writer.cpp b/tools/pe_bliss/resource_version_info_writer.cpp
deleted file mode 100644
index ed95a0f7ea..0000000000
--- a/tools/pe_bliss/resource_version_info_writer.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "resource_version_info_writer.h"
-#include "pe_structures.h"
-#include "resource_internal.h"
-#include "utils.h"
-#include "pe_resource_manager.h"
-#include "resource_version_info_reader.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_version_info_writer::resource_version_info_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Sets/replaces full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-void resource_version_info_writer::set_version_info(const file_version_info& file_info,
- const lang_string_values_map& string_values,
- const translation_values_map& translations,
- uint32_t language,
- uint32_t codepage,
- uint32_t timestamp)
-{
- std::string version_data;
-
- //Calculate total size of version resource data
- uint32_t total_version_info_length =
- static_cast<uint32_t>(sizeof(version_info_block) - sizeof(uint16_t) + sizeof(uint16_t) /* pading */
- + (resource_version_info_reader::version_info_key.length() + 1) * 2
- + sizeof(vs_fixedfileinfo));
-
- //If we have any strings values
- if(!string_values.empty())
- {
- total_version_info_length += sizeof(version_info_block) - sizeof(uint16_t); //StringFileInfo block
- total_version_info_length += SizeofStringFileInfo; //Name of block (key)
-
- //Add required size for version strings
- for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
- {
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*table_it).first.length() + 1) * 2), sizeof(uint32_t)); //Name of child block and block size (key of string table block)
-
- const string_values_map& values = (*table_it).second;
- for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
- {
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*it).first.length() + 1) * 2), sizeof(uint32_t));
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(((*it).second.length() + 1) * 2), sizeof(uint32_t));
- }
- }
- }
-
- //If we have translations
- if(!translations.empty())
- {
- total_version_info_length += (sizeof(version_info_block) - sizeof(uint16_t)) * 2; //VarFileInfo and Translation blocks
- total_version_info_length += SizeofVarFileInfoAligned; //DWORD-aligned VarFileInfo block name
- total_version_info_length += SizeofTranslationAligned; //DWORD-aligned Translation block name
- total_version_info_length += static_cast<uint32_t>(translations.size() * sizeof(uint16_t) * 2);
- }
-
- //Resize version data buffer
- version_data.resize(total_version_info_length);
-
- //Create root version block
- version_info_block root_block = {0};
- root_block.ValueLength = sizeof(vs_fixedfileinfo);
- root_block.Length = static_cast<uint16_t>(total_version_info_length);
-
- //Fill fixed file info
- vs_fixedfileinfo fixed_info = {0};
- fixed_info.dwFileDateLS = file_info.get_file_date_ls();
- fixed_info.dwFileDateMS = file_info.get_file_date_ms();
- fixed_info.dwFileFlags = file_info.get_file_flags();
- fixed_info.dwFileFlagsMask = vs_ffi_fileflagsmask;
- fixed_info.dwFileOS = file_info.get_file_os_raw();
- fixed_info.dwFileSubtype = file_info.get_file_subtype();
- fixed_info.dwFileType = file_info.get_file_type_raw();
- fixed_info.dwFileVersionLS = file_info.get_file_version_ls();
- fixed_info.dwFileVersionMS = file_info.get_file_version_ms();
- fixed_info.dwSignature = vs_ffi_signature;
- fixed_info.dwStrucVersion = vs_ffi_strucversion;
- fixed_info.dwProductVersionLS = file_info.get_product_version_ls();
- fixed_info.dwProductVersionMS = file_info.get_product_version_ms();
-
- //Write root block and fixed file info to buffer
- uint32_t data_ptr = 0;
- memcpy(&version_data[data_ptr], &root_block, sizeof(version_info_block) - sizeof(uint16_t));
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
- memcpy(&version_data[data_ptr], resource_version_info_reader::version_info_key.c_str(), (resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
- data_ptr += static_cast<uint32_t>((resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- memcpy(&version_data[data_ptr], &fixed_info, sizeof(fixed_info));
- data_ptr += sizeof(fixed_info);
-
- //Write string values, if any
- if(!string_values.empty())
- {
- //Create string file info root block
- version_info_block string_file_info_block = {0};
- string_file_info_block.Type = 1; //Block type is string
- memcpy(&version_data[data_ptr], &string_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* string_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr1 = data_ptr; //Used to calculate string file info block length later
- memcpy(&version_data[data_ptr], StringFileInfo, SizeofStringFileInfo); //Write block name
- data_ptr += SizeofStringFileInfo;
-
- //Create string table root block (child of string file info)
- version_info_block string_table_block = {0};
- string_table_block.Type = 1; //Block type is string
-
- for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
- {
- const string_values_map& values = (*table_it).second;
-
- memcpy(&version_data[data_ptr], &string_table_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* string_table_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr2 = data_ptr; //Used to calculate string table block length later
- uint32_t lang_key_length = static_cast<uint32_t>(((*table_it).first.length() + 1) * sizeof(uint16_t));
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*table_it).first.c_str(), lang_key_length); //Write block key
-#else
- {
- u16string str(pe_utils::to_ucs2((*table_it).first));
- memcpy(&version_data[data_ptr], str.c_str(), lang_key_length); //Write block key
- }
-#endif
-
- data_ptr += lang_key_length;
- //Align key if necessary
- if((sizeof(uint16_t) * 3 + lang_key_length) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
-
- //Create string block (child of string table block)
- version_info_block string_block = {0};
- string_block.Type = 1; //Block type is string
- for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
- {
- //Calculate value length and key length of string block
- string_block.ValueLength = static_cast<uint16_t>((*it).second.length() + 1);
- uint32_t key_length = static_cast<uint32_t>(((*it).first.length() + 1) * sizeof(uint16_t));
- //Calculate length of block
- string_block.Length = static_cast<uint16_t>(pe_utils::align_up(sizeof(uint16_t) * 3 + key_length, sizeof(uint32_t)) + string_block.ValueLength * sizeof(uint16_t));
-
- //Write string block
- memcpy(&version_data[data_ptr], &string_block, sizeof(version_info_block) - sizeof(uint16_t));
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*it).first.c_str(), key_length); //Write block key
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).first));
- memcpy(&version_data[data_ptr], str.c_str(), key_length); //Write block key
- }
-#endif
-
- data_ptr += key_length;
- //Align key if necessary
- if((sizeof(uint16_t) * 3 + key_length) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
-
- //Write block data (value)
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*it).second.c_str(), string_block.ValueLength * sizeof(uint16_t));
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).second));
- memcpy(&version_data[data_ptr], str.c_str(), string_block.ValueLength * sizeof(uint16_t));
- }
-#endif
-
- data_ptr += string_block.ValueLength * 2;
- //Align data if necessary
- if((string_block.ValueLength * 2) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
- }
-
- //Calculate string table and string file info blocks lengths
- string_table_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
- }
-
- string_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
- }
-
- //If we have transactions
- if(!translations.empty())
- {
- //Create root var file info block
- version_info_block var_file_info_block = {0};
- var_file_info_block.Type = 1; //Type of block is string
- //Write block header
- memcpy(&version_data[data_ptr], &var_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* var_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr1 = data_ptr; //Used to calculate var file info block length later
- memcpy(&version_data[data_ptr], VarFileInfoAligned, SizeofVarFileInfoAligned); //Write block key (aligned)
- data_ptr += SizeofVarFileInfoAligned;
-
- //Create root translation block (child of var file info block)
- version_info_block translation_block = {0};
- //Write block header
- memcpy(&version_data[data_ptr], &translation_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* translation_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr2 = data_ptr; //Used to calculate var file info block length later
- memcpy(&version_data[data_ptr], TranslationAligned, SizeofTranslationAligned); //Write block key (aligned)
- data_ptr += SizeofTranslationAligned;
-
- //Calculate translation block value length
- translation_block_ptr->ValueLength = static_cast<uint16_t>(sizeof(uint16_t) * 2 * translations.size());
-
- //Write translation values to block
- for(translation_values_map::const_iterator it = translations.begin(); it != translations.end(); ++it)
- {
- uint16_t lang_id = (*it).first; //Language ID
- uint16_t codepage_id = (*it).second; //Codepage ID
- memcpy(&version_data[data_ptr], &lang_id, sizeof(lang_id));
- data_ptr += sizeof(lang_id);
- memcpy(&version_data[data_ptr], &codepage_id, sizeof(codepage_id));
- data_ptr += sizeof(codepage_id);
- }
-
- //Calculate Translation and VarFileInfo blocks lengths
- translation_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
- var_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
- }
-
- //Add/replace version info resource
- res_.add_resource(version_data, pe_resource_viewer::resource_version, 1, language, codepage, timestamp);
-}
-
-//Removes version info by language (ID = 1)
-bool resource_version_info_writer::remove_version_info(uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_version, 1, language);
-}
-}
diff --git a/tools/pe_bliss/resource_version_info_writer.h b/tools/pe_bliss/resource_version_info_writer.h
deleted file mode 100644
index da279ddedb..0000000000
--- a/tools/pe_bliss/resource_version_info_writer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "file_version_info.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_version_info_writer
-{
-public:
- resource_version_info_writer(pe_resource_manager& res);
-
- //Sets/replaces full version information:
- //file_version_info: versions and file info
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- void set_version_info(const file_version_info& file_info,
- const lang_string_values_map& string_values,
- const translation_values_map& translations,
- uint32_t language,
- uint32_t codepage = 0,
- uint32_t timestamp = 0);
-
- //Removes version info by language (ID = 1)
- bool remove_version_info(uint32_t language);
-
-private:
- pe_resource_manager& res_;
-};
-}
diff --git a/tools/pe_bliss/stdint_defs.h b/tools/pe_bliss/stdint_defs.h
deleted file mode 100644
index bbc003690a..0000000000
--- a/tools/pe_bliss/stdint_defs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#ifdef _MSC_VER
-#if _MSC_VER < 1600
-namespace pe_bliss
-{
- //stdint.h definitions for MSVC 2008 and earlier, as
- //it doesn't have them
- typedef signed char int8_t;
- typedef short int16_t;
- typedef int int32_t;
-
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
- typedef unsigned int uint32_t;
-
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-}
-#else
-#include <stdint.h>
-#endif
-#else
-#include <stdint.h>
-#endif
diff --git a/tools/pe_bliss/utils.cpp b/tools/pe_bliss/utils.cpp
deleted file mode 100644
index e6a75d5497..0000000000
--- a/tools/pe_bliss/utils.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <string.h>
-#include "utils.h"
-#include "pe_exception.h"
-
-
-namespace pe_bliss
-{
-const double pe_utils::log_2 = 1.44269504088896340736; //instead of using M_LOG2E
-
-//Returns stream size
-std::streamoff pe_utils::get_file_size(std::istream& file)
-{
- //Get old istream offset
- std::streamoff old_offset = file.tellg();
- file.seekg(0, std::ios::end);
- std::streamoff filesize = file.tellg();
- //Set old istream offset
- file.seekg(old_offset);
- return filesize;
-}
-
-#ifndef PE_BLISS_WINDOWS
-const u16string pe_utils::to_ucs2(const std::wstring& str)
-{
- u16string ret;
- if(str.empty())
- return ret;
-
- int len = str.length();
-
- ret.resize(len);
-
- for(int i=0;i<len;i++) {
- ret[i]=str[i]&0xFFFF;
- }
-
- return ret;
-}
-
-const std::wstring pe_utils::from_ucs2(const u16string& str)
-{
- std::wstring ret;
- if(str.empty())
- return ret;
-
- int len = str.length();
- ret.resize(str.length());
-
- for(int i=0;i<len;i++) {
- ret[i]=str[i];
- }
-
- return ret;
-}
-#endif
-
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2)
-{
- return guid1.Data1 == guid2.Data1
- && guid1.Data2 == guid2.Data2
- && guid1.Data3 == guid2.Data3
- && !memcmp(guid1.Data4, guid2.Data4, sizeof(guid1.Data4));
-}
-}
diff --git a/tools/pe_bliss/utils.h b/tools/pe_bliss/utils.h
deleted file mode 100644
index 29125f8dc1..0000000000
--- a/tools/pe_bliss/utils.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include <string>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_utils
-{
-public:
- //Returns true if string "data" with maximum length "raw_length" is null-terminated
- template<typename T>
- static bool is_null_terminated(const T* data, size_t raw_length)
- {
- raw_length /= sizeof(T);
- for(size_t l = 0; l < raw_length; l++)
- {
- if(data[l] == static_cast<T>(L'\0'))
- return true;
- }
-
- return false;
- }
-
- //Helper template function to strip nullbytes in the end of string
- template<typename T>
- static void strip_nullbytes(std::basic_string<T>& str)
- {
- while(!*(str.end() - 1) && !str.empty())
- str.erase(str.length() - 1);
- }
-
- //Helper function to determine if number is power of 2
- template<typename T>
- static inline bool is_power_of_2(T x)
- {
- return !(x & (x - 1));
- }
-
- //Helper function to align number down
- template<typename T>
- static inline T align_down(T x, uint32_t align)
- {
- return x & ~(static_cast<T>(align) - 1);
- }
-
- //Helper function to align number up
- template<typename T>
- static inline T align_up(T x, uint32_t align)
- {
- return (x & static_cast<T>(align - 1)) ? align_down(x, align) + static_cast<T>(align) : x;
- }
-
- //Returns true if sum of two unsigned integers is safe (no overflow occurs)
- static inline bool is_sum_safe(uint32_t a, uint32_t b)
- {
- return a <= static_cast<uint32_t>(-1) - b;
- }
-
- //Two gigabytes value in bytes
- static const uint32_t two_gb = 0x80000000;
- static const uint32_t max_dword = 0xFFFFFFFF;
- static const uint32_t max_word = 0x0000FFFF;
- static const double log_2; //instead of using M_LOG2E
-
- //Returns stream size
- static std::streamoff get_file_size(std::istream& file);
-
-#ifndef PE_BLISS_WINDOWS
-public:
- static const u16string to_ucs2(const std::wstring& str);
- static const std::wstring from_ucs2(const u16string& str);
-#endif
-
-private:
- pe_utils();
- pe_utils(pe_utils&);
- pe_utils& operator=(const pe_utils&);
-};
-
-//Windows GUID comparison
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2);
-}
diff --git a/tools/pe_bliss/version_info_editor.cpp b/tools/pe_bliss/version_info_editor.cpp
deleted file mode 100644
index 199eebfd54..0000000000
--- a/tools/pe_bliss/version_info_editor.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <sstream>
-#include <iomanip>
-#include "version_info_types.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_editor::version_info_editor(lang_string_values_map& strings, translation_values_map& translations)
- :version_info_viewer(strings, translations),
- strings_edit_(strings),
- translations_edit_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Sets company name
-void version_info_editor::set_company_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"CompanyName", value, translation);
-}
-
-//Sets file description
-void version_info_editor::set_file_description(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"FileDescription", value, translation);
-}
-
-//Sets file version
-void version_info_editor::set_file_version(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"FileVersion", value, translation);
-}
-
-//Sets internal file name
-void version_info_editor::set_internal_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"InternalName", value, translation);
-}
-
-//Sets legal copyright
-void version_info_editor::set_legal_copyright(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"LegalCopyright", value, translation);
-}
-
-//Sets original file name
-void version_info_editor::set_original_filename(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"OriginalFilename", value, translation);
-}
-
-//Sets product name
-void version_info_editor::set_product_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"ProductName", value, translation);
-}
-
-//Sets product version
-void version_info_editor::set_product_version(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"ProductVersion", value, translation);
-}
-
-//Sets version info property value
-//property_name - property name
-//value - property value
-//If translation does not exist, it will be added
-//If property does not exist, it will be added
-void version_info_editor::set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation)
-{
- lang_string_values_map::iterator it = strings_edit_.begin();
-
- if(translation.empty())
- {
- //If no translation was specified
- it = strings_edit_.find(default_language_translation); //Find default translation table
- if(it == strings_edit_.end()) //If there's no default translation table, take the first one
- {
- it = strings_edit_.begin();
- if(it == strings_edit_.end()) //If there's no any translation table, add default one
- {
- it = strings_edit_.insert(std::make_pair(default_language_translation, string_values_map())).first;
- //Also add it to translations list
- add_translation(default_language_translation);
- }
- }
- }
- else
- {
- it = strings_edit_.find(translation); //Find specified translation table
- if(it == strings_edit_.end()) //If there's no translation, add it
- {
- it = strings_edit_.insert(std::make_pair(translation, string_values_map())).first;
- //Also add it to translations list
- add_translation(translation);
- }
- }
-
- //Change value of the required property
- ((*it).second)[property_name] = value;
-}
-
-//Adds translation to translation list
-void version_info_editor::add_translation(const std::wstring& translation)
-{
- std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
- add_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::add_translation(uint16_t language_id, uint16_t codepage_id)
-{
- std::pair<translation_values_map::const_iterator, translation_values_map::const_iterator>
- range(translations_edit_.equal_range(language_id));
-
- //If translation already exists
- for(translation_values_map::const_iterator it = range.first; it != range.second; ++it)
- {
- if((*it).second == codepage_id)
- return;
- }
-
- translations_edit_.insert(std::make_pair(language_id, codepage_id));
-}
-
-//Removes translation from translations and strings lists
-void version_info_editor::remove_translation(const std::wstring& translation)
-{
- std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
- remove_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::remove_translation(uint16_t language_id, uint16_t codepage_id)
-{
- {
- //Erase string table (if exists)
- std::wstringstream ss;
- ss << std::hex
- << std::setw(4) << std::setfill(L'0') << language_id
- << std::setw(4) << std::setfill(L'0') << codepage_id;
-
- strings_edit_.erase(ss.str());
- }
-
- //Find and erase translation from translations table
- std::pair<translation_values_map::iterator, translation_values_map::iterator>
- it_pair = translations_edit_.equal_range(language_id);
-
- for(translation_values_map::iterator it = it_pair.first; it != it_pair.second; ++it)
- {
- if((*it).second == codepage_id)
- {
- translations_edit_.erase(it);
- break;
- }
- }
-}
-}
diff --git a/tools/pe_bliss/version_info_editor.h b/tools/pe_bliss/version_info_editor.h
deleted file mode 100644
index 53d3dc62c1..0000000000
--- a/tools/pe_bliss/version_info_editor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
- //Helper class to read and edit version information
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- class version_info_editor : public version_info_viewer
- {
- public:
- //Default constructor
- //strings - version info strings with charsets
- //translations - version info translations map
- version_info_editor(lang_string_values_map& strings, translation_values_map& translations);
-
- //Below functions have parameter translation
- //If it's empty, the default language translation will be taken
- //If there's no default language translation, the first one will be taken
-
- //Sets company name
- void set_company_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets file description
- void set_file_description(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets file version
- void set_file_version(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets internal file name
- void set_internal_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets legal copyright
- void set_legal_copyright(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets original file name
- void set_original_filename(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets product name
- void set_product_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets product version
- void set_product_version(const std::wstring& value, const std::wstring& translation = std::wstring());
-
- //Sets version info property value
- //property_name - property name
- //value - property value
- //If translation does not exist, it will be added to strings and translations lists
- //If property does not exist, it will be added
- void set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation = std::wstring());
-
- //Adds translation to translation list
- void add_translation(const std::wstring& translation);
- void add_translation(uint16_t language_id, uint16_t codepage_id);
-
- //Removes translation from translations and strings lists
- void remove_translation(const std::wstring& translation);
- void remove_translation(uint16_t language_id, uint16_t codepage_id);
-
- private:
- lang_string_values_map& strings_edit_;
- translation_values_map& translations_edit_;
- };
-}
diff --git a/tools/pe_bliss/version_info_types.h b/tools/pe_bliss/version_info_types.h
deleted file mode 100644
index 6010c9691e..0000000000
--- a/tools/pe_bliss/version_info_types.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
- //Typedef for version info functions: Name - Value
- typedef std::map<std::wstring, std::wstring> string_values_map;
- //Typedef for version info functions: Language string - String Values Map
- //Language String consists of LangID and CharsetID
- //E.g. 041904b0 for Russian UNICODE, 040004b0 for Process Default Language UNICODE
- typedef std::map<std::wstring, string_values_map> lang_string_values_map;
-
- //Typedef for version info functions: Language - Character Set
- typedef std::multimap<uint16_t, uint16_t> translation_values_map;
-}
diff --git a/tools/pe_bliss/version_info_viewer.cpp b/tools/pe_bliss/version_info_viewer.cpp
deleted file mode 100644
index 6e2d0d5c5b..0000000000
--- a/tools/pe_bliss/version_info_viewer.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include <iomanip>
-#include <sstream>
-#include "pe_exception.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default process language, UNICODE
-const std::wstring version_info_viewer::default_language_translation(L"040904b0");
-
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_viewer::version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations)
- :strings_(strings), translations_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Returns company name
-const std::wstring version_info_viewer::get_company_name(const std::wstring& translation) const
-{
- return get_property(L"CompanyName", translation);
-}
-
-//Returns file description
-const std::wstring version_info_viewer::get_file_description(const std::wstring& translation) const
-{
- return get_property(L"FileDescription", translation);
-}
-
-//Returns file version
-const std::wstring version_info_viewer::get_file_version(const std::wstring& translation) const
-{
- return get_property(L"FileVersion", translation);
-}
-
-//Returns internal file name
-const std::wstring version_info_viewer::get_internal_name(const std::wstring& translation) const
-{
- return get_property(L"InternalName", translation);
-}
-
-//Returns legal copyright
-const std::wstring version_info_viewer::get_legal_copyright(const std::wstring& translation) const
-{
- return get_property(L"LegalCopyright", translation);
-}
-
-//Returns original file name
-const std::wstring version_info_viewer::get_original_filename(const std::wstring& translation) const
-{
- return get_property(L"OriginalFilename", translation);
-}
-
-//Returns product name
-const std::wstring version_info_viewer::get_product_name(const std::wstring& translation) const
-{
- return get_property(L"ProductName", translation);
-}
-
-//Returns product version
-const std::wstring version_info_viewer::get_product_version(const std::wstring& translation) const
-{
- return get_property(L"ProductVersion", translation);
-}
-
-//Returns list of translations in string representation
-const version_info_viewer::translation_list version_info_viewer::get_translation_list() const
-{
- translation_list ret;
-
- //Enumerate all translations
- for(translation_values_map::const_iterator it = translations_.begin(); it != translations_.end(); ++it)
- {
- //Create string representation of translation value
- std::wstringstream ss;
- ss << std::hex
- << std::setw(4) << std::setfill(L'0') << (*it).first
- << std::setw(4) << std::setfill(L'0') << (*it).second;
-
- //Save it
- ret.push_back(ss.str());
- }
-
- return ret;
-}
-
-//Returns version info property value
-//property_name - required property name
-//If throw_if_absent = true, will throw exception if property does not exist
-//If throw_if_absent = false, will return empty string if property does not exist
-const std::wstring version_info_viewer::get_property(const std::wstring& property_name, const std::wstring& translation, bool throw_if_absent) const
-{
- std::wstring ret;
-
- //If there're no strings
- if(strings_.empty())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
-
- lang_string_values_map::const_iterator it = strings_.begin();
-
- if(translation.empty())
- {
- //If no translation was specified
- it = strings_.find(default_language_translation); //Find default translation table
- if(it == strings_.end()) //If there's no default translation table, take the first one
- it = strings_.begin();
- }
- else
- {
- it = strings_.find(translation); //Find specified translation table
- if(it == strings_.end())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
- }
-
- //Find value of the required property
- string_values_map::const_iterator str_it = (*it).second.find(property_name);
-
- if(str_it == (*it).second.end())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
-
- ret = (*str_it).second;
-
- return ret;
-}
-
-//Converts translation HEX-string to pair of language ID and codepage ID
-const version_info_viewer::translation_pair version_info_viewer::translation_from_string(const std::wstring& translation)
-{
- uint32_t translation_id = 0;
-
- {
- //Convert string to DWORD
- std::wstringstream ss;
- ss << std::hex << translation;
- ss >> translation_id;
- }
-
- return std::make_pair(static_cast<uint16_t>(translation_id >> 16), static_cast<uint16_t>(translation_id & 0xFFFF));
-}
-}
diff --git a/tools/pe_bliss/version_info_viewer.h b/tools/pe_bliss/version_info_viewer.h
deleted file mode 100644
index bc2f6f2ba7..0000000000
--- a/tools/pe_bliss/version_info_viewer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* Permission is hereby granted, free of charge, to any person */
-/* obtaining a copy of this software and associated documentation */
-/* files (the "Software"), to deal in the Software without */
-/* restriction, including without limitation the rights to use, */
-/* copy, modify, merge, publish, distribute, sublicense, and/or */
-/* sell copies of the Software, and to permit persons to whom the */
-/* Software is furnished to do so, subject to the following conditions: */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <vector>
-#include <string>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-//Helper class to read version information
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-class version_info_viewer
-{
-public:
- //Useful typedefs
- typedef std::pair<uint16_t, uint16_t> translation_pair;
- typedef std::vector<std::wstring> translation_list;
-
-public:
- //Default constructor
- //strings - version info strings with charsets
- //translations - version info translations map
- version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations);
-
- //Below functions have parameter translation
- //If it's empty, the default language translation will be taken
- //If there's no default language translation, the first one will be taken
-
- //Returns company name
- const std::wstring get_company_name(const std::wstring& translation = std::wstring()) const;
- //Returns file description
- const std::wstring get_file_description(const std::wstring& translation = std::wstring()) const;
- //Returns file version
- const std::wstring get_file_version(const std::wstring& translation = std::wstring()) const;
- //Returns internal file name
- const std::wstring get_internal_name(const std::wstring& translation = std::wstring()) const;
- //Returns legal copyright
- const std::wstring get_legal_copyright(const std::wstring& translation = std::wstring()) const;
- //Returns original file name
- const std::wstring get_original_filename(const std::wstring& translation = std::wstring()) const;
- //Returns product name
- const std::wstring get_product_name(const std::wstring& translation = std::wstring()) const;
- //Returns product version
- const std::wstring get_product_version(const std::wstring& translation = std::wstring()) const;
-
- //Returns list of translations in string representation
- const translation_list get_translation_list() const;
-
- //Returns version info property value
- //property_name - required property name
- //If throw_if_absent = true, will throw exception if property does not exist
- //If throw_if_absent = false, will return empty string if property does not exist
- const std::wstring get_property(const std::wstring& property_name, const std::wstring& translation = std::wstring(), bool throw_if_absent = false) const;
-
- //Converts translation HEX-string to pair of language ID and codepage ID
- static const translation_pair translation_from_string(const std::wstring& translation);
-
-public:
- //Default process language, UNICODE
- static const std::wstring default_language_translation;
-
-private:
- const lang_string_values_map& strings_;
- const translation_values_map& translations_;
-};
-}