├── Makefile ├── README.md ├── pe_bliss_tests_vc10.sln ├── pe_bliss_tests_vc9.sln ├── pe_bliss_vc10.sln ├── pe_bliss_vc9.sln ├── pe_lib ├── Makefile ├── entropy.cpp ├── entropy.h ├── file_version_info.cpp ├── file_version_info.h ├── message_table.cpp ├── message_table.h ├── pe_base.cpp ├── pe_base.h ├── pe_bliss.h ├── pe_bliss_resources.h ├── pe_bound_import.cpp ├── pe_bound_import.h ├── pe_checksum.cpp ├── pe_checksum.h ├── pe_debug.cpp ├── pe_debug.h ├── pe_directory.cpp ├── pe_directory.h ├── pe_dotnet.cpp ├── pe_dotnet.h ├── pe_exception.cpp ├── pe_exception.h ├── pe_exception_directory.cpp ├── pe_exception_directory.h ├── pe_exports.cpp ├── pe_exports.h ├── pe_factory.cpp ├── pe_factory.h ├── pe_imports.cpp ├── pe_imports.h ├── pe_lib.vcproj ├── pe_lib.vcxproj ├── pe_lib.vcxproj.filters ├── pe_load_config.cpp ├── pe_load_config.h ├── pe_properties.cpp ├── pe_properties.h ├── pe_properties_generic.cpp ├── pe_properties_generic.h ├── pe_rebuilder.cpp ├── pe_rebuilder.h ├── pe_relocations.cpp ├── pe_relocations.h ├── pe_resource_manager.cpp ├── pe_resource_manager.h ├── pe_resource_viewer.cpp ├── pe_resource_viewer.h ├── pe_resources.cpp ├── pe_resources.h ├── pe_rich_data.cpp ├── pe_rich_data.h ├── pe_section.cpp ├── pe_section.h ├── pe_structures.h ├── pe_tls.cpp ├── pe_tls.h ├── readme.txt ├── resource_bitmap_reader.cpp ├── resource_bitmap_reader.h ├── resource_bitmap_writer.cpp ├── resource_bitmap_writer.h ├── resource_cursor_icon_reader.cpp ├── resource_cursor_icon_reader.h ├── resource_cursor_icon_writer.cpp ├── resource_cursor_icon_writer.h ├── resource_data_info.cpp ├── resource_data_info.h ├── resource_internal.h ├── resource_message_list_reader.cpp ├── resource_message_list_reader.h ├── resource_string_table_reader.cpp ├── resource_string_table_reader.h ├── resource_version_info_reader.cpp ├── resource_version_info_reader.h ├── resource_version_info_writer.cpp ├── resource_version_info_writer.h ├── stdint_defs.h ├── utils.cpp ├── utils.h ├── version_info_editor.cpp ├── version_info_editor.h ├── version_info_types.h ├── version_info_viewer.cpp └── version_info_viewer.h ├── samples ├── Makefile ├── address_convertions │ ├── Makefile │ ├── address_convertions.vcproj │ ├── address_convertions.vcxproj │ ├── address_convertions.vcxproj.filters │ └── main.cpp ├── basic_dotnet_viewer │ ├── Makefile │ ├── basic_dotnet_viewer.vcproj │ ├── basic_dotnet_viewer.vcxproj │ ├── basic_dotnet_viewer.vcxproj.filters │ └── main.cpp ├── basic_info_viewer │ ├── Makefile │ ├── basic_info_viewer.vcproj │ ├── basic_info_viewer.vcxproj │ ├── basic_info_viewer.vcxproj.filters │ └── main.cpp ├── bound_import_reader │ ├── Makefile │ ├── bound_import_reader.vcproj │ ├── bound_import_reader.vcxproj │ ├── bound_import_reader.vcxproj.filters │ └── main.cpp ├── debug_info_reader │ ├── Makefile │ ├── debug_info_reader.vcproj │ ├── debug_info_reader.vcxproj │ ├── debug_info_reader.vcxproj.filters │ └── main.cpp ├── entropy_calculator │ ├── Makefile │ ├── entropy_calculator.vcproj │ ├── entropy_calculator.vcxproj │ ├── entropy_calculator.vcxproj.filters │ └── main.cpp ├── exception_dir_reader │ ├── Makefile │ ├── exception_dir_reader.vcproj │ ├── exception_dir_reader.vcxproj │ ├── exception_dir_reader.vcxproj.filters │ └── main.cpp ├── export_adder │ ├── Makefile │ ├── export_adder.vcproj │ ├── export_adder.vcxproj │ ├── export_adder.vcxproj.filters │ └── main.cpp ├── exports_reader │ ├── Makefile │ ├── exports_reader.vcproj │ ├── exports_reader.vcxproj │ ├── exports_reader.vcxproj.filters │ └── main.cpp ├── full_pe_rebuilder │ ├── Makefile │ ├── full_pe_rebuilder.vcproj │ ├── full_pe_rebuilder.vcxproj │ ├── full_pe_rebuilder.vcxproj.filters │ └── main.cpp ├── image_config_editor │ ├── Makefile │ ├── image_config_editor.vcproj │ ├── image_config_editor.vcxproj │ ├── image_config_editor.vcxproj.filters │ └── main.cpp ├── import_adder │ ├── Makefile │ ├── import_adder.vcproj │ ├── import_adder.vcxproj │ ├── import_adder.vcxproj.filters │ └── main.cpp ├── imports_reader │ ├── Makefile │ ├── imports_reader.vcproj │ ├── imports_reader.vcxproj │ ├── imports_reader.vcxproj.filters │ └── main.cpp ├── lib.h ├── pe_config_reader │ ├── Makefile │ ├── main.cpp │ ├── pe_config_reader.vcproj │ ├── pe_config_reader.vcxproj │ └── pe_config_reader.vcxproj.filters ├── pe_realigner │ ├── Makefile │ ├── main.cpp │ ├── pe_realigner.vcproj │ ├── pe_realigner.vcxproj │ └── pe_realigner.vcxproj.filters ├── pe_rebaser │ ├── Makefile │ ├── main.cpp │ ├── pe_rebaser.vcproj │ ├── pe_rebaser.vcxproj │ └── pe_rebaser.vcxproj.filters ├── pe_sections_reader │ ├── Makefile │ ├── main.cpp │ ├── pe_sections_reader.vcproj │ ├── pe_sections_reader.vcxproj │ └── pe_sections_reader.vcxproj.filters ├── pe_stripper │ ├── Makefile │ ├── main.cpp │ ├── pe_stripper.vcproj │ ├── pe_stripper.vcxproj │ └── pe_stripper.vcxproj.filters ├── relocation_adder │ ├── Makefile │ ├── main.cpp │ ├── relocation_adder.vcproj │ ├── relocation_adder.vcxproj │ └── relocation_adder.vcxproj.filters ├── relocations_reader │ ├── Makefile │ ├── main.cpp │ ├── relocations_reader.vcproj │ ├── relocations_reader.vcxproj │ └── relocations_reader.vcxproj.filters ├── resource_editor │ ├── Makefile │ ├── main.cpp │ ├── resource.h │ ├── resource.rc │ ├── resource_editor.vcproj │ ├── resource_editor.vcxproj │ ├── resource_editor.vcxproj.filters │ └── wxwin.ico ├── resource_viewer │ ├── Makefile │ ├── main.cpp │ ├── resource_viewer.vcproj │ ├── resource_viewer.vcxproj │ └── resource_viewer.vcxproj.filters ├── rich_overlay_stub_reader │ ├── Makefile │ ├── main.cpp │ ├── rich_overlay_stub_reader.vcproj │ ├── rich_overlay_stub_reader.vcxproj │ └── rich_overlay_stub_reader.vcxproj.filters ├── sample.mak ├── section_adder │ ├── Makefile │ ├── main.cpp │ ├── section_adder.vcproj │ ├── section_adder.vcxproj │ └── section_adder.vcxproj.filters ├── sections_and_addresses │ ├── Makefile │ ├── main.cpp │ ├── sections_and_addresses.vcproj │ ├── sections_and_addresses.vcxproj │ └── sections_and_addresses.vcxproj.filters ├── tls_editor │ ├── Makefile │ ├── main.cpp │ ├── tls_editor.vcproj │ ├── tls_editor.vcxproj │ └── tls_editor.vcxproj.filters └── tls_reader │ ├── Makefile │ ├── main.cpp │ ├── tls_reader.vcproj │ ├── tls_reader.vcxproj │ └── tls_reader.vcxproj.filters └── tests ├── Makefile ├── lib.h ├── pe_files ├── TestApp.exe ├── bound32.exe ├── bound64.exe ├── debug_test.exe ├── image32.exe ├── image64.exe ├── message_table_resource.exe ├── test_dll_32.dll └── test_dll_64.dll ├── test.h ├── test_bound_import ├── Makefile ├── main.cpp ├── test_bound_import.vcproj ├── test_bound_import.vcxproj └── test_bound_import.vcxproj.filters ├── test_checksum ├── Makefile ├── main.cpp ├── test_checksum.vcproj ├── test_checksum.vcxproj └── test_checksum.vcxproj.filters ├── test_debug ├── Makefile ├── main.cpp ├── test_debug.vcproj ├── test_debug.vcxproj └── test_debug.vcxproj.filters ├── test_dotnet ├── Makefile ├── main.cpp ├── test_dotnet.vcproj ├── test_dotnet.vcxproj └── test_dotnet.vcxproj.filters ├── test_entropy ├── Makefile ├── main.cpp ├── test_entropy.vcproj ├── test_entropy.vcxproj └── test_entropy.vcxproj.filters ├── test_exception_directory ├── Makefile ├── main.cpp ├── test_exception_directory.vcproj ├── test_exception_directory.vcxproj └── test_exception_directory.vcxproj.filters ├── test_exports ├── Makefile ├── main.cpp ├── test_exports.vcproj ├── test_exports.vcxproj └── test_exports.vcxproj.filters ├── test_imports ├── Makefile ├── main.cpp ├── test_imports.vcproj ├── test_imports.vcxproj └── test_imports.vcxproj.filters ├── test_load_config ├── Makefile ├── main.cpp ├── test_load_config.vcproj ├── test_load_config.vcxproj └── test_load_config.vcxproj.filters ├── test_relocations ├── Makefile ├── main.cpp ├── test_relocations.vcproj ├── test_relocations.vcxproj └── test_relocations.vcxproj.filters ├── test_resource_bitmap ├── Makefile ├── main.cpp ├── test_resource_bitmap.vcproj ├── test_resource_bitmap.vcxproj └── test_resource_bitmap.vcxproj.filters ├── test_resource_icon_cursor ├── Makefile ├── main.cpp ├── test_resource_icon_cursor.vcproj ├── test_resource_icon_cursor.vcxproj └── test_resource_icon_cursor.vcxproj.filters ├── test_resource_manager ├── Makefile ├── main.cpp ├── test_resource_manager.vcproj ├── test_resource_manager.vcxproj └── test_resource_manager.vcxproj.filters ├── test_resource_message_table ├── Makefile ├── main.cpp ├── test_resource_message_table.vcproj ├── test_resource_message_table.vcxproj └── test_resource_message_table.vcxproj.filters ├── test_resource_string_table ├── Makefile ├── main.cpp ├── test_resource_string_table.vcproj ├── test_resource_string_table.vcxproj └── test_resource_string_table.vcxproj.filters ├── test_resource_version_info ├── Makefile ├── main.cpp ├── test_resource_version_info.vcproj ├── test_resource_version_info.vcxproj └── test_resource_version_info.vcxproj.filters ├── test_resource_viewer ├── Makefile ├── main.cpp ├── test_resource_viewer.vcproj ├── test_resource_viewer.vcxproj └── test_resource_viewer.vcxproj.filters ├── test_resources ├── Makefile ├── main.cpp ├── test_resources.vcproj ├── test_resources.vcxproj └── test_resources.vcxproj.filters ├── test_rich_data ├── Makefile ├── main.cpp ├── test_rich_data.vcproj ├── test_rich_data.vcxproj └── test_rich_data.vcxproj.filters ├── test_runner ├── Makefile ├── main.cpp ├── test_runner.vcproj ├── test_runner.vcxproj └── test_runner.vcxproj.filters ├── test_tls ├── Makefile ├── main.cpp ├── test_tls.vcproj ├── test_tls.vcxproj └── test_tls.vcxproj.filters ├── tests.mak ├── tests_basic ├── Makefile ├── main.cpp ├── tests_basic.vcproj ├── tests_basic.vcxproj └── tests_basic.vcxproj.filters └── tests_utils ├── Makefile ├── main.cpp ├── tests_utils.vcproj ├── tests_utils.vcxproj └── tests_utils.vcxproj.filters /Makefile: -------------------------------------------------------------------------------- 1 | TARGETS = pe_bliss samples_pack tests_pack 2 | TARGETS_CLEAN = pe_clean samples_clean tests_clean 3 | 4 | all: $(TARGETS) 5 | 6 | clean: $(TARGETS_CLEAN) 7 | 8 | pe_bliss: 9 | $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./pe_lib 10 | 11 | samples_pack: pe_bliss 12 | $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./samples 13 | 14 | pe_clean: 15 | $(MAKE) -C ./pe_lib clean 16 | 17 | samples_clean: 18 | $(MAKE) -C ./samples clean 19 | 20 | tests_pack: pe_bliss 21 | $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./tests 22 | 23 | tests_clean: 24 | $(MAKE) -C ./tests clean 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PE Bliss # 2 | 3 | ### Cross-Platform Portable Executable C++ Library ### 4 | 5 | Compatible with Windows and Linux (tested on MSVC++ 2008, 2010, GCC 4.4 on Linux). Currently tested on little-endian systems only and might not support big-endian ones. 6 | 7 | Library has many usage samples and is well unit-tested. 8 | 9 | _Library is free to use in both commertial and non-commertial projects. You can also modify and redistribute it. If you are using it, please, do not forget to specify the name or other copyright of PE Bliss somewhere in the description of your project._ 10 | 11 | 12 | 13 | --- 14 | 15 | 16 | **A huge update is coming soon!** Possible new features of the future update: 17 | 18 | * more high-level classes and functions to work with PE resources; 19 | 20 | * high-level .NET PE parsing (metadata tables, signatures, resources); 21 | 22 | * C++/CLI wrapper, which allows .NET developers to use the library in C# or VB.NET projects; 23 | 24 | * more samples and tests; 25 | 26 | * bugfixes. 27 | 28 | 29 | 30 | --- 31 | 32 | 33 | **Current version: 1.0.0** 34 | 35 | ### Summary ### 36 | 37 | [+] Read 32- and 64-bit PE files (PE, PE+) for Windows, work similar with both formats 38 | 39 | [+] Create PE/PE+ binaries from scratch 40 | 41 | [+] Rebuild 32- and 64-bit PE files 42 | 43 | [+] Work with directories and headers 44 | 45 | [+] Convert addresses 46 | 47 | [+] Read and write PE sections 48 | 49 | [+] Read and write imports 50 | 51 | [+] Read and write exports (forwarders supported) 52 | 53 | [+] Read and write relocations 54 | 55 | [+] Read and write resources 56 | 57 | [+] Read and write TLS (including callbacks and raw data) 58 | 59 | [+] Read and write image config (including SE Handlers and Lock Prefix addresses) 60 | 61 | [+] Read basic .NET information 62 | 63 | [+] Read and write bound imports 64 | 65 | [+] Read exception directory (PE+ only) 66 | 67 | [+] Read debug directory and extended debug information 68 | 69 | [+] Calculate entropy 70 | 71 | [+] Change file alignment 72 | 73 | [+] Change base address 74 | 75 | [+] Work with DOS Stub and Rich overlay 76 | 77 | [+] High-level resource reading: bitmaps, icons, cursors, version info, string and message tables 78 | 79 | [+] High-level resource editing: bitmaps, icons, cursors, version info 80 | 81 | 82 | 83 | Library doesn't use WinAPI and doesn't execute PE files, so it's safe to use it with suspicious binaries. 84 | 85 | 86 | 87 | --- 88 | 89 | [Author's blog](http://kaimi.ru/) 90 | -------------------------------------------------------------------------------- /pe_lib/Makefile: -------------------------------------------------------------------------------- 1 | OBJS = entropy.o file_version_info.o message_table.o pe_base.o pe_bound_import.o pe_checksum.o pe_debug.o pe_directory.o pe_dotnet.o pe_exception_directory.o pe_exports.o pe_imports.o pe_load_config.o pe_properties.o pe_properties_generic.o pe_relocations.o pe_factory.o pe_resources.o pe_resource_manager.o pe_resource_viewer.o pe_rich_data.o pe_section.o pe_tls.o utils.o version_info_editor.o version_info_viewer.o pe_exception.o resource_message_list_reader.o resource_string_table_reader.o resource_version_info_reader.o resource_version_info_writer.o resource_cursor_icon_reader.o resource_cursor_icon_writer.o resource_bitmap_writer.o resource_bitmap_reader.o resource_data_info.o pe_rebuilder.o 2 | LIBNAME = pebliss 3 | LIBPATH = ../lib 4 | CXXFLAGS = -O2 -Wall -fPIC -DPIC -I. 5 | 6 | ifdef PE_DEBUG 7 | CXXFLAGS += -g -O0 8 | endif 9 | 10 | all: $(LIBPATH)/lib$(LIBNAME).a 11 | 12 | clean: 13 | rm -f $(OBJS) lib$(LIBNAME).a 14 | rm -rf ../lib 15 | 16 | lib$(LIBNAME).a: $(OBJS) 17 | ar -cvr lib$(LIBNAME).a $(OBJS) 18 | ranlib lib$(LIBNAME).a 19 | 20 | $(LIBPATH): 21 | mkdir -p ../lib 22 | 23 | $(LIBPATH)/lib$(LIBNAME).a: lib$(LIBNAME).a $(LIBPATH) 24 | cp -d lib$(LIBNAME).a ../lib 25 | -------------------------------------------------------------------------------- /pe_lib/entropy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "entropy.h" 3 | #include "utils.h" 4 | 5 | namespace pe_bliss 6 | { 7 | //Calculates entropy for PE image section 8 | double entropy_calculator::calculate_entropy(const section& s) 9 | { 10 | if(s.get_raw_data().empty()) //Don't count entropy for empty sections 11 | throw pe_exception("Section is empty", pe_exception::section_is_empty); 12 | 13 | return calculate_entropy(s.get_raw_data().data(), s.get_raw_data().length()); 14 | } 15 | 16 | //Calculates entropy for istream (from current position of stream) 17 | double entropy_calculator::calculate_entropy(std::istream& file) 18 | { 19 | uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes 20 | 21 | if(file.bad()) 22 | throw pe_exception("Stream is bad", pe_exception::stream_is_bad); 23 | 24 | std::streamoff pos = file.tellg(); 25 | 26 | std::streamoff length = pe_utils::get_file_size(file); 27 | length -= file.tellg(); 28 | 29 | if(!length) //Don't calculate entropy for empty buffers 30 | throw pe_exception("Data length is zero", pe_exception::data_is_empty); 31 | 32 | //Count bytes 33 | for(std::streamoff i = 0; i != length; ++i) 34 | ++byte_count[static_cast(file.get())]; 35 | 36 | file.seekg(pos); 37 | 38 | return calculate_entropy(byte_count, length); 39 | } 40 | 41 | //Calculates entropy for data block 42 | double entropy_calculator::calculate_entropy(const char* data, size_t length) 43 | { 44 | uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes 45 | 46 | if(!length) //Don't calculate entropy for empty buffers 47 | throw pe_exception("Data length is zero", pe_exception::data_is_empty); 48 | 49 | //Count bytes 50 | for(size_t i = 0; i != length; ++i) 51 | ++byte_count[static_cast(data[i])]; 52 | 53 | return calculate_entropy(byte_count, length); 54 | } 55 | 56 | //Calculates entropy for this PE file (only section data) 57 | double entropy_calculator::calculate_entropy(const pe_base& pe) 58 | { 59 | uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes 60 | 61 | size_t total_data_length = 0; 62 | 63 | //Count bytes for each section 64 | for(section_list::const_iterator it = pe.get_image_sections().begin(); it != pe.get_image_sections().end(); ++it) 65 | { 66 | const std::string& data = (*it).get_raw_data(); 67 | size_t length = data.length(); 68 | total_data_length += length; 69 | for(size_t i = 0; i != length; ++i) 70 | ++byte_count[static_cast(data[i])]; 71 | } 72 | 73 | return calculate_entropy(byte_count, total_data_length); 74 | } 75 | 76 | //Calculates entropy from bytes count 77 | double entropy_calculator::calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length) 78 | { 79 | double entropy = 0.; //Entropy result value 80 | //Calculate entropy 81 | for(uint32_t i = 0; i < 256; ++i) 82 | { 83 | double temp = static_cast(byte_count[i]) / total_length; 84 | if(temp > 0.) 85 | entropy += std::abs(temp * (std::log(temp) * pe_utils::log_2)); 86 | } 87 | 88 | return entropy; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /pe_lib/entropy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "pe_base.h" 4 | 5 | namespace pe_bliss 6 | { 7 | class entropy_calculator 8 | { 9 | public: 10 | //Calculates entropy for PE image section 11 | static double calculate_entropy(const section& s); 12 | 13 | //Calculates entropy for istream (from current position of stream) 14 | static double calculate_entropy(std::istream& file); 15 | 16 | //Calculates entropy for data block 17 | static double calculate_entropy(const char* data, size_t length); 18 | 19 | //Calculates entropy for this PE file (only section data) 20 | static double calculate_entropy(const pe_base& pe); 21 | 22 | private: 23 | entropy_calculator(); 24 | entropy_calculator(const entropy_calculator&); 25 | entropy_calculator& operator=(const entropy_calculator&); 26 | 27 | //Calculates entropy from bytes count 28 | static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length); 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /pe_lib/message_table.cpp: -------------------------------------------------------------------------------- 1 | #include "message_table.h" 2 | #include "utils.h" 3 | 4 | namespace pe_bliss 5 | { 6 | //Default constructor 7 | message_table_item::message_table_item() 8 | :unicode_(false) 9 | {} 10 | 11 | //Constructor from ANSI string 12 | message_table_item::message_table_item(const std::string& str) 13 | :unicode_(false), ansi_str_(str) 14 | { 15 | pe_utils::strip_nullbytes(ansi_str_); 16 | } 17 | 18 | //Constructor from UNICODE string 19 | message_table_item::message_table_item(const std::wstring& str) 20 | :unicode_(true), unicode_str_(str) 21 | { 22 | pe_utils::strip_nullbytes(unicode_str_); 23 | } 24 | 25 | //Returns true if contained string is unicode 26 | bool message_table_item::is_unicode() const 27 | { 28 | return unicode_; 29 | } 30 | 31 | //Returns ANSI string 32 | const std::string& message_table_item::get_ansi_string() const 33 | { 34 | return ansi_str_; 35 | } 36 | 37 | //Returns UNICODE string 38 | const std::wstring& message_table_item::get_unicode_string() const 39 | { 40 | return unicode_str_; 41 | } 42 | 43 | //Sets ANSI string (clears UNICODE one) 44 | void message_table_item::set_string(const std::string& str) 45 | { 46 | ansi_str_ = str; 47 | pe_utils::strip_nullbytes(ansi_str_); 48 | unicode_str_.clear(); 49 | unicode_ = false; 50 | } 51 | 52 | //Sets UNICODE string (clears ANSI one) 53 | void message_table_item::set_string(const std::wstring& str) 54 | { 55 | unicode_str_ = str; 56 | pe_utils::strip_nullbytes(unicode_str_); 57 | ansi_str_.clear(); 58 | unicode_ = true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pe_lib/message_table.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "stdint_defs.h" 5 | 6 | namespace pe_bliss 7 | { 8 | //Structure representing message table string 9 | class message_table_item 10 | { 11 | public: 12 | //Default constructor 13 | message_table_item(); 14 | //Constructors from ANSI and UNICODE strings 15 | explicit message_table_item(const std::string& str); 16 | explicit message_table_item(const std::wstring& str); 17 | 18 | //Returns true if string is UNICODE 19 | bool is_unicode() const; 20 | //Returns ANSI string 21 | const std::string& get_ansi_string() const; 22 | //Returns UNICODE string 23 | const std::wstring& get_unicode_string() const; 24 | 25 | public: 26 | //Sets ANSI or UNICODE string 27 | void set_string(const std::string& str); 28 | void set_string(const std::wstring& str); 29 | 30 | private: 31 | bool unicode_; 32 | std::string ansi_str_; 33 | std::wstring unicode_str_; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /pe_lib/pe_bliss.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pe_base.h" 3 | #include "pe_rebuilder.h" 4 | #include "pe_factory.h" 5 | #include "pe_bound_import.h" 6 | #include "pe_debug.h" 7 | #include "pe_dotnet.h" 8 | #include "pe_exception_directory.h" 9 | #include "pe_exports.h" 10 | #include "pe_imports.h" 11 | #include "pe_load_config.h" 12 | #include "pe_relocations.h" 13 | #include "pe_resources.h" 14 | #include "pe_rich_data.h" 15 | #include "pe_tls.h" 16 | #include "pe_properties_generic.h" 17 | #include "pe_checksum.h" 18 | #include "entropy.h" 19 | -------------------------------------------------------------------------------- /pe_lib/pe_bliss_resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "file_version_info.h" 3 | #include "message_table.h" 4 | #include "pe_resource_manager.h" 5 | #include "pe_resource_viewer.h" 6 | #include "version_info_editor.h" 7 | #include "version_info_viewer.h" 8 | #include "resource_bitmap_reader.h" 9 | #include "resource_bitmap_writer.h" 10 | #include "resource_cursor_icon_reader.h" 11 | #include "resource_cursor_icon_writer.h" 12 | #include "resource_version_info_reader.h" 13 | #include "resource_version_info_writer.h" 14 | #include "resource_string_table_reader.h" 15 | #include "resource_message_list_reader.h" 16 | -------------------------------------------------------------------------------- /pe_lib/pe_bound_import.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "pe_structures.h" 5 | #include "pe_base.h" 6 | #include "pe_directory.h" 7 | 8 | namespace pe_bliss 9 | { 10 | //Class representing bound import reference 11 | class bound_import_ref 12 | { 13 | public: 14 | //Default constructor 15 | bound_import_ref(); 16 | //Constructor from data 17 | bound_import_ref(const std::string& module_name, uint32_t timestamp); 18 | 19 | //Returns imported module name 20 | const std::string& get_module_name() const; 21 | //Returns bound import date and time stamp 22 | uint32_t get_timestamp() const; 23 | 24 | public: //Setters 25 | //Sets module name 26 | void set_module_name(const std::string& module_name); 27 | //Sets timestamp 28 | void set_timestamp(uint32_t timestamp); 29 | 30 | private: 31 | std::string module_name_; //Imported module name 32 | uint32_t timestamp_; //Bound import timestamp 33 | }; 34 | 35 | //Class representing image bound import information 36 | class bound_import 37 | { 38 | public: 39 | typedef std::vector ref_list; 40 | 41 | public: 42 | //Default constructor 43 | bound_import(); 44 | //Constructor from data 45 | bound_import(const std::string& module_name, uint32_t timestamp); 46 | 47 | //Returns imported module name 48 | const std::string& get_module_name() const; 49 | //Returns bound import date and time stamp 50 | uint32_t get_timestamp() const; 51 | 52 | //Returns bound references cound 53 | size_t get_module_ref_count() const; 54 | //Returns module references 55 | const ref_list& get_module_ref_list() const; 56 | 57 | public: //Setters 58 | //Sets module name 59 | void set_module_name(const std::string& module_name); 60 | //Sets timestamp 61 | void set_timestamp(uint32_t timestamp); 62 | 63 | //Adds module reference 64 | void add_module_ref(const bound_import_ref& ref); 65 | //Clears module references list 66 | void clear_module_refs(); 67 | //Returns module references 68 | ref_list& get_module_ref_list(); 69 | 70 | private: 71 | std::string module_name_; //Imported module name 72 | uint32_t timestamp_; //Bound import timestamp 73 | ref_list refs_; //Module references list 74 | }; 75 | 76 | typedef std::vector bound_import_module_list; 77 | 78 | //Returns bound import information 79 | const bound_import_module_list get_bound_import_module_list(const pe_base& pe);//Export directory rebuilder 80 | 81 | //imports - bound imported modules list 82 | //imports_section - section where export directory will be placed (must be attached to PE image) 83 | //offset_from_section_start - offset from imports_section raw data start 84 | //save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers 85 | //auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped 86 | 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); 87 | } 88 | -------------------------------------------------------------------------------- /pe_lib/pe_checksum.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_checksum.h" 2 | #include "pe_structures.h" 3 | #include "pe_base.h" 4 | 5 | namespace pe_bliss 6 | { 7 | using namespace pe_win; 8 | 9 | //Calculate checksum of image 10 | uint32_t calculate_checksum(std::istream& file) 11 | { 12 | //Save istream state 13 | std::ios_base::iostate state = file.exceptions(); 14 | std::streamoff old_offset = file.tellg(); 15 | 16 | //Checksum value 17 | unsigned long long checksum = 0; 18 | 19 | try 20 | { 21 | image_dos_header header; 22 | 23 | file.exceptions(std::ios::goodbit); 24 | 25 | //Read DOS header 26 | pe_base::read_dos_header(file, header); 27 | 28 | //Calculate PE checksum 29 | file.seekg(0); 30 | unsigned long long top = 0xFFFFFFFF; 31 | top++; 32 | 33 | //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ 34 | static const unsigned long checksum_pos_in_optional_headers = 64; 35 | //Calculate real PE headers "CheckSum" field position 36 | //Sum is safe here 37 | unsigned long pe_checksum_pos = header.e_lfanew + sizeof(image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers; 38 | 39 | //Calculate checksum for each byte of file 40 | std::streamoff filesize = pe_utils::get_file_size(file); 41 | for(long long i = 0; i < filesize; i += 4) 42 | { 43 | unsigned long dw = 0; 44 | 45 | //Read DWORD from file 46 | file.read(reinterpret_cast(&dw), sizeof(unsigned long)); 47 | //Skip "CheckSum" DWORD 48 | if(i == pe_checksum_pos) 49 | continue; 50 | 51 | //Calculate checksum 52 | checksum = (checksum & 0xffffffff) + dw + (checksum >> 32); 53 | if(checksum > top) 54 | checksum = (checksum & 0xffffffff) + (checksum >> 32); 55 | } 56 | 57 | //Finish checksum 58 | checksum = (checksum & 0xffff) + (checksum >> 16); 59 | checksum = (checksum) + (checksum >> 16); 60 | checksum = checksum & 0xffff; 61 | 62 | checksum += static_cast(filesize); 63 | } 64 | catch(const std::exception&) 65 | { 66 | //If something went wrong, restore istream state 67 | file.exceptions(state); 68 | file.seekg(old_offset); 69 | file.clear(); 70 | //Rethrow 71 | throw; 72 | } 73 | 74 | //Restore istream state 75 | file.exceptions(state); 76 | file.seekg(old_offset); 77 | file.clear(); 78 | 79 | //Return checksum 80 | return static_cast(checksum); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /pe_lib/pe_checksum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "stdint_defs.h" 4 | 5 | namespace pe_bliss 6 | { 7 | //Calculate checksum of image (performs no checks on PE structures) 8 | uint32_t calculate_checksum(std::istream& file); 9 | } 10 | -------------------------------------------------------------------------------- /pe_lib/pe_directory.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_directory.h" 2 | 3 | namespace pe_bliss 4 | { 5 | //Default constructor 6 | image_directory::image_directory() 7 | :rva_(0), size_(0) 8 | {} 9 | 10 | //Constructor from data 11 | image_directory::image_directory(uint32_t rva, uint32_t size) 12 | :rva_(rva), size_(size) 13 | {} 14 | 15 | //Returns RVA 16 | uint32_t image_directory::get_rva() const 17 | { 18 | return rva_; 19 | } 20 | 21 | //Returns size 22 | uint32_t image_directory::get_size() const 23 | { 24 | return size_; 25 | } 26 | 27 | //Sets RVA 28 | void image_directory::set_rva(uint32_t rva) 29 | { 30 | rva_ = rva; 31 | } 32 | 33 | //Sets size 34 | void image_directory::set_size(uint32_t size) 35 | { 36 | size_ = size; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pe_lib/pe_directory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdint_defs.h" 3 | 4 | namespace pe_bliss 5 | { 6 | //Class representing image directory data 7 | class image_directory 8 | { 9 | public: 10 | //Default constructor 11 | image_directory(); 12 | //Constructor from data 13 | image_directory(uint32_t rva, uint32_t size); 14 | 15 | //Returns RVA 16 | uint32_t get_rva() const; 17 | //Returns size 18 | uint32_t get_size() const; 19 | 20 | //Sets RVA 21 | void set_rva(uint32_t rva); 22 | //Sets size 23 | void set_size(uint32_t size); 24 | 25 | private: 26 | uint32_t rva_; 27 | uint32_t size_; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /pe_lib/pe_dotnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pe_structures.h" 3 | #include "pe_base.h" 4 | 5 | namespace pe_bliss 6 | { 7 | //Class representing basic .NET header information 8 | class basic_dotnet_info 9 | { 10 | public: 11 | //Default constructor 12 | basic_dotnet_info(); 13 | //Constructor from data 14 | explicit basic_dotnet_info(const pe_win::image_cor20_header& header); 15 | 16 | //Returns major runtime version 17 | uint16_t get_major_runtime_version() const; 18 | //Returns minor runtime version 19 | uint16_t get_minor_runtime_version() const; 20 | 21 | //Returns RVA of metadata (symbol table and startup information) 22 | uint32_t get_rva_of_metadata() const; 23 | //Returns size of metadata (symbol table and startup information) 24 | uint32_t get_size_of_metadata() const; 25 | 26 | //Returns flags 27 | uint32_t get_flags() const; 28 | 29 | //Returns true if entry point is native 30 | bool is_native_entry_point() const; 31 | //Returns true if 32 bit required 32 | bool is_32bit_required() const; 33 | //Returns true if image is IL library 34 | bool is_il_library() const; 35 | //Returns true if image uses IL only 36 | bool is_il_only() const; 37 | 38 | //Returns entry point RVA (if entry point is native) 39 | //Returns entry point managed token (if entry point is managed) 40 | uint32_t get_entry_point_rva_or_token() const; 41 | 42 | //Returns RVA of managed resources 43 | uint32_t get_rva_of_resources() const; 44 | //Returns size of managed resources 45 | uint32_t get_size_of_resources() const; 46 | //Returns RVA of strong name signature 47 | uint32_t get_rva_of_strong_name_signature() const; 48 | //Returns size of strong name signature 49 | uint32_t get_size_of_strong_name_signature() const; 50 | //Returns RVA of code manager table 51 | uint32_t get_rva_of_code_manager_table() const; 52 | //Returns size of code manager table 53 | uint32_t get_size_of_code_manager_table() const; 54 | //Returns RVA of VTable fixups 55 | uint32_t get_rva_of_vtable_fixups() const; 56 | //Returns size of VTable fixups 57 | uint32_t get_size_of_vtable_fixups() const; 58 | //Returns RVA of export address table jumps 59 | uint32_t get_rva_of_export_address_table_jumps() const; 60 | //Returns size of export address table jumps 61 | uint32_t get_size_of_export_address_table_jumps() const; 62 | //Returns RVA of managed native header 63 | //(precompiled header info, usually set to zero, for internal use) 64 | uint32_t get_rva_of_managed_native_header() const; 65 | //Returns size of managed native header 66 | //(precompiled header info, usually set to zero, for internal use) 67 | uint32_t get_size_of_managed_native_header() const; 68 | 69 | private: 70 | pe_win::image_cor20_header header_; 71 | }; 72 | 73 | //Returns basic .NET information 74 | //If image is not native, throws an exception 75 | const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe); 76 | } 77 | -------------------------------------------------------------------------------- /pe_lib/pe_exception.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_exception.h" 2 | 3 | namespace pe_bliss 4 | { 5 | //PE exception class constructors 6 | pe_exception::pe_exception(const char* text, exception_id id) 7 | :std::runtime_error(text), id_(id) 8 | {} 9 | 10 | pe_exception::pe_exception(const std::string& text, exception_id id) 11 | :std::runtime_error(text), id_(id) 12 | {} 13 | 14 | //Returns exception ID 15 | pe_exception::exception_id pe_exception::get_id() const 16 | { 17 | return id_; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pe_lib/pe_exception.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace pe_bliss 6 | { 7 | //PE exception class 8 | class pe_exception : public std::runtime_error 9 | { 10 | public: 11 | //Exception IDs 12 | enum exception_id 13 | { 14 | unknown_error, 15 | bad_pe_file, 16 | bad_dos_header, 17 | image_nt_headers_not_found, 18 | error_reading_image_nt_headers, 19 | error_reading_data_directories, 20 | error_reading_file, 21 | pe_signature_incorrect, 22 | incorrect_number_of_rva_and_sizes, 23 | error_changing_section_virtual_size, 24 | section_number_incorrect, 25 | section_table_incorrect, 26 | incorrect_section_alignment, 27 | incorrect_file_alignment, 28 | incorrect_size_of_image, 29 | incorrect_size_of_headers, 30 | image_section_headers_not_found, 31 | zero_section_sizes, 32 | section_incorrect_addr_or_size, 33 | section_not_found, 34 | image_section_data_not_found, 35 | no_section_found, 36 | image_section_table_incorrect, 37 | directory_does_not_exist, 38 | rva_not_exists, 39 | error_reading_section_header, 40 | error_reading_overlay, 41 | incorrect_address_conversion, 42 | 43 | incorrect_export_directory, 44 | incorrect_import_directory, 45 | incorrect_relocation_directory, 46 | incorrect_tls_directory, 47 | incorrect_config_directory, 48 | incorrect_bound_import_directory, 49 | incorrect_resource_directory, 50 | incorrect_exception_directory, 51 | incorrect_debug_directory, 52 | 53 | resource_directory_entry_error, 54 | resource_directory_entry_not_found, 55 | resource_data_entry_not_found, 56 | resource_incorrect_bitmap, 57 | resource_incorrect_icon, 58 | resource_incorrect_cursor, 59 | resource_incorrect_string_table, 60 | resource_string_not_found, 61 | resource_incorrect_message_table, 62 | resource_incorrect_version_info, 63 | 64 | advanced_debug_information_request_error, 65 | image_does_not_have_managed_code, 66 | 67 | section_is_empty, 68 | data_is_empty, 69 | stream_is_bad, 70 | 71 | section_is_not_attached, 72 | insufficient_space, 73 | 74 | cannot_rebase_relocations, 75 | 76 | exports_list_is_empty, 77 | duplicate_exported_function_ordinal, 78 | duplicate_exported_function_name, 79 | 80 | version_info_string_does_not_exist, 81 | 82 | no_more_sections_can_be_added, 83 | 84 | no_icon_group_found, 85 | no_cursor_group_found, 86 | 87 | encoding_convertion_error, 88 | 89 | error_expanding_section, 90 | 91 | cannot_rebuild_image 92 | }; 93 | 94 | public: 95 | //Class constructors 96 | explicit pe_exception(const char* text, exception_id id = unknown_error); 97 | explicit pe_exception(const std::string& text, exception_id id = unknown_error); 98 | 99 | //Returns exception ID from exception_id enumeration 100 | exception_id get_id() const; 101 | 102 | //Destructor 103 | virtual ~pe_exception() throw() 104 | {} 105 | 106 | private: 107 | exception_id id_; 108 | }; 109 | } 110 | -------------------------------------------------------------------------------- /pe_lib/pe_exception_directory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "pe_structures.h" 4 | #include "pe_base.h" 5 | 6 | namespace pe_bliss 7 | { 8 | //Class representing exception directory entry 9 | class exception_entry 10 | { 11 | public: 12 | //Default constructor 13 | exception_entry(); 14 | //Constructor from data 15 | exception_entry(const pe_win::image_runtime_function_entry& entry, const pe_win::unwind_info& unwind_info); 16 | 17 | //Returns starting address of function, affected by exception unwinding 18 | uint32_t get_begin_address() const; 19 | //Returns ending address of function, affected by exception unwinding 20 | uint32_t get_end_address() const; 21 | //Returns unwind info address 22 | uint32_t get_unwind_info_address() const; 23 | 24 | //Returns UNWIND_INFO structure version 25 | uint8_t get_unwind_info_version() const; 26 | 27 | //Returns unwind info flags 28 | uint8_t get_flags() const; 29 | //The function has an exception handler that should be called 30 | //when looking for functions that need to examine exceptions 31 | bool has_exception_handler() const; 32 | //The function has a termination handler that should be called 33 | //when unwinding an exception 34 | bool has_termination_handler() const; 35 | //The unwind info structure is not the primary one for the procedure 36 | bool is_chaininfo() const; 37 | 38 | //Returns size of function prolog 39 | uint8_t get_size_of_prolog() const; 40 | 41 | //Returns number of unwind slots 42 | uint8_t get_number_of_unwind_slots() const; 43 | 44 | //If the function uses frame pointer 45 | bool uses_frame_pointer() const; 46 | //Number of the nonvolatile register used as the frame pointer, 47 | //using the same encoding for the operation info field of UNWIND_CODE nodes 48 | uint8_t get_frame_pointer_register_number() const; 49 | //The scaled offset from RSP that is applied to the FP reg when it is established. 50 | //The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240 51 | uint8_t get_scaled_rsp_offset() const; 52 | 53 | private: 54 | uint32_t begin_address_, end_address_, unwind_info_address_; 55 | uint8_t unwind_info_version_; 56 | uint8_t flags_; 57 | uint8_t size_of_prolog_; 58 | uint8_t count_of_codes_; 59 | uint8_t frame_register_, frame_offset_; 60 | }; 61 | 62 | typedef std::vector exception_entry_list; 63 | 64 | //Returns exception directory data (exists on PE+ only) 65 | //Unwind opcodes are not listed, because their format and list are subject to change 66 | const exception_entry_list get_exception_directory_data(const pe_base& pe); 67 | } 68 | -------------------------------------------------------------------------------- /pe_lib/pe_factory.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_factory.h" 2 | #include "pe_properties_generic.h" 3 | 4 | namespace pe_bliss 5 | { 6 | pe_base pe_factory::create_pe(std::istream& file, bool read_debug_raw_data) 7 | { 8 | return pe_base::get_pe_type(file) == pe_type_32 9 | ? pe_base(file, pe_properties_32(), read_debug_raw_data) 10 | : pe_base(file, pe_properties_64(), read_debug_raw_data); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /pe_lib/pe_factory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "pe_base.h" 5 | 6 | namespace pe_bliss 7 | { 8 | class pe_factory 9 | { 10 | public: 11 | //Creates pe_base class instance from PE or PE+ istream 12 | //If read_bound_import_raw_data, raw bound import data will be read (used to get bound import info) 13 | //If read_debug_raw_data, raw debug data will be read (used to get image debug info) 14 | static pe_base create_pe(std::istream& file, bool read_debug_raw_data = true); 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /pe_lib/pe_properties.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_properties.h" 2 | 3 | namespace pe_bliss 4 | { 5 | //Destructor 6 | pe_properties::~pe_properties() 7 | {} 8 | 9 | //Clears PE characteristics flag 10 | void pe_properties::clear_characteristics_flags(uint16_t flags) 11 | { 12 | set_characteristics(get_characteristics() & ~flags); 13 | } 14 | 15 | //Sets PE characteristics flag 16 | void pe_properties::set_characteristics_flags(uint16_t flags) 17 | { 18 | set_characteristics(get_characteristics() | flags); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pe_lib/pe_rebuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace pe_bliss 5 | { 6 | class pe_base; 7 | //Rebuilds PE image, writes resulting image to ostream "out". If strip_dos_header == true, DOS header will be stripped a little 8 | //If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically 9 | //If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers) 10 | 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); 11 | } 12 | -------------------------------------------------------------------------------- /pe_lib/pe_rich_data.cpp: -------------------------------------------------------------------------------- 1 | #include "pe_rich_data.h" 2 | 3 | namespace pe_bliss 4 | { 5 | //STUB OVERLAY 6 | //Default constructor 7 | rich_data::rich_data() 8 | :number_(0), version_(0), times_(0) 9 | {} 10 | 11 | //Who knows, what these fields mean... 12 | uint32_t rich_data::get_number() const 13 | { 14 | return number_; 15 | } 16 | 17 | uint32_t rich_data::get_version() const 18 | { 19 | return version_; 20 | } 21 | 22 | uint32_t rich_data::get_times() const 23 | { 24 | return times_; 25 | } 26 | 27 | void rich_data::set_number(uint32_t number) 28 | { 29 | number_ = number; 30 | } 31 | 32 | void rich_data::set_version(uint32_t version) 33 | { 34 | version_ = version; 35 | } 36 | 37 | void rich_data::set_times(uint32_t times) 38 | { 39 | times_ = times; 40 | } 41 | 42 | //Returns MSVC rich data 43 | const rich_data_list get_rich_data(const pe_base& pe) 44 | { 45 | //Returned value 46 | rich_data_list ret; 47 | 48 | const std::string& rich_overlay = pe.get_stub_overlay(); 49 | 50 | //If there's no rich overlay, return empty vector 51 | if(rich_overlay.size() < sizeof(uint32_t)) 52 | return ret; 53 | 54 | //True if rich data was found 55 | bool found = false; 56 | 57 | //Rich overlay ID ("Rich" word) 58 | static const uint32_t rich_overlay_id = 0x68636952; 59 | 60 | //Search for rich data overlay ID 61 | const char* begin = &rich_overlay[0]; 62 | const char* end = begin + rich_overlay.length(); 63 | for(; begin != end; ++begin) 64 | { 65 | if(*reinterpret_cast(begin) == rich_overlay_id) 66 | { 67 | found = true; //We've found it! 68 | break; 69 | } 70 | } 71 | 72 | //If we found it 73 | if(found) 74 | { 75 | //Check remaining length 76 | if(static_cast(end - begin) < sizeof(uint32_t)) 77 | return ret; 78 | 79 | //The XOR key is after "Rich" word, we should get it 80 | uint32_t xorkey = *reinterpret_cast(begin + sizeof(uint32_t)); 81 | 82 | //True if rich data was found 83 | found = false; 84 | 85 | //Second search for signature "DanS" 86 | begin = &rich_overlay[0]; 87 | for(; begin != end; ++begin) 88 | { 89 | if((*reinterpret_cast(begin) ^ xorkey) == 0x536e6144) //"DanS" 90 | { 91 | found = true; 92 | break; 93 | } 94 | } 95 | 96 | //If second signature is found 97 | if(found) 98 | { 99 | begin += sizeof(uint32_t) * 3; 100 | //List all rich data structures 101 | while(begin < end) 102 | { 103 | begin += sizeof(uint32_t); 104 | if(begin >= end) 105 | break; 106 | 107 | //Check for rich overlay data end ("Rich" word reached) 108 | if(*reinterpret_cast(begin) == rich_overlay_id) 109 | break; 110 | 111 | //Create rich_data structure 112 | rich_data data; 113 | data.set_number((*reinterpret_cast(begin) ^ xorkey) >> 16); 114 | data.set_version((*reinterpret_cast(begin) ^ xorkey) & 0xFFFF); 115 | 116 | begin += sizeof(uint32_t); 117 | if(begin >= end) 118 | break; 119 | 120 | data.set_times(*reinterpret_cast(begin) ^ xorkey); 121 | 122 | //Save rich data structure 123 | ret.push_back(data); 124 | } 125 | } 126 | } 127 | 128 | //Return rich data structures list 129 | return ret; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /pe_lib/pe_rich_data.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "pe_structures.h" 4 | #include "pe_base.h" 5 | 6 | namespace pe_bliss 7 | { 8 | //Rich data overlay class of Microsoft Visual Studio 9 | class rich_data 10 | { 11 | public: 12 | //Default constructor 13 | rich_data(); 14 | 15 | public: //Getters 16 | //Who knows, what these fields mean... 17 | uint32_t get_number() const; 18 | uint32_t get_version() const; 19 | uint32_t get_times() const; 20 | 21 | public: //Setters, used by PE library only 22 | void set_number(uint32_t number); 23 | void set_version(uint32_t version); 24 | void set_times(uint32_t times); 25 | 26 | private: 27 | uint32_t number_; 28 | uint32_t version_; 29 | uint32_t times_; 30 | }; 31 | 32 | //Rich data list typedef 33 | typedef std::vector rich_data_list; 34 | 35 | //Returns a vector with rich data (stub overlay) 36 | const rich_data_list get_rich_data(const pe_base& pe); 37 | } 38 | -------------------------------------------------------------------------------- /pe_lib/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/pe_lib/readme.txt -------------------------------------------------------------------------------- /pe_lib/resource_bitmap_reader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource_bitmap_reader.h" 3 | #include "pe_resource_viewer.h" 4 | #include "pe_structures.h" 5 | 6 | namespace pe_bliss 7 | { 8 | using namespace pe_win; 9 | 10 | resource_bitmap_reader::resource_bitmap_reader(const pe_resource_viewer& res) 11 | :res_(res) 12 | {} 13 | 14 | //Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness) 15 | const std::string resource_bitmap_reader::get_bitmap_by_name(const std::wstring& name, uint32_t index) const 16 | { 17 | return create_bitmap(res_.get_resource_data_by_name(pe_resource_viewer::resource_bitmap, name, index).get_data()); 18 | } 19 | 20 | //Returns bitmap data by name and language (minimum checks of format correctness) 21 | const std::string resource_bitmap_reader::get_bitmap_by_name(uint32_t language, const std::wstring& name) const 22 | { 23 | return create_bitmap(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_bitmap, name).get_data()); 24 | } 25 | 26 | //Returns bitmap data by ID and language (minimum checks of format correctness) 27 | const std::string resource_bitmap_reader::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const 28 | { 29 | return create_bitmap(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_bitmap, id).get_data()); 30 | } 31 | 32 | //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness) 33 | const std::string resource_bitmap_reader::get_bitmap_by_id(uint32_t id, uint32_t index) const 34 | { 35 | return create_bitmap(res_.get_resource_data_by_id(pe_resource_viewer::resource_bitmap, id, index).get_data()); 36 | } 37 | 38 | //Helper function of creating bitmap header 39 | const std::string resource_bitmap_reader::create_bitmap(const std::string& resource_data) 40 | { 41 | //Create bitmap file header 42 | bitmapfileheader header = {0}; 43 | header.bfType = 0x4d42; //Signature "BM" 44 | header.bfOffBits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader); //Offset to bitmap bits 45 | header.bfSize = static_cast(sizeof(bitmapfileheader) + resource_data.length()); //Size of bitmap 46 | 47 | //Check size of resource data 48 | if(resource_data.length() < sizeof(bitmapinfoheader)) 49 | throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); 50 | 51 | { 52 | //Get bitmap info header 53 | const bitmapinfoheader* info = reinterpret_cast(resource_data.data()); 54 | 55 | //If color table is present, skip it 56 | if(info->biClrUsed != 0) 57 | header.bfOffBits += 4 * info->biClrUsed; //Add this size to offset to bitmap bits 58 | else if(info->biBitCount <= 8) 59 | header.bfOffBits += 4 * static_cast(std::pow(2.f, info->biBitCount)); //Add this size to offset to bitmap bits 60 | } 61 | 62 | //Return final bitmap data 63 | return std::string(reinterpret_cast(&header), sizeof(bitmapfileheader)) + resource_data; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /pe_lib/resource_bitmap_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "stdint_defs.h" 4 | 5 | namespace pe_bliss 6 | { 7 | class pe_resource_viewer; 8 | 9 | class resource_bitmap_reader 10 | { 11 | public: 12 | resource_bitmap_reader(const pe_resource_viewer& res); 13 | 14 | //Returns bitmap data by name and language (minimum checks of format correctness) 15 | const std::string get_bitmap_by_name(uint32_t language, const std::wstring& name) const; 16 | //Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness) 17 | const std::string get_bitmap_by_name(const std::wstring& name, uint32_t index = 0) const; 18 | //Returns bitmap data by ID and language (minimum checks of format correctness) 19 | const std::string get_bitmap_by_id_lang(uint32_t language, uint32_t id) const; 20 | //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness) 21 | const std::string get_bitmap_by_id(uint32_t id, uint32_t index = 0) const; 22 | 23 | private: 24 | //Helper function of creating bitmap header 25 | static const std::string create_bitmap(const std::string& resource_data); 26 | 27 | const pe_resource_viewer& res_; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /pe_lib/resource_bitmap_writer.cpp: -------------------------------------------------------------------------------- 1 | #include "resource_bitmap_writer.h" 2 | #include "pe_resource_manager.h" 3 | #include "pe_structures.h" 4 | 5 | namespace pe_bliss 6 | { 7 | using namespace pe_win; 8 | 9 | resource_bitmap_writer::resource_bitmap_writer(pe_resource_manager& res) 10 | :res_(res) 11 | {} 12 | 13 | //Adds bitmap from bitmap file data. If bitmap already exists, replaces it 14 | //timestamp will be used for directories that will be added 15 | void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp) 16 | { 17 | //Check bitmap data a little 18 | if(bitmap_file.length() < sizeof(bitmapfileheader)) 19 | throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); 20 | 21 | resource_directory_entry new_entry; 22 | new_entry.set_id(id); 23 | 24 | //Add bitmap 25 | res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp); 26 | } 27 | 28 | //Adds bitmap from bitmap file data. If bitmap already exists, replaces it 29 | //timestamp will be used for directories that will be added 30 | void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp) 31 | { 32 | //Check bitmap data a little 33 | if(bitmap_file.length() < sizeof(bitmapfileheader)) 34 | throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); 35 | 36 | resource_directory_entry new_entry; 37 | new_entry.set_name(name); 38 | 39 | //Add bitmap 40 | res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp); 41 | } 42 | 43 | //Removes bitmap by name/ID and language 44 | bool resource_bitmap_writer::remove_bitmap(const std::wstring& name, uint32_t language) 45 | { 46 | return res_.remove_resource(pe_resource_viewer::resource_bitmap, name, language); 47 | } 48 | 49 | //Removes bitmap by name/ID and language 50 | bool resource_bitmap_writer::remove_bitmap(uint32_t id, uint32_t language) 51 | { 52 | return res_.remove_resource(pe_resource_viewer::resource_bitmap, id, language); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pe_lib/resource_bitmap_writer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "stdint_defs.h" 4 | 5 | namespace pe_bliss 6 | { 7 | class pe_resource_manager; 8 | 9 | class resource_bitmap_writer 10 | { 11 | public: 12 | resource_bitmap_writer(pe_resource_manager& res); 13 | 14 | //Adds bitmap from bitmap file data. If bitmap already exists, replaces it 15 | //timestamp will be used for directories that will be added 16 | void add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); 17 | void add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); 18 | 19 | //Removes bitmap by name/ID and language 20 | bool remove_bitmap(const std::wstring& name, uint32_t language); 21 | bool remove_bitmap(uint32_t id, uint32_t language); 22 | 23 | private: 24 | pe_resource_manager& res_; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /pe_lib/resource_data_info.cpp: -------------------------------------------------------------------------------- 1 | #include "resource_data_info.h" 2 | #include "pe_resource_viewer.h" 3 | 4 | namespace pe_bliss 5 | { 6 | //Default constructor 7 | resource_data_info::resource_data_info(const std::string& data, uint32_t codepage) 8 | :data_(data), codepage_(codepage) 9 | {} 10 | 11 | //Constructor from data 12 | resource_data_info::resource_data_info(const resource_data_entry& data) 13 | :data_(data.get_data()), codepage_(data.get_codepage()) 14 | {} 15 | 16 | //Returns resource data 17 | const std::string& resource_data_info::get_data() const 18 | { 19 | return data_; 20 | } 21 | 22 | //Returns resource codepage 23 | uint32_t resource_data_info::get_codepage() const 24 | { 25 | return codepage_; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pe_lib/resource_data_info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "stdint_defs.h" 4 | 5 | namespace pe_bliss 6 | { 7 | class resource_data_entry; 8 | 9 | //Class representing resource data 10 | class resource_data_info 11 | { 12 | public: 13 | //Constructor from data 14 | resource_data_info(const std::string& data, uint32_t codepage); 15 | //Constructor from data 16 | explicit resource_data_info(const resource_data_entry& data); 17 | 18 | //Returns resource data 19 | const std::string& get_data() const; 20 | //Returns resource codepage 21 | uint32_t get_codepage() const; 22 | 23 | private: 24 | std::string data_; 25 | uint32_t codepage_; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /pe_lib/resource_internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define U16TEXT(t) reinterpret_cast( t ) 4 | 5 | #define StringFileInfo U16TEXT("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0") 6 | #define SizeofStringFileInfo sizeof("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0") 7 | #define VarFileInfo U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0") 8 | #define Translation U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0") 9 | 10 | #define VarFileInfoAligned U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0") 11 | #define TranslationAligned U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0") 12 | #define SizeofVarFileInfoAligned sizeof("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0") 13 | #define SizeofTranslationAligned sizeof("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0") 14 | -------------------------------------------------------------------------------- /pe_lib/resource_message_list_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "message_table.h" 3 | 4 | namespace pe_bliss 5 | { 6 | class pe_resource_viewer; 7 | 8 | //ID; message_table_item 9 | typedef std::map resource_message_list; 10 | 11 | class resource_message_list_reader 12 | { 13 | public: 14 | resource_message_list_reader(const pe_resource_viewer& res); 15 | 16 | //Returns message table data by ID and language 17 | const resource_message_list get_message_table_by_id_lang(uint32_t language, uint32_t id) const; 18 | //Returns message table data by ID and index in language directory (instead of language) 19 | const resource_message_list get_message_table_by_id(uint32_t id, uint32_t index = 0) const; 20 | 21 | //Helper function of parsing message list table 22 | //resource_data - raw message table resource data 23 | static const resource_message_list parse_message_list(const std::string& resource_data); 24 | 25 | private: 26 | const pe_resource_viewer& res_; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /pe_lib/resource_string_table_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "stdint_defs.h" 5 | 6 | namespace pe_bliss 7 | { 8 | class pe_resource_viewer; 9 | 10 | //ID; string 11 | typedef std::map resource_string_list; 12 | 13 | class resource_string_table_reader 14 | { 15 | public: 16 | resource_string_table_reader(const pe_resource_viewer& res); 17 | 18 | public: 19 | //Returns string table data by ID and language 20 | const resource_string_list get_string_table_by_id_lang(uint32_t language, uint32_t id) const; 21 | //Returns string table data by ID and index in language directory (instead of language) 22 | const resource_string_list get_string_table_by_id(uint32_t id, uint32_t index = 0) const; 23 | //Returns string from string table by ID and language 24 | const std::wstring get_string_by_id_lang(uint32_t language, uint16_t id) const; 25 | //Returns string from string table by ID and index in language directory (instead of language) 26 | const std::wstring get_string_by_id(uint16_t id, uint32_t index = 0) const; 27 | 28 | private: 29 | const pe_resource_viewer& res_; 30 | 31 | //Helper function of parsing string list table 32 | //Id of resource is needed to calculate string IDs correctly 33 | //resource_data is raw string table resource data 34 | static const resource_string_list parse_string_list(uint32_t id, const std::string& resource_data); 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /pe_lib/resource_version_info_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "file_version_info.h" 4 | #include "pe_structures.h" 5 | #include "version_info_types.h" 6 | 7 | namespace pe_bliss 8 | { 9 | class pe_resource_viewer; 10 | 11 | class resource_version_info_reader 12 | { 13 | public: //VERSION INFO 14 | resource_version_info_reader(const pe_resource_viewer& res); 15 | 16 | //Returns full version information: 17 | //file_version_info: versions and file info 18 | //lang_lang_string_values_map: map of version info strings with encodings with encodings 19 | //translation_values_map: map of translations 20 | const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index = 0) const; 21 | const file_version_info get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const; 22 | 23 | public: 24 | //L"VS_VERSION_INFO" key of root version info block 25 | static const u16string version_info_key; 26 | 27 | private: 28 | const pe_resource_viewer& res_; 29 | 30 | //VERSION INFO helpers 31 | //Returns aligned version block value position 32 | static uint32_t get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key); 33 | 34 | //Returns aligned version block first child position 35 | static uint32_t get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key); 36 | 37 | //Returns full version information: 38 | //file_version_info: versions and file info 39 | //lang_string_values_map: map of version info strings with encodings 40 | //translation_values_map: map of translations 41 | const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const; 42 | 43 | //Throws an exception (id = resource_incorrect_version_info) 44 | static void throw_incorrect_version_info(); 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /pe_lib/resource_version_info_writer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "version_info_types.h" 3 | #include "file_version_info.h" 4 | 5 | namespace pe_bliss 6 | { 7 | class pe_resource_manager; 8 | 9 | class resource_version_info_writer 10 | { 11 | public: 12 | resource_version_info_writer(pe_resource_manager& res); 13 | 14 | //Sets/replaces full version information: 15 | //file_version_info: versions and file info 16 | //lang_string_values_map: map of version info strings with encodings 17 | //translation_values_map: map of translations 18 | void set_version_info(const file_version_info& file_info, 19 | const lang_string_values_map& string_values, 20 | const translation_values_map& translations, 21 | uint32_t language, 22 | uint32_t codepage = 0, 23 | uint32_t timestamp = 0); 24 | 25 | //Removes version info by language (ID = 1) 26 | bool remove_version_info(uint32_t language); 27 | 28 | private: 29 | pe_resource_manager& res_; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /pe_lib/stdint_defs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef _MSC_VER 3 | #if _MSC_VER < 1600 4 | namespace pe_bliss 5 | { 6 | //stdint.h definitions for MSVC 2008 and earlier, as 7 | //it doesn't have them 8 | typedef signed char int8_t; 9 | typedef short int16_t; 10 | typedef int int32_t; 11 | 12 | typedef unsigned char uint8_t; 13 | typedef unsigned short uint16_t; 14 | typedef unsigned int uint32_t; 15 | 16 | typedef long long int64_t; 17 | typedef unsigned long long uint64_t; 18 | } 19 | #else 20 | #include 21 | #endif 22 | #else 23 | #include 24 | #endif 25 | -------------------------------------------------------------------------------- /pe_lib/utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | #include "pe_exception.h" 4 | 5 | #ifndef PE_BLISS_WINDOWS 6 | #include 7 | #endif 8 | 9 | namespace pe_bliss 10 | { 11 | const double pe_utils::log_2 = 1.44269504088896340736; //instead of using M_LOG2E 12 | 13 | //Returns stream size 14 | std::streamoff pe_utils::get_file_size(std::istream& file) 15 | { 16 | //Get old istream offset 17 | std::streamoff old_offset = file.tellg(); 18 | file.seekg(0, std::ios::end); 19 | std::streamoff filesize = file.tellg(); 20 | //Set old istream offset 21 | file.seekg(old_offset); 22 | return filesize; 23 | } 24 | 25 | #ifndef PE_BLISS_WINDOWS 26 | const u16string pe_utils::to_ucs2(const std::wstring& str) 27 | { 28 | u16string ret; 29 | if(str.empty()) 30 | return ret; 31 | 32 | ret.resize(str.length()); 33 | 34 | iconv_t conv = iconv_open("UCS-2", "WCHAR_T"); 35 | if(conv == reinterpret_cast(-1)) 36 | throw pe_exception("Error opening iconv", pe_exception::encoding_convertion_error); 37 | 38 | size_t inbytesleft = str.length() * sizeof(wchar_t); 39 | size_t outbytesleft = ret.length() * sizeof(unicode16_t); 40 | const wchar_t* in_pos = str.c_str(); 41 | unicode16_t* out_pos = &ret[0]; 42 | 43 | size_t result = iconv(conv, const_cast(reinterpret_cast(&in_pos)), &inbytesleft, reinterpret_cast(&out_pos), &outbytesleft); 44 | iconv_close(conv); 45 | 46 | if(result == static_cast(-1)) 47 | throw pe_exception("Iconv error", pe_exception::encoding_convertion_error); 48 | 49 | return ret; 50 | } 51 | 52 | const std::wstring pe_utils::from_ucs2(const u16string& str) 53 | { 54 | std::wstring ret; 55 | if(str.empty()) 56 | return ret; 57 | 58 | ret.resize(str.length()); 59 | 60 | iconv_t conv = iconv_open("WCHAR_T", "UCS-2"); 61 | if(conv == reinterpret_cast(-1)) 62 | throw pe_exception("Error opening iconv", pe_exception::encoding_convertion_error); 63 | 64 | size_t inbytesleft = str.length() * sizeof(unicode16_t); 65 | size_t outbytesleft = ret.length() * sizeof(wchar_t); 66 | const unicode16_t* in_pos = str.c_str(); 67 | wchar_t* out_pos = &ret[0]; 68 | 69 | size_t result = iconv(conv, const_cast(reinterpret_cast(&in_pos)), &inbytesleft, reinterpret_cast(&out_pos), &outbytesleft); 70 | iconv_close(conv); 71 | 72 | if(result == static_cast(-1)) 73 | throw pe_exception("Iconv error", pe_exception::encoding_convertion_error); 74 | 75 | return ret; 76 | } 77 | #endif 78 | 79 | bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2) 80 | { 81 | return guid1.Data1 == guid2.Data1 82 | && guid1.Data2 == guid2.Data2 83 | && guid1.Data3 == guid2.Data3 84 | && !memcmp(guid1.Data4, guid2.Data4, sizeof(guid1.Data4)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /pe_lib/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "stdint_defs.h" 5 | #include "pe_structures.h" 6 | 7 | namespace pe_bliss 8 | { 9 | class pe_utils 10 | { 11 | public: 12 | //Returns true if string "data" with maximum length "raw_length" is null-terminated 13 | template 14 | static bool is_null_terminated(const T* data, size_t raw_length) 15 | { 16 | raw_length /= sizeof(T); 17 | for(size_t l = 0; l < raw_length; l++) 18 | { 19 | if(data[l] == static_cast(L'\0')) 20 | return true; 21 | } 22 | 23 | return false; 24 | } 25 | 26 | //Helper template function to strip nullbytes in the end of string 27 | template 28 | static void strip_nullbytes(std::basic_string& str) 29 | { 30 | while(!*(str.end() - 1) && !str.empty()) 31 | str.erase(str.length() - 1); 32 | } 33 | 34 | //Helper function to determine if number is power of 2 35 | template 36 | static inline bool is_power_of_2(T x) 37 | { 38 | return !(x & (x - 1)); 39 | } 40 | 41 | //Helper function to align number down 42 | template 43 | static inline T align_down(T x, uint32_t align) 44 | { 45 | return x & ~(static_cast(align) - 1); 46 | } 47 | 48 | //Helper function to align number up 49 | template 50 | static inline T align_up(T x, uint32_t align) 51 | { 52 | return (x & static_cast(align - 1)) ? align_down(x, align) + static_cast(align) : x; 53 | } 54 | 55 | //Returns true if sum of two unsigned integers is safe (no overflow occurs) 56 | static inline bool is_sum_safe(uint32_t a, uint32_t b) 57 | { 58 | return a <= static_cast(-1) - b; 59 | } 60 | 61 | //Two gigabytes value in bytes 62 | static const uint32_t two_gb = 0x80000000; 63 | static const uint32_t max_dword = 0xFFFFFFFF; 64 | static const uint32_t max_word = 0x0000FFFF; 65 | static const double log_2; //instead of using M_LOG2E 66 | 67 | //Returns stream size 68 | static std::streamoff get_file_size(std::istream& file); 69 | 70 | #ifndef PE_BLISS_WINDOWS 71 | public: 72 | static const u16string to_ucs2(const std::wstring& str); 73 | static const std::wstring from_ucs2(const u16string& str); 74 | #endif 75 | 76 | private: 77 | pe_utils(); 78 | pe_utils(pe_utils&); 79 | pe_utils& operator=(const pe_utils&); 80 | }; 81 | 82 | //Windows GUID comparison 83 | bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2); 84 | } 85 | -------------------------------------------------------------------------------- /pe_lib/version_info_editor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "version_info_types.h" 3 | #include "version_info_viewer.h" 4 | 5 | namespace pe_bliss 6 | { 7 | //Helper class to read and edit version information 8 | //lang_string_values_map: map of version info strings with encodings 9 | //translation_values_map: map of translations 10 | class version_info_editor : public version_info_viewer 11 | { 12 | public: 13 | //Default constructor 14 | //strings - version info strings with charsets 15 | //translations - version info translations map 16 | version_info_editor(lang_string_values_map& strings, translation_values_map& translations); 17 | 18 | //Below functions have parameter translation 19 | //If it's empty, the default language translation will be taken 20 | //If there's no default language translation, the first one will be taken 21 | 22 | //Sets company name 23 | void set_company_name(const std::wstring& value, const std::wstring& translation = std::wstring()); 24 | //Sets file description 25 | void set_file_description(const std::wstring& value, const std::wstring& translation = std::wstring()); 26 | //Sets file version 27 | void set_file_version(const std::wstring& value, const std::wstring& translation = std::wstring()); 28 | //Sets internal file name 29 | void set_internal_name(const std::wstring& value, const std::wstring& translation = std::wstring()); 30 | //Sets legal copyright 31 | void set_legal_copyright(const std::wstring& value, const std::wstring& translation = std::wstring()); 32 | //Sets original file name 33 | void set_original_filename(const std::wstring& value, const std::wstring& translation = std::wstring()); 34 | //Sets product name 35 | void set_product_name(const std::wstring& value, const std::wstring& translation = std::wstring()); 36 | //Sets product version 37 | void set_product_version(const std::wstring& value, const std::wstring& translation = std::wstring()); 38 | 39 | //Sets version info property value 40 | //property_name - property name 41 | //value - property value 42 | //If translation does not exist, it will be added to strings and translations lists 43 | //If property does not exist, it will be added 44 | void set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation = std::wstring()); 45 | 46 | //Adds translation to translation list 47 | void add_translation(const std::wstring& translation); 48 | void add_translation(uint16_t language_id, uint16_t codepage_id); 49 | 50 | //Removes translation from translations and strings lists 51 | void remove_translation(const std::wstring& translation); 52 | void remove_translation(uint16_t language_id, uint16_t codepage_id); 53 | 54 | private: 55 | lang_string_values_map& strings_edit_; 56 | translation_values_map& translations_edit_; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /pe_lib/version_info_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "stdint_defs.h" 5 | 6 | namespace pe_bliss 7 | { 8 | //Typedef for version info functions: Name - Value 9 | typedef std::map string_values_map; 10 | //Typedef for version info functions: Language string - String Values Map 11 | //Language String consists of LangID and CharsetID 12 | //E.g. 041904b0 for Russian UNICODE, 040004b0 for Process Default Language UNICODE 13 | typedef std::map lang_string_values_map; 14 | 15 | //Typedef for version info functions: Language - Character Set 16 | typedef std::multimap translation_values_map; 17 | } 18 | -------------------------------------------------------------------------------- /pe_lib/version_info_viewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "pe_resource_viewer.h" 6 | #include "pe_structures.h" 7 | #include "version_info_types.h" 8 | 9 | namespace pe_bliss 10 | { 11 | //Helper class to read version information 12 | //lang_string_values_map: map of version info strings with encodings 13 | //translation_values_map: map of translations 14 | class version_info_viewer 15 | { 16 | public: 17 | //Useful typedefs 18 | typedef std::pair translation_pair; 19 | typedef std::vector translation_list; 20 | 21 | public: 22 | //Default constructor 23 | //strings - version info strings with charsets 24 | //translations - version info translations map 25 | version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations); 26 | 27 | //Below functions have parameter translation 28 | //If it's empty, the default language translation will be taken 29 | //If there's no default language translation, the first one will be taken 30 | 31 | //Returns company name 32 | const std::wstring get_company_name(const std::wstring& translation = std::wstring()) const; 33 | //Returns file description 34 | const std::wstring get_file_description(const std::wstring& translation = std::wstring()) const; 35 | //Returns file version 36 | const std::wstring get_file_version(const std::wstring& translation = std::wstring()) const; 37 | //Returns internal file name 38 | const std::wstring get_internal_name(const std::wstring& translation = std::wstring()) const; 39 | //Returns legal copyright 40 | const std::wstring get_legal_copyright(const std::wstring& translation = std::wstring()) const; 41 | //Returns original file name 42 | const std::wstring get_original_filename(const std::wstring& translation = std::wstring()) const; 43 | //Returns product name 44 | const std::wstring get_product_name(const std::wstring& translation = std::wstring()) const; 45 | //Returns product version 46 | const std::wstring get_product_version(const std::wstring& translation = std::wstring()) const; 47 | 48 | //Returns list of translations in string representation 49 | const translation_list get_translation_list() const; 50 | 51 | //Returns version info property value 52 | //property_name - required property name 53 | //If throw_if_absent = true, will throw exception if property does not exist 54 | //If throw_if_absent = false, will return empty string if property does not exist 55 | const std::wstring get_property(const std::wstring& property_name, const std::wstring& translation = std::wstring(), bool throw_if_absent = false) const; 56 | 57 | //Converts translation HEX-string to pair of language ID and codepage ID 58 | static const translation_pair translation_from_string(const std::wstring& translation); 59 | 60 | public: 61 | //Default process language, UNICODE 62 | static const std::wstring default_language_translation; 63 | 64 | private: 65 | const lang_string_values_map& strings_; 66 | const translation_values_map& translations_; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /samples/Makefile: -------------------------------------------------------------------------------- 1 | SAMPLES = address_convertions basic_dotnet_viewer basic_info_viewer bound_import_reader debug_info_reader entropy_calculator exception_dir_reader export_adder exports_reader full_pe_rebuilder image_config_editor import_adder imports_reader pe_config_reader pe_realigner pe_rebaser pe_sections_reader pe_stripper relocation_adder relocations_reader resource_editor resource_viewer rich_overlay_stub_reader section_adder sections_and_addresses tls_editor tls_reader 2 | OUTDIR = ./out/ 3 | LIBPATH = ../lib/libpebliss.a 4 | TARGETS = $(foreach sample,$(SAMPLES),$(sample)_sample) 5 | TARGETS_CLEAN = $(foreach sample,$(SAMPLES),$(sample)_clean) 6 | 7 | all: $(TARGETS) 8 | 9 | clean: $(TARGETS_CLEAN) 10 | 11 | $(OUTDIR): 12 | mkdir -p $(OUTDIR) 13 | 14 | %_sample: $(OUTDIR) $(LIBPATH) 15 | $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./$* 16 | 17 | %_clean: 18 | $(MAKE) -C ./$* clean 19 | -------------------------------------------------------------------------------- /samples/address_convertions/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/address_convertions/address_convertions.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/address_convertions/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как конвертировать адреса для PE-файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: address_convertions.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Получаем список секций 33 | std::cout << "Reading PE sections..." << std::hex << std::showbase << std::endl << std::endl; 34 | const section_list sections = image.get_image_sections(); 35 | 36 | //Перечисляем секции и выводим информацию о них 37 | for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) 38 | { 39 | const section& s = *it; //Секция 40 | std::cout << "Section [" << s.get_name() << "]" << std::endl //Имя секции 41 | << " -> RVA: " << s.get_virtual_address() << std::endl //Виртуальный адрес (RVA) 42 | << " -> VA: " << image.rva_to_va_64(s.get_virtual_address()) << std::endl //Виртуальный адрес (VA) 43 | << " -> File offset: " << image.rva_to_file_offset(s.get_virtual_address()) //Файловое смещение секции, вычисленное из ее RVA 44 | << std::endl << std::endl; 45 | } 46 | } 47 | catch(const pe_exception& e) 48 | { 49 | //Если возникла ошибка 50 | std::cout << "Error: " << e.what() << std::endl; 51 | return -1; 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /samples/basic_dotnet_viewer/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/basic_dotnet_viewer/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как получить базовую информацию о .NET PE-файле 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: basic_dotnet_viewer.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Если образ не .NET, выходим 33 | if(!image.is_dotnet()) 34 | { 35 | std::cout << "Image is not .NET" << std::endl; 36 | return 0; 37 | } 38 | 39 | std::cout << "Reading basic dotnet info..." << std::hex << std::showbase << std::endl << std::endl; 40 | 41 | //Получаем .NET-заголовок PE-файла 42 | const basic_dotnet_info info(get_basic_dotnet_info(image)); 43 | 44 | //Выводим некоторую информацию 45 | std::cout << "Major runtime version: " << info.get_major_runtime_version() << std::endl //Версия рантайма 46 | << "Minor runtime version: " << info.get_minor_runtime_version() << std::endl 47 | << "Flags: " << info.get_flags() << std::endl //Флаги 48 | << "RVA of resources: " << info.get_rva_of_resources() << std::endl //RVA ресурсов 49 | << "RVA of metadata: " << info.get_rva_of_metadata() << std::endl //RVA метаданных 50 | << "Size of resources: " << info.get_size_of_resources() << std::endl //Размер ресурсов 51 | << "Size of metadata: " << info.get_size_of_metadata() << std::endl; //Размер метаданных 52 | 53 | //Определим точку входа .NET 54 | if(info.is_native_entry_point()) 55 | std::cout << "Entry point RVA: "; 56 | else 57 | std::cout << "Entry point token: "; 58 | 59 | std::cout << info.get_entry_point_rva_or_token() << std::endl; 60 | } 61 | catch(const pe_exception& e) 62 | { 63 | //Если возникла ошибка 64 | std::cout << "Error: " << e.what() << std::endl; 65 | return -1; 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /samples/basic_info_viewer/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/basic_info_viewer/basic_info_viewer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/basic_info_viewer/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как получить базовую информацию о PE-файле 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: basic_info_viewer.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Фабрика автоматически получает тип PE-файла и создает экземпляр нужного класса, 33 | //но можно получить тип PE-файла и вручную, воспользовавшись одной из перегрузок функции get_pe_type 34 | //Здесь мы просто выведем уже известный тип PE-файла: 35 | std::cout << "PE file type: " << (image.get_pe_type() == pe_type_32 ? "PE32 (PE)" : "PE64 (PE+)") << std::endl; 36 | 37 | //Вычислим контрольную сумму PE-файла 38 | std::cout << "Calculated checksum: "<< std::hex << std::showbase << calculate_checksum(pe_file) << std::endl; 39 | //Выведем контрольную сумму из заголовка файла (для не-драйверов она обычно равна 0) 40 | std::cout << "Stored checksum: " << image.get_checksum() << std::endl; 41 | 42 | //Выведем характеристики PE-файла 43 | std::cout << "Characteristics: " << image.get_characteristics() << std::endl; 44 | 45 | //Выведем адрес точки входа 46 | std::cout << "Entry point: " << image.get_ep() << std::endl; 47 | 48 | //Выведем выравнивание 49 | std::cout << "File alignment: " << image.get_file_alignment() << std::endl; 50 | std::cout << "Section alignment: " << image.get_section_alignment() << std::endl; 51 | 52 | //Выведем базу образа в 64-битном виде (универсально для PE и PE+) 53 | std::cout << "Image base: " << image.get_image_base_64() << std::endl; 54 | 55 | //Выведем подсистему 56 | std::cout << "Subsystem: " << image.get_subsystem() << std::endl; 57 | std::cout << "Is console: " << (image.is_console() ? "YES" : "NO") << std::endl; 58 | std::cout << "Is windows GUI: " << (image.is_gui() ? "YES" : "NO") << std::endl; 59 | 60 | //Выведем, какие директории есть у файла 61 | std::cout << "Has bound import: " << (image.has_bound_import() ? "YES" : "NO") << std::endl; 62 | std::cout << "Has config: " << (image.has_config() ? "YES" : "NO") << std::endl; 63 | std::cout << "Has debug: " << (image.has_debug() ? "YES" : "NO") << std::endl; 64 | std::cout << "Has delay import: " << (image.has_delay_import() ? "YES" : "NO") << std::endl; 65 | std::cout << "Has exception directory: " << (image.has_exception_directory() ? "YES" : "NO") << std::endl; 66 | std::cout << "Has exports: " << (image.has_exports() ? "YES" : "NO") << std::endl; 67 | std::cout << "Has imports: " << (image.has_imports() ? "YES" : "NO") << std::endl; 68 | std::cout << "Has reloc: " << (image.has_reloc() ? "YES" : "NO") << std::endl; 69 | std::cout << "Has resources: " << (image.has_resources() ? "YES" : "NO") << std::endl; 70 | std::cout << "Has security: " << (image.has_security() ? "YES" : "NO") << std::endl; 71 | std::cout << "Has tls: " << (image.has_tls() ? "YES" : "NO") << std::endl; 72 | std::cout << "Is .NET: " << (image.is_dotnet() ? "YES" : "NO") << std::endl; 73 | } 74 | catch(const pe_exception& e) 75 | { 76 | //Если возникла ошибка 77 | std::cout << "Error: " << e.what() << std::endl; 78 | return -1; 79 | } 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /samples/bound_import_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/bound_import_reader/bound_import_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/bound_import_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о привязанном импорте PE-файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: bound_import_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Проверим, есть ли привязанный импорт у PE-файла 33 | if(!image.has_bound_import()) 34 | { 35 | std::cout << "Image has no bound import" << std::endl; 36 | return 0; 37 | } 38 | 39 | std::cout << "Reading PE bound import..." << std::hex << std::showbase << std::endl << std::endl; 40 | 41 | //Получаем информацию о привязанном импорте 42 | const bound_import_module_list modules(get_bound_import_module_list(image)); 43 | 44 | //Выведем импортируемые модули и форварды 45 | for(bound_import_module_list::const_iterator it = modules.begin(); it != modules.end(); ++it) 46 | { 47 | const bound_import& import = *it; //Импортируемая библиотека 48 | std::cout << "Module: " << import.get_module_name() << std::endl //Имя модуля 49 | << "Timestamp: " << import.get_timestamp() << std::endl; //Временная метка 50 | 51 | //Перечислим форварды для модуля - модули, на которые ссылается этот: 52 | const bound_import::ref_list& refs = import.get_module_ref_list(); 53 | for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it) 54 | { 55 | std::cout << " -> Module: " << (*ref_it).get_module_name() << std::endl //Имя модуля, на который ссылается родительский модуль 56 | << " -> Timestamp: " << (*ref_it).get_timestamp() << std::endl; //Временная метка 57 | } 58 | } 59 | } 60 | catch(const pe_exception& e) 61 | { 62 | //Если возникла ошибка 63 | std::cout << "Error: " << e.what() << std::endl; 64 | return -1; 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /samples/debug_info_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/debug_info_reader/debug_info_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/entropy_calculator/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/entropy_calculator/entropy_calculator.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/entropy_calculator/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как посчитать энтропию файла и секций PE 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: entropy_calculator.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | 28 | try 29 | { 30 | //Считаем энтропию файла 31 | std::cout << "File entropy: " << entropy_calculator::calculate_entropy(pe_file) << std::endl; 32 | 33 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 34 | pe_base image(pe_factory::create_pe(pe_file)); 35 | 36 | std::cout << "Sections entropy: " << entropy_calculator::calculate_entropy(image) << std::endl; //Считаем энтропию всех секций 37 | 38 | //Перечисляем секции и считаем их энтропию по отдельности 39 | const section_list sections = image.get_image_sections(); 40 | for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) 41 | { 42 | if(!(*it).empty()) //Если секция не пуста - посчитаем ее энтропию 43 | std::cout << "Section [" << (*it).get_name() << "] entropy: " << entropy_calculator::calculate_entropy(*it) << std::endl; 44 | } 45 | } 46 | catch(const pe_exception& e) 47 | { 48 | //Если возникла ошибка 49 | std::cout << "Error: " << e.what() << std::endl; 50 | return -1; 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /samples/exception_dir_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/exception_dir_reader/exception_dir_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/exception_dir_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о директории исключений 11 | //Она существует только для 64-разрядных PE-файлов (PE+) 12 | int main(int argc, char* argv[]) 13 | { 14 | if(argc != 2) 15 | { 16 | std::cout << "Usage: exception_dir_reader.exe PE_FILE" << std::endl; 17 | return 0; 18 | } 19 | 20 | //Открываем файл 21 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 22 | if(!pe_file) 23 | { 24 | std::cout << "Cannot open " << argv[1] << std::endl; 25 | return -1; 26 | } 27 | 28 | try 29 | { 30 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 31 | pe_base image(pe_factory::create_pe(pe_file)); 32 | 33 | //Проверим, есть ли директория информации об исключениях у PE-файла 34 | if(!image.has_exception_directory()) 35 | { 36 | std::cout << "Image has no exception directory" << std::endl; 37 | return 0; 38 | } 39 | 40 | std::cout << "Reading exception directory..." << std::hex << std::showbase << std::endl << std::endl; 41 | 42 | //Получаем информацию из exception directory 43 | const exception_entry_list info(get_exception_directory_data(image)); 44 | 45 | //Выведем записи из exception directory 46 | //Подробное описание всех этих структур есть в MSDN 47 | for(exception_entry_list::const_iterator it = info.begin(); it != info.end(); ++it) 48 | { 49 | const exception_entry& entry = *it; //Запись из таблицы 50 | 51 | //Выведем информацию 52 | std::cout << "Addresses: [" << entry.get_begin_address() << ":" << entry.get_end_address() << "]:" << std::endl 53 | << "Flags: " << static_cast(entry.get_flags()) << std::endl 54 | << "Frame pointer register number: " << static_cast(entry.get_frame_pointer_register_number()) << std::endl 55 | << "Number of unwind slots: " << static_cast(entry.get_number_of_unwind_slots()) << std::endl 56 | << "Scaled RSP offset: " << static_cast(entry.get_scaled_rsp_offset()) << std::endl 57 | << "Size of prolog: " << static_cast(entry.get_size_of_prolog()) << std::endl 58 | << "Unwind info address: " << entry.get_unwind_info_address() << std::endl 59 | << "Unwind info version: " << static_cast(entry.get_unwind_info_version()) << std::endl 60 | << std::endl; 61 | } 62 | } 63 | catch(const pe_exception& e) 64 | { 65 | //Если возникла ошибка 66 | std::cout << "Error: " << e.what() << std::endl; 67 | return -1; 68 | } 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /samples/export_adder/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/export_adder/export_adder.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/exports_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/exports_reader/exports_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/exports_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию об экспортах PE или PE+ файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: exports_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Проверим, есть ли экспорты у PE-файла 33 | if(!image.has_exports()) 34 | { 35 | std::cout << "Image has no exports" << std::endl; 36 | return 0; 37 | } 38 | 39 | std::cout << "Reading PE exports..." << std::hex << std::showbase << std::endl << std::endl; 40 | 41 | //Получаем полную информацию об экспортах и список экспортируемых функций 42 | export_info info; 43 | const exported_functions_list exports = get_exported_functions(image, info); 44 | 45 | //Выведем некоторую информацию об экспорте: 46 | std::cout << "Export info" << std::endl 47 | << "Library name: " << info.get_name() << std::endl //Имя библиотеки 48 | << "Timestamp: " << info.get_timestamp() << std::endl //Временная метка 49 | << "Ordinal base: " << info.get_ordinal_base() << std::endl //База ординалов 50 | << std::endl; 51 | 52 | //Перечисляем секции и выводим информацию о них 53 | for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) 54 | { 55 | const exported_function& func = *it; //Экспортируемая функция 56 | std::cout << "[+] "; 57 | if(func.has_name()) //Если функция имеет имя, выведем его и ординал имени 58 | std::cout << func.get_name() << ", name ordinal: " << func.get_name_ordinal() << " "; 59 | 60 | //Ординал функции 61 | std::cout << "ORD: " << func.get_ordinal(); 62 | 63 | //Если функция - форвард (переадресация в другую DLL), выведем имя форварда 64 | if(func.is_forwarded()) 65 | std::cout << std::endl << " -> " << func.get_forwarded_name(); 66 | 67 | std::cout << std::endl; 68 | } 69 | } 70 | catch(const pe_exception& e) 71 | { 72 | //Если возникла ошибка 73 | std::cout << "Error: " << e.what() << std::endl; 74 | return -1; 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /samples/full_pe_rebuilder/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/image_config_editor/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/image_config_editor/image_config_editor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/image_config_editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как пересобрать директорию Load Config у PE-файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: image_config_editor.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Получим информацию о директории Load Config 33 | image_config_info info(get_image_config(image)); 34 | 35 | //Но пересоберем эту директорию, расположив ее в новой секции 36 | section load_config; 37 | load_config.get_raw_data().resize(1); //Мы не можем добавлять пустые секции, поэтому пусть у нее будет начальный размер данных 1 38 | load_config.set_name("load_cfg"); //Имя секции 39 | load_config.readable(true).writeable(true); //Доступна на чтение и запись 40 | section& attached_section = image.add_section(load_config); //Добавим секцию и получим ссылку на добавленную секцию с просчитанными размерами 41 | 42 | //Если у файла была таблица SE Handler'ов 43 | if(info.get_se_handler_table_va()) 44 | info.add_se_handler_rva(0x7777); //Добавим новый SE Handler в таблицу (просто для теста) 45 | 46 | //Если у файла не существовало таблицы Lock-префиксов, добавим ее 47 | //(также для теста) 48 | if(!info.get_lock_prefix_table_va()) 49 | info.add_lock_prefix_rva(0x9999); 50 | 51 | //Пересобираем директорию Image Load Config, пересобираем таблицу Lock-префиксов, если она имелась, а также 52 | //таблицу SE Handler'ов, если она есть 53 | rebuild_image_config(image, info, attached_section, 1); 54 | 55 | //Создаем новый PE-файл 56 | std::string base_file_name(argv[1]); 57 | std::string::size_type slash_pos; 58 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 59 | base_file_name = base_file_name.substr(slash_pos + 1); 60 | 61 | base_file_name = "new_" + base_file_name; 62 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 63 | if(!new_pe_file) 64 | { 65 | std::cout << "Cannot create " << base_file_name << std::endl; 66 | return -1; 67 | } 68 | 69 | //Пересобираем PE-файл 70 | rebuild_pe(image, new_pe_file); 71 | 72 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 73 | } 74 | catch(const pe_exception& e) 75 | { 76 | //Если возникла ошибка 77 | std::cout << "Error: " << e.what() << std::endl; 78 | return -1; 79 | } 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /samples/import_adder/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/import_adder/import_adder.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/imports_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/imports_reader/imports_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/imports_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию об импортах PE или PE+ файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: imports_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Проверим, есть ли импорты у файла 33 | if(!image.has_imports()) 34 | { 35 | std::cout << "Image has no imports" << std::endl; 36 | return 0; 37 | } 38 | 39 | std::cout << "Reading PE imports..." << std::hex << std::showbase << std::endl << std::endl; 40 | 41 | //Получаем список импортируемых библиотек с функциями 42 | const imported_functions_list imports = get_imported_functions(image); 43 | 44 | //Перечисляем импортированные библиотеки и выводим информацию о них 45 | for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it) 46 | { 47 | const import_library& lib = *it; //Импортируемая библиотека 48 | std::cout << "Library [" << lib.get_name() << "]" << std::endl //Имя 49 | << "Timestamp: " << lib.get_timestamp() << std::endl //Временная метка 50 | << "RVA to IAT: " << lib.get_rva_to_iat() << std::endl //Относительный адрес к import address table 51 | << "========" << std::endl; 52 | 53 | //Перечисляем импортированные функции для библиотеки 54 | const import_library::imported_list& functions = lib.get_imported_functions(); 55 | for(import_library::imported_list::const_iterator func_it = functions.begin(); func_it != functions.end(); ++func_it) 56 | { 57 | const imported_function& func = *func_it; //Импортированная функция 58 | std::cout << "[+] "; 59 | if(func.has_name()) //Если функция имеет имя - выведем его 60 | std::cout << func.get_name(); 61 | else 62 | std::cout << "#" << func.get_ordinal(); //Иначе она импортирована по ординалу 63 | 64 | //Хинт 65 | std::cout << " hint: " << func.get_hint() << std::endl; 66 | } 67 | 68 | std::cout << std::endl; 69 | } 70 | } 71 | catch(const pe_exception& e) 72 | { 73 | //Если возникла ошибка 74 | std::cout << "Error: " << e.what() << std::endl; 75 | return -1; 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /samples/lib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _M_X64 3 | #ifdef _DEBUG 4 | #pragma comment(lib, "../../Debug/pe_bliss.lib") 5 | #else 6 | #pragma comment(lib, "../../Release/pe_bliss.lib") 7 | #endif 8 | #else 9 | #ifdef _DEBUG 10 | #pragma comment(lib, "../../x64/Debug/pe_bliss.lib") 11 | #else 12 | #pragma comment(lib, "../../x64/Release/pe_bliss.lib") 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /samples/pe_config_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/pe_config_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о Image Config (конфигурация исполняемого файла) PE или PE+ 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: pe_config_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | std::cout << "Reading PE image config info..." << std::hex << std::showbase << std::endl << std::endl; 33 | 34 | //Получаем конфигурацию 35 | const image_config_info info(get_image_config(image)); 36 | 37 | //Выводим данные конфигурации 38 | //Подробнее о полях - в MSDN 39 | std::cout << "Critical section default timeout: " << info.get_critical_section_default_timeout() << std::endl 40 | << "Decommit free block threshold: " << info.get_decommit_free_block_threshold() << std::endl 41 | << "Decommit total free threshold: " << info.get_decommit_total_free_threshold() << std::endl 42 | << "Global flags clear: " << info.get_global_flags_clear() << std::endl 43 | << "Global flags set: " << info.get_global_flags_set() << std::endl 44 | << "VA of lock table prefix: " << info.get_lock_prefix_table_va() << std::endl 45 | << "Max allocation size: " << info.get_max_allocation_size() << std::endl 46 | << "Process affinity mask: " << info.get_process_affinity_mask() << std::endl 47 | << "Process heap flags: " << info.get_process_heap_flags() << std::endl 48 | << "Security cookie VA: " << info.get_security_cookie_va() << std::endl 49 | << "CSDVersion: " << info.get_service_pack_version() << std::endl 50 | << "Timestamp: " << info.get_time_stamp() << std::endl 51 | << "Virtual memory threshold: " << info.get_virtual_memory_threshold() << std::endl 52 | << std::endl; 53 | 54 | //Выведем адреса SE-хендлеров 55 | const image_config_info::se_handler_list& se_handlers = info.get_se_handler_rvas(); 56 | for(image_config_info::se_handler_list::const_iterator it = se_handlers.begin(); it != se_handlers.end(); ++it) 57 | std::cout << "SE Handler: " << (*it) << std::endl; 58 | } 59 | catch(const pe_exception& e) 60 | { 61 | //Если возникла ошибка 62 | std::cout << "Error: " << e.what() << std::endl; 63 | return -1; 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /samples/pe_config_reader/pe_config_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/pe_realigner/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/pe_realigner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как изменить файловое выравнивание PE-файлов 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: pe_realigner.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Выведем темущий file alignment 33 | std::cout << "File alignment: " << image.get_file_alignment() << std::endl; 34 | 35 | //Предложим выбрать новое выравнивание 36 | unsigned int new_alignment_index = static_cast(-1); 37 | 38 | while(new_alignment_index > 3) 39 | { 40 | if(std::cin.fail()) 41 | { 42 | //На случай, если пользователь ввел что-то некорректное 43 | std::cin.clear(); 44 | std::cin.ignore(static_cast(-1), '\n'); 45 | } 46 | 47 | std::cout << "Choose new file alignment" << std::endl; 48 | std::cout << "(0 = 512, 1 = 1024, 2 = 2048, 3 = 4096): "; 49 | std::cin >> new_alignment_index; 50 | } 51 | 52 | unsigned int available_aligns[] = {512, 1024, 2048, 4096}; 53 | 54 | //Изменим выравнивание на то, которое указал пользователь 55 | image.realign_file(available_aligns[new_alignment_index]); 56 | 57 | //Создаем новый PE-файл 58 | std::string base_file_name(argv[1]); 59 | std::string::size_type slash_pos; 60 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 61 | base_file_name = base_file_name.substr(slash_pos + 1); 62 | 63 | base_file_name = "new_" + base_file_name; 64 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 65 | if(!new_pe_file) 66 | { 67 | std::cout << "Cannot create " << base_file_name << std::endl; 68 | return -1; 69 | } 70 | 71 | //Пересобираем PE-файл 72 | rebuild_pe(image, new_pe_file); 73 | 74 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 75 | } 76 | catch(const pe_exception& e) 77 | { 78 | //Если возникла ошибка 79 | std::cout << "Error: " << e.what() << std::endl; 80 | return -1; 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /samples/pe_realigner/pe_realigner.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/pe_rebaser/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/pe_rebaser/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как изменить базовый адрес загрузки PE-файла при условии наличия релокаций 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: pe_rebaser.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Проверим, есть ли релокации у образа 33 | if(!image.has_reloc()) 34 | { 35 | std::cout << "Image has no relocations, rebase is not possible" << std::endl; 36 | return 0; 37 | } 38 | 39 | //Получим значение базового адреса загрузки образа (64-бита, универсально для PE и PE+) 40 | uint64_t base = image.get_image_base_64(); 41 | base += 0x100000; //Изменим базовый адрес загрузки 42 | 43 | //Произведем пересчет необходимых адресов 44 | rebase_image(image, get_relocations(image), base); 45 | 46 | //Создаем новый PE-файл 47 | std::string base_file_name(argv[1]); 48 | std::string::size_type slash_pos; 49 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 50 | base_file_name = base_file_name.substr(slash_pos + 1); 51 | 52 | base_file_name = "new_" + base_file_name; 53 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 54 | if(!new_pe_file) 55 | { 56 | std::cout << "Cannot create " << base_file_name << std::endl; 57 | return -1; 58 | } 59 | 60 | //Пересобираем PE-файл 61 | rebuild_pe(image, new_pe_file); 62 | 63 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 64 | } 65 | catch(const pe_exception& e) 66 | { 67 | //Если возникла ошибка 68 | std::cout << "Error: " << e.what() << std::endl; 69 | return -1; 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /samples/pe_rebaser/pe_rebaser.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/pe_sections_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/pe_sections_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о секциях PE или PE+ файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: pe_sections_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Получаем список секций 33 | std::cout << "Reading PE sections..." << std::hex << std::showbase << std::endl << std::endl; 34 | const section_list sections(image.get_image_sections()); 35 | 36 | //Перечисляем секции и выводим информацию о них 37 | for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) 38 | { 39 | const section& s = *it; //Секция 40 | std::cout << "Section [" << s.get_name() << "]" << std::endl //Имя секции 41 | << "Characteristics: " << s.get_characteristics() << std::endl //Характеристики 42 | << "Size of raw data: " << s.get_size_of_raw_data() << std::endl //Размер данных в файле 43 | << "Virtual address: " << s.get_virtual_address() << std::endl //Виртуальный адрес 44 | << "Virtual size: " << s.get_virtual_size() << std::endl //Виртуальный размер 45 | << std::endl; 46 | } 47 | } 48 | catch(const pe_exception& e) 49 | { 50 | //Если возникла ошибка 51 | std::cout << "Error: " << e.what() << std::endl; 52 | return -1; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /samples/pe_sections_reader/pe_sections_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/pe_stripper/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/pe_stripper/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как вырезать ненужные данные из PE-файла и пересобрать его 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: pe_stripper.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Удалим DOS stub и rich overlay 33 | image.strip_stub_overlay(); 34 | 35 | //Удалим ненужные DATA_DIRECTORY (нулевые) 36 | //Очень малое количество линкеров умеют это делать 37 | image.strip_data_directories(0); 38 | 39 | //Создаем новый PE-файл 40 | std::string base_file_name(argv[1]); 41 | std::string::size_type slash_pos; 42 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 43 | base_file_name = base_file_name.substr(slash_pos + 1); 44 | 45 | base_file_name = "new_" + base_file_name; 46 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 47 | if(!new_pe_file) 48 | { 49 | std::cout << "Cannot create " << base_file_name << std::endl; 50 | return -1; 51 | } 52 | 53 | //Пересобираем PE-файл с опцией сжатия DOS-header 54 | //Уменьшения размера это не дает, но упаковывает NT-заголовки в DOS-заголовок 55 | //При пересборке автоматически убираются ненужные нулевые байты в самом конце образа, 56 | //в результате чего размер образа становится немного меньше 57 | rebuild_pe(image, new_pe_file, true); 58 | 59 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 60 | } 61 | catch(const pe_exception& e) 62 | { 63 | //Если возникла ошибка 64 | std::cout << "Error: " << e.what() << std::endl; 65 | return -1; 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /samples/pe_stripper/pe_stripper.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/relocation_adder/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/relocation_adder/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как добавить новую релокацию в таблицы релокаций PE-файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: relocation_adder.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Перечислим и получим все записи из таблиц релокаций в PE-файле, кроме абсолютных 33 | //Можно было бы включить в список и абсолютные записи (ABSOLUTE), передав в вызов true 34 | //Эти записи не нужны при пересборке релокаций, они используются для выравнивания 35 | //и будут добавлены автоматически пересборщиком 36 | relocation_table_list tables(get_relocations(image)); 37 | 38 | //Создаем новую таблицу релокаций 39 | relocation_table new_table; 40 | new_table.set_rva(0x5678); //Относительный адрес релокаций в таблице - он некорректен, для примера, поэтому получившийся PE скорее всего не загрузится 41 | //Добавим в таблицу новую релокацию 42 | new_table.add_relocation(relocation_entry(10, 3)); //Тип 3 - HIGHLOW-релокация, RRVA = 10, т.е. RVA = 0x5678 + 10 43 | //Добавляем таблицу 44 | tables.push_back(new_table); 45 | 46 | //Можно редактировать и существующие релокации, но делать этого не стоит, так как файл не загрузится, если что-то в них поменять 47 | //Если их удалить у EXE-файла полностью, то все будет нормально, у DLL этого делать не стоит 48 | //Мы просто пересоберем релокации 49 | //Они будет иметь больший размер, чем до нашего редактирования, 50 | //поэтому запишем их в новую секцию, чтобы все поместилось 51 | //(мы не можем расширять существующие секции, если только секция не в самом конце файла) 52 | section new_relocs; 53 | new_relocs.get_raw_data().resize(1); //Мы не можем добавлять пустые секции, поэтому пусть у нее будет начальный размер данных 1 54 | new_relocs.set_name("new_rel"); //Имя секции 55 | new_relocs.readable(true); //Доступна на чтение 56 | section& attached_section = image.add_section(new_relocs); //Добавим секцию и получим ссылку на добавленную секцию с просчитанными размерами 57 | 58 | rebuild_relocations(image, tables, attached_section); //Пересобираем экспорты, расположив их с начала новой секции и записав новые данные таблиц релокаций в PE-заголовок 59 | 60 | //Создаем новый PE-файл 61 | std::string base_file_name(argv[1]); 62 | std::string::size_type slash_pos; 63 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 64 | base_file_name = base_file_name.substr(slash_pos + 1); 65 | 66 | base_file_name = "new_" + base_file_name; 67 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 68 | if(!new_pe_file) 69 | { 70 | std::cout << "Cannot create " << base_file_name << std::endl; 71 | return -1; 72 | } 73 | 74 | //Пересобираем PE-файл 75 | rebuild_pe(image, new_pe_file); 76 | 77 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 78 | } 79 | catch(const pe_exception& e) 80 | { 81 | //Если возникла ошибка 82 | std::cout << "Error: " << e.what() << std::endl; 83 | return -1; 84 | } 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /samples/relocation_adder/relocation_adder.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/relocations_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/relocations_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о релокациях PE или PE+ файла 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: relocations_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Проверим, есть ли релокации у файла 33 | if(!image.has_reloc()) 34 | { 35 | std::cout << "Image has no relocations" << std::endl; 36 | return 0; 37 | } 38 | 39 | std::cout << "Reading PE relocations..." << std::hex << std::showbase << std::endl << std::endl; 40 | 41 | //Получаем список таблиц релокаций 42 | const relocation_table_list tables(get_relocations(image)); 43 | 44 | //Перечисляем таблицы релокаций и выводим информацию о них 45 | for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it) 46 | { 47 | const relocation_table& table = *it; //Таблица релокаций 48 | std::cout << "RVA [" << table.get_rva() << "]" << std::endl //Относительный адрес 49 | << "==========" 50 | << std::endl; 51 | 52 | //Перечислим все релокации 53 | const relocation_table::relocation_list& relocs = table.get_relocations(); 54 | for(relocation_table::relocation_list::const_iterator reloc_it = relocs.begin(); reloc_it != relocs.end(); ++reloc_it) 55 | { 56 | std::cout << "[+] " << (*reloc_it).get_item() << std::endl; 57 | } 58 | 59 | std::cout << std::endl; 60 | } 61 | } 62 | catch(const pe_exception& e) 63 | { 64 | //Если возникла ошибка 65 | std::cout << "Error: " << e.what() << std::endl; 66 | return -1; 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /samples/relocations_reader/relocations_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/resource_editor/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/resource_editor/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/samples/resource_editor/resource.h -------------------------------------------------------------------------------- /samples/resource_editor/resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/samples/resource_editor/resource.rc -------------------------------------------------------------------------------- /samples/resource_editor/resource_editor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Resource Files 33 | 34 | 35 | 36 | 37 | Resource Files 38 | 39 | 40 | -------------------------------------------------------------------------------- /samples/resource_editor/wxwin.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/samples/resource_editor/wxwin.ico -------------------------------------------------------------------------------- /samples/resource_viewer/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/resource_viewer/resource_viewer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/rich_overlay_stub_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/rich_overlay_stub_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как получить информацию о стабе PE-файла и rich overlay, который добавляет при компиляции MS Visual Studio 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: rich_overlay_stub_reader.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Выведем длину DOS stub'а 33 | std::cout << "Image stub length: " << image.get_stub_overlay().length() << std::endl << std::endl; 34 | 35 | //Перечисляем все RICH-записи 36 | rich_data_list data = get_rich_data(image); 37 | for(rich_data_list::const_iterator it = data.begin(); it != data.end(); ++it) 38 | { 39 | //Выводим информацию о записи 40 | std::cout << "Number: " << (*it).get_number() << std::endl 41 | << "Times: " << (*it).get_times() << std::endl 42 | << "Version: " << (*it).get_version() << std::endl 43 | << std::endl; 44 | } 45 | 46 | //Отобразим информацию о том, есть ли у файла оверлей в конце (у некоторых инсталляторов, например, есть) 47 | std::cout << "Has overlay in the end: " << (image.has_overlay() ? "YES" : "NO") << std::endl; 48 | } 49 | catch(const pe_exception& e) 50 | { 51 | //Если возникла ошибка 52 | std::cout << "Error: " << e.what() << std::endl; 53 | return -1; 54 | } 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/sample.mak: -------------------------------------------------------------------------------- 1 | PWD=$(shell pwd) 2 | OUTDIR = ../out/ 3 | LIBPATH = ../../lib/libpebliss.a 4 | NAME=$(shell basename $(PWD)) 5 | CXXFLAGS = -O2 -Wall -I../../pe_lib 6 | 7 | ifdef PE_DEBUG 8 | CXXFLAGS += -g -O0 9 | endif 10 | 11 | all: $(OUTDIR)$(NAME) 12 | 13 | clean: 14 | rm -f $(NAME) *.o 15 | rm -f $(OUTDIR)$(NAME) 16 | 17 | $(NAME): main.o 18 | $(CXX) -Wall $^ -lpebliss -L../../lib -o $(NAME) 19 | 20 | main.o: $(LIBPATH) 21 | 22 | $(OUTDIR)$(NAME): $(NAME) 23 | cp -d $(NAME) $(OUTDIR) 24 | 25 | -------------------------------------------------------------------------------- /samples/section_adder/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/section_adder/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как добавить секцию в PE-файл и записать в нее какие-нибудь данные 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: section_adder.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Секцию можно добавить только после всех существующих, чтобы PE-файл не испортился 33 | //Создаем новую секцию 34 | section new_section; 35 | new_section.readable(true).writeable(true); //Делаем секцию доступной для чтения и записи 36 | new_section.set_name("kaimi.ru"); //Ставим имя секции - максимум 8 символов 37 | new_section.set_raw_data("Tralala"); //Устанавливаем данные секции 38 | 39 | //Добавляем секцию. Все адреса пересчитаются автоматически 40 | //Вызов вернет ссылку на уже добавленную секцию с пересчитанными адресами 41 | //Совсем пустую секцию к образу добавить нельзя, у нее должен быть ненулевой размер данных или виртуальный размер 42 | section& added_section = image.add_section(new_section); 43 | 44 | //Если нужно изменить виртуальный размер секции, то делается это так: 45 | image.set_section_virtual_size(added_section, 0x1000); 46 | 47 | //Создаем новый PE-файл 48 | std::string base_file_name(argv[1]); 49 | std::string::size_type slash_pos; 50 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 51 | base_file_name = base_file_name.substr(slash_pos + 1); 52 | 53 | base_file_name = "new_" + base_file_name; 54 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 55 | if(!new_pe_file) 56 | { 57 | std::cout << "Cannot create " << base_file_name << std::endl; 58 | return -1; 59 | } 60 | 61 | //Пересобираем PE-файл 62 | rebuild_pe(image, new_pe_file); 63 | 64 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 65 | } 66 | catch(const pe_exception& e) 67 | { 68 | //Если возникла ошибка 69 | std::cout << "Error: " << e.what() << std::endl; 70 | return -1; 71 | } 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /samples/section_adder/section_adder.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/sections_and_addresses/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/sections_and_addresses/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как работать с секциями в PE-файле 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: sections_and_addresses.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Выведем имя секции, в которой находится точка входа PE-файла 33 | //В хитрых PE-файлах точка входа может находиться в заголовке, тогда section_from_rva бросит исключение 34 | std::cout << "EP section name: " << image.section_from_rva(image.get_ep()).get_name() << std::endl; 35 | //Длина "сырых" (raw) данных секции 36 | std::cout << "EP section data length: " << image.section_data_length_from_rva(image.get_ep()) << std::endl; 37 | 38 | //Если у PE-файла есть импорты, выведем имя секции, в которой они находятся 39 | if(image.has_imports()) 40 | std::cout << "Import section name: " << image.section_from_directory(pe_win::image_directory_entry_import).get_name() << std::endl; 41 | } 42 | catch(const pe_exception& e) 43 | { 44 | //Если возникла ошибка 45 | std::cout << "Error: " << e.what() << std::endl; 46 | return -1; 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /samples/sections_and_addresses/sections_and_addresses.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/tls_editor/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/tls_editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как редактировать TLS (Thread Local Storage) у PE-файлов 11 | int main(int argc, char* argv[]) 12 | { 13 | if(argc != 2) 14 | { 15 | std::cout << "Usage: tls_editor.exe PE_FILE" << std::endl; 16 | return 0; 17 | } 18 | 19 | //Открываем файл 20 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 21 | if(!pe_file) 22 | { 23 | std::cout << "Cannot open " << argv[1] << std::endl; 24 | return -1; 25 | } 26 | 27 | try 28 | { 29 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 30 | pe_base image(pe_factory::create_pe(pe_file)); 31 | 32 | //Получим информацию о TLS PE-файла 33 | //Если TLS нет, этот вызов выбросит исключение 34 | tls_info info(get_tls_info(image)); 35 | 36 | //Пересоберем TLS 37 | //Он, вероятно, будет иметь больший размер, чем до нашего редактирования, 38 | //поэтому запишем его в новую секцию, чтобы все поместилось 39 | //(мы не можем расширять существующие секции, если только секция не в самом конце файла) 40 | section new_tls; 41 | new_tls.get_raw_data().resize(1); //Мы не можем добавлять пустые секции, поэтому пусть у нее будет начальный размер данных 1 42 | new_tls.set_name("new_tls"); //Имя секции 43 | new_tls.readable(true); //Доступна на чтение 44 | section& attached_section = image.add_section(new_tls); //Добавим секцию и получим ссылку на добавленную секцию с просчитанными размерами 45 | 46 | if(info.get_callbacks_rva() != 0) //Если у TLS есть хотя бы один коллбек 47 | info.add_tls_callback(0x100); //Добавим новый коллбек в TLS - относительный адрес, скорее всего, некорректен, поэтому программа не запустится (просто для примера) 48 | 49 | info.set_raw_data("Hello, world!"); //Установим или заменим "сырые" данные TLS 50 | info.set_raw_data_start_rva(image.rva_from_section_offset(attached_section, 0)); //Расположим их с начала добавленной секции 51 | info.recalc_raw_data_end_rva(); //Просчитаем новый конечный адрес "сырых" данных 52 | 53 | //Пересобираем TLS, расположив их с 50-го байта (будет выровнено, секция будет автоматически расширена) новой секции и записав новые данные TLS в PE-заголовок 54 | //По умолчанию функция пересобирает также TLS-коллбеки и "сырые" данные TLS, располагая их по указанным в структуре info адресам 55 | //Опция expand позволяет задать, как должны распологаться "сырые" данные 56 | //tls_data_expand_raw позволяет увеличить "сырой" размер секции, то есть размер в файле 57 | //tls_data_expand_virtual позволяет увеличить виртуальный размер секции с данными TLS 58 | //Если не хватит места под данные TLS, будет записана только их часть, или вообще ничего записано не будет 59 | rebuild_tls(image, info, attached_section, 50); 60 | 61 | //Создаем новый PE-файл 62 | std::string base_file_name(argv[1]); 63 | std::string::size_type slash_pos; 64 | if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) 65 | base_file_name = base_file_name.substr(slash_pos + 1); 66 | 67 | base_file_name = "new_" + base_file_name; 68 | std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); 69 | if(!new_pe_file) 70 | { 71 | std::cout << "Cannot create " << base_file_name << std::endl; 72 | return -1; 73 | } 74 | 75 | //Пересобираем PE-файл 76 | rebuild_pe(image, new_pe_file); 77 | 78 | std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; 79 | } 80 | catch(const pe_exception& e) 81 | { 82 | //Если возникла ошибка 83 | std::cout << "Error: " << e.what() << std::endl; 84 | return -1; 85 | } 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /samples/tls_editor/tls_editor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/tls_reader/Makefile: -------------------------------------------------------------------------------- 1 | include ../sample.mak 2 | -------------------------------------------------------------------------------- /samples/tls_reader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef PE_BLISS_WINDOWS 5 | #include "lib.h" 6 | #endif 7 | 8 | using namespace pe_bliss; 9 | 10 | //Пример, показывающий, как считать и получить информацию о статическом TLS (Thread Local Storage, локальная память потока) 11 | //PE или PE+ файла 12 | int main(int argc, char* argv[]) 13 | { 14 | if(argc != 2) 15 | { 16 | std::cout << "Usage: tls_reader.exe PE_FILE" << std::endl; 17 | return 0; 18 | } 19 | 20 | //Открываем файл 21 | std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); 22 | if(!pe_file) 23 | { 24 | std::cout << "Cannot open " << argv[1] << std::endl; 25 | return -1; 26 | } 27 | 28 | try 29 | { 30 | //Создаем экземпляр PE или PE+ класса с помощью фабрики 31 | pe_base image(pe_factory::create_pe(pe_file)); 32 | 33 | std::cout << "Reading PE TLS info..." << std::hex << std::showbase << std::endl << std::endl; 34 | 35 | //Получаем информацию о TLS 36 | const tls_info info = get_tls_info(image); 37 | 38 | //Выводим информацию о TLS 39 | std::cout << "Callbacks RVA: " << info.get_callbacks_rva() << std::endl 40 | << "Index RVA: " << info.get_index_rva() << std::endl 41 | << "Raw data start RVA: " << info.get_raw_data_start_rva() << std::endl 42 | << "Raw data end RVA: " << info.get_raw_data_end_rva() << std::endl 43 | << "Size of zero fill: " << info.get_size_of_zero_fill() << std::endl; 44 | 45 | //Выведем TLS-коллбеки: 46 | const tls_info::tls_callback_list& tls_callbacks = info.get_tls_callbacks(); 47 | for(tls_info::tls_callback_list::const_iterator it = tls_callbacks.begin(); it != tls_callbacks.end(); ++it) 48 | std::cout << "Callback: " << (*it) << std::endl; 49 | } 50 | catch(const pe_exception& e) 51 | { 52 | //Если возникла ошибка 53 | std::cout << "Error: " << e.what() << std::endl; 54 | return -1; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /samples/tls_reader/tls_reader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | TESTS = tests_utils tests_basic test_rich_data test_entropy test_runner test_checksum test_tls test_relocations test_load_config test_exception_directory test_imports test_exports test_resources test_bound_import test_resource_viewer test_dotnet test_debug test_resource_manager test_resource_bitmap test_resource_icon_cursor test_resource_string_table test_resource_message_table test_resource_version_info 2 | OUTDIR = ./bin/ 3 | LIBPATH = ../lib/libpebliss.a 4 | TARGETS = $(foreach test,$(TESTS),$(test)_test) 5 | TARGETS_CLEAN = $(foreach test,$(TESTS),$(test)_clean) 6 | 7 | all: $(TARGETS) run_all_tests 8 | 9 | clean: $(TARGETS_CLEAN) 10 | 11 | $(OUTDIR): 12 | mkdir -p $(OUTDIR) 13 | 14 | %_test: $(OUTDIR) $(LIBPATH) 15 | $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./$* 16 | 17 | %_clean: 18 | $(MAKE) -C ./$* clean 19 | 20 | run_all_tests: 21 | ./bin/test_runner 22 | -------------------------------------------------------------------------------- /tests/lib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _M_X64 3 | #ifdef _DEBUG 4 | #pragma comment(lib, "../../Debug/pe_bliss.lib") 5 | #else 6 | #pragma comment(lib, "../../Release/pe_bliss.lib") 7 | #endif 8 | #else 9 | #ifdef _DEBUG 10 | #pragma comment(lib, "../../x64/Debug/pe_bliss.lib") 11 | #else 12 | #pragma comment(lib, "../../x64/Release/pe_bliss.lib") 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /tests/pe_files/TestApp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/TestApp.exe -------------------------------------------------------------------------------- /tests/pe_files/bound32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/bound32.exe -------------------------------------------------------------------------------- /tests/pe_files/bound64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/bound64.exe -------------------------------------------------------------------------------- /tests/pe_files/debug_test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/debug_test.exe -------------------------------------------------------------------------------- /tests/pe_files/image32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/image32.exe -------------------------------------------------------------------------------- /tests/pe_files/image64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/image64.exe -------------------------------------------------------------------------------- /tests/pe_files/message_table_resource.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/message_table_resource.exe -------------------------------------------------------------------------------- /tests/pe_files/test_dll_32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/test_dll_32.dll -------------------------------------------------------------------------------- /tests/pe_files/test_dll_64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BackupGGCode/portable-executable-library/598b120bf0a51dd48fb73fa648e1953a56c71c73/tests/pe_files/test_dll_64.dll -------------------------------------------------------------------------------- /tests/test_bound_import/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_bound_import/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | void test_bound_imports(const pe_base& image) 12 | { 13 | bound_import_module_list imports; 14 | PE_TEST_EXCEPTION(imports = get_bound_import_module_list(image), "Bound Import Parser test", test_level_critical); 15 | PE_TEST(imports.size() == 2, "Bound Import test 1", test_level_critical); 16 | PE_TEST(imports[0].get_module_name() == "USER32.dll" 17 | && imports[1].get_module_name() == "KERNEL32.dll", "Bound Import test 2", test_level_normal); 18 | 19 | if(image.get_pe_type() == pe_type_32) 20 | { 21 | PE_TEST(imports[0].get_timestamp() == 0x4a5bdb3c 22 | && imports[1].get_timestamp() == 0x4afc68c0, "Bound Import test 3", test_level_normal); 23 | } 24 | else 25 | { 26 | PE_TEST(imports[0].get_timestamp() == 0x4a5bdb3c 27 | && imports[1].get_timestamp() == 0, "Bound Import test 3", test_level_normal); 28 | } 29 | 30 | PE_TEST(imports[0].get_module_ref_count() == 0 31 | && imports[1].get_module_ref_count() == 1, "Bound Import test 4", test_level_critical); 32 | PE_TEST(imports[1].get_module_ref_list()[0].get_module_name() == "NTDLL.DLL" 33 | && imports[1].get_module_ref_list()[0].get_timestamp() == 0x4afc681b, "Bound Import test 5", test_level_normal); 34 | } 35 | 36 | int main(int argc, char* argv[]) 37 | { 38 | PE_TEST_START 39 | 40 | std::auto_ptr pe_file; 41 | if(!open_pe_file(argc, argv, pe_file)) 42 | return -1; 43 | 44 | pe_base image(pe_factory::create_pe(*pe_file)); 45 | test_bound_imports(image); 46 | 47 | { 48 | std::stringstream new_pe(std::ios::in | std::ios::out | std::ios::binary); 49 | PE_TEST_EXCEPTION(rebuild_pe(image, new_pe, false, true, true), "Bound Rebuild PE test 1", test_level_critical); 50 | PE_TEST_EXCEPTION(image = pe_factory::create_pe(new_pe), "Bound Rebuild PE test 2", test_level_critical); 51 | test_bound_imports(image); 52 | 53 | new_pe.str(""); 54 | PE_TEST_EXCEPTION(rebuild_pe(image, new_pe, true, true, true), "Bound Rebuild PE test 3", test_level_critical); 55 | PE_TEST_EXCEPTION(image = pe_factory::create_pe(new_pe), "Bound Rebuild PE test 4", test_level_critical); 56 | test_bound_imports(image); 57 | } 58 | 59 | 60 | section s; 61 | s.get_raw_data().resize(1); 62 | s.set_name("newbound"); 63 | s.readable(true); 64 | section& new_bound_import_section = image.add_section(s); 65 | bound_import_module_list imports; 66 | PE_TEST_EXCEPTION(imports = get_bound_import_module_list(image), "Bound Import Parser test", test_level_critical); 67 | 68 | uint32_t old_bound_import_rva = image.get_directory_rva(pe_win::image_directory_entry_bound_import); 69 | PE_TEST_EXCEPTION(rebuild_bound_imports(image, imports, new_bound_import_section, 0, true, true), "Bound Import Rebuilder test 1", test_level_critical); 70 | PE_TEST(old_bound_import_rva != image.get_directory_rva(pe_win::image_directory_entry_bound_import), "Bound Import Directory test", test_level_normal); 71 | test_bound_imports(image); 72 | 73 | new_bound_import_section.set_raw_data("111"); 74 | old_bound_import_rva = image.get_directory_rva(pe_win::image_directory_entry_bound_import); 75 | PE_TEST_EXCEPTION(rebuild_bound_imports(image, imports, new_bound_import_section, 3, true, true), "Bound Import Rebuilder test 2", test_level_critical); 76 | PE_TEST(new_bound_import_section.get_raw_data().substr(0, 3) == "111", "Bound Import Rebuilder Offset test", test_level_normal); 77 | PE_TEST(old_bound_import_rva != image.get_directory_rva(pe_win::image_directory_entry_bound_import), "Bound Import Directory test 2", test_level_normal); 78 | test_bound_imports(image); 79 | 80 | PE_TEST_END 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /tests/test_bound_import/test_bound_import.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/test_checksum/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_checksum/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | PE_TEST_START 14 | 15 | std::auto_ptr pe_file; 16 | if(!open_pe_file(argc, argv, pe_file)) 17 | return -1; 18 | 19 | pe_base image(pe_factory::create_pe(*pe_file)); 20 | 21 | uint32_t checksum = -1; 22 | PE_TEST_EXCEPTION(checksum = calculate_checksum(*pe_file), "Checksum test 1", test_level_normal); 23 | PE_TEST(image.get_checksum() == checksum, "Checksum test 2", test_level_normal); 24 | 25 | PE_TEST_END 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/test_checksum/test_checksum.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_debug/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_debug/test_debug.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_dotnet/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_dotnet/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | PE_TEST_START 14 | 15 | std::auto_ptr pe_file; 16 | if(!open_pe_file(argc, argv, pe_file)) 17 | return -1; 18 | 19 | pe_base image(pe_factory::create_pe(*pe_file)); 20 | 21 | basic_dotnet_info info; 22 | PE_TEST_EXCEPTION(info = get_basic_dotnet_info(image), "Basic Dotnet Info Parser test", test_level_critical); 23 | PE_TEST(info.get_flags() == 1, "DotNet test 1", test_level_normal); 24 | PE_TEST(info.get_major_runtime_version() == 2 && info.get_minor_runtime_version() == 5, "DotNet test 2", test_level_normal); 25 | PE_TEST(info.get_rva_of_metadata() == 0x2064 && info.get_size_of_metadata() == 0x598, "DotNet test 3", test_level_normal); 26 | PE_TEST(info.get_rva_of_resources() == 0 && info.get_size_of_resources() == 0, "DotNet test 4", test_level_normal); 27 | PE_TEST(info.get_rva_of_strong_name_signature() == 0 && info.get_size_of_strong_name_signature() == 0, "DotNet test 5", test_level_normal); 28 | PE_TEST(info.get_rva_of_code_manager_table() == 0 && info.get_size_of_code_manager_table() == 0, "DotNet test 6", test_level_normal); 29 | PE_TEST(info.get_rva_of_vtable_fixups() == 0 && info.get_size_of_vtable_fixups() == 0, "DotNet test 7", test_level_normal); 30 | PE_TEST(info.get_rva_of_export_address_table_jumps() == 0 && info.get_size_of_export_address_table_jumps() == 0, "DotNet test 8", test_level_normal); 31 | PE_TEST(info.get_rva_of_managed_native_header() == 0 && info.get_size_of_managed_native_header() == 0, "DotNet test 9", test_level_normal); 32 | PE_TEST(info.get_entry_point_rva_or_token() == 0x06000001, "DotNet test 10", test_level_normal); 33 | PE_TEST(!info.is_native_entry_point(), "DotNet test 11", test_level_normal); 34 | PE_TEST(!info.is_32bit_required(), "DotNet test 12", test_level_normal); 35 | 36 | PE_TEST_END 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /tests/test_dotnet/test_dotnet.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_entropy/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_entropy/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | PE_TEST_START 14 | 15 | std::auto_ptr pe_file; 16 | if(!open_pe_file(argc, argv, pe_file)) 17 | return -1; 18 | 19 | pe_base image(pe_factory::create_pe(*pe_file)); 20 | 21 | PE_TEST(entropy_calculator::calculate_entropy(image) > 3.0, "Entropy test 1", test_level_normal); 22 | PE_TEST(entropy_calculator::calculate_entropy(*pe_file) > 3.0, "Entropy test 2", test_level_normal); 23 | PE_TEST(entropy_calculator::calculate_entropy(image.get_image_sections().at(0)) > 3.0, "Entropy test 3", test_level_normal); 24 | 25 | const char data[] = "123456789"; 26 | PE_TEST(entropy_calculator::calculate_entropy(data, sizeof(data) - 1) > 3.0, "Entropy test 4", test_level_normal); 27 | 28 | PE_TEST_EXPECT_EXCEPTION(entropy_calculator::calculate_entropy("", 0), pe_exception::data_is_empty, "Entropy test 5", test_level_normal); 29 | PE_TEST_EXPECT_EXCEPTION(entropy_calculator::calculate_entropy(section()), pe_exception::section_is_empty, "Entropy test 6", test_level_normal); 30 | 31 | PE_TEST_END 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /tests/test_entropy/test_entropy.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_exception_directory/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_exception_directory/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | PE_TEST_START 14 | 15 | std::auto_ptr pe_file; 16 | if(!open_pe_file(argc, argv, pe_file)) 17 | return -1; 18 | 19 | pe_base image(pe_factory::create_pe(*pe_file)); 20 | 21 | if(image.get_pe_type() == pe_type_64) 22 | { 23 | exception_entry_list info; 24 | PE_TEST_EXCEPTION(info = get_exception_directory_data(image), "Exception directory parser test", test_level_critical); 25 | PE_TEST(info.size() == 0x1C6, "Exception directory test 1", test_level_normal); 26 | PE_TEST(info[5].get_begin_address() == 0x000011D5 27 | && info[5].get_end_address() == 0x00001220, "Exception directory test 2", test_level_normal); 28 | PE_TEST(info[5].get_flags() == 4, "Exception directory test 3", test_level_normal); 29 | PE_TEST(info[5].get_unwind_info_address() == 0x21528, "Exception directory test 4", test_level_normal); 30 | PE_TEST(info[5].get_unwind_info_version() == 1, "Exception directory test 5", test_level_normal); 31 | PE_TEST(info[5].get_size_of_prolog() == 0x5, "Exception directory test 6", test_level_normal); 32 | PE_TEST(info[5].get_number_of_unwind_slots() == 2, "Exception directory test 7", test_level_normal); 33 | PE_TEST(info[5].get_frame_pointer_register_number() == 0, "Exception directory test 8", test_level_normal); 34 | PE_TEST(info[5].get_scaled_rsp_offset() == 0, "Exception directory test 9", test_level_normal); 35 | } 36 | 37 | PE_TEST_END 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/test_exception_directory/test_exception_directory.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_exports/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_exports/test_exports.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_imports/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_imports/test_imports.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_load_config/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_load_config/test_load_config.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_relocations/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_relocations/test_relocations.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_bitmap/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_bitmap/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "test.h" 6 | #ifdef PE_BLISS_WINDOWS 7 | #include "lib.h" 8 | #endif 9 | 10 | using namespace pe_bliss; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | PE_TEST_START 15 | 16 | std::auto_ptr pe_file; 17 | if(!open_pe_file(argc, argv, pe_file)) 18 | return -1; 19 | 20 | pe_base image(pe_factory::create_pe(*pe_file)); 21 | 22 | resource_directory root(get_resources(image)); 23 | 24 | pe_resource_manager res(root); 25 | resource_bitmap_reader bmp_read(res); 26 | resource_bitmap_writer bmp_write(res); 27 | 28 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 1", test_level_normal); 29 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(123, L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 2", test_level_normal); 30 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(123), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 3", test_level_normal); 31 | 32 | std::string bitmap; 33 | PE_TEST_EXCEPTION(bitmap = bmp_read.get_bitmap_by_id(102), "Bitmap Reader test 4", test_level_normal); 34 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(102, 1), pe_exception::resource_data_entry_not_found, "Bitmap Reader test 5", test_level_normal); 35 | PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, L"TEST", 1049, 1234, 5678), "Bitmap Writer test 1", test_level_normal); 36 | 37 | std::string bitmap2; 38 | PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_name(1049, L"TEST"), "Bitmap Reader test 6", test_level_critical); 39 | PE_TEST(bitmap == bitmap2, "Bitmap Reader test 7", test_level_normal); 40 | 41 | PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, 9000, 1049, 1234, 5678), "Bitmap Writer test 2", test_level_critical); 42 | PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_id(9000), "Bitmap Reader test 8", test_level_normal); 43 | PE_TEST(bitmap == bitmap2, "Bitmap Reader test 9", test_level_normal); 44 | 45 | PE_TEST_EXCEPTION(bitmap = bmp_read.get_bitmap_by_id(103), "Bitmap Reader test 10", test_level_normal); 46 | PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, 9000, 1049, 1234, 5678), "Bitmap Writer test 3 (bitmap replace test)", test_level_critical); 47 | PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_id(9000), "Bitmap Reader test 11", test_level_normal); 48 | PE_TEST(bitmap == bitmap2, "Bitmap Reader test 12", test_level_normal); 49 | 50 | PE_TEST_EXCEPTION(bmp_write.remove_bitmap(9000, 1049), "Bitmap Writer test 4", test_level_critical); 51 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(9000), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 13", test_level_normal); 52 | 53 | PE_TEST_EXCEPTION(bmp_write.remove_bitmap(L"TEST", 1049), "Bitmap Writer test 5", test_level_critical); 54 | PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 14", test_level_normal); 55 | 56 | PE_TEST_END 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /tests/test_resource_bitmap/test_resource_bitmap.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_icon_cursor/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_manager/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_manager/test_resource_manager.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_message_table/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_message_table/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "test.h" 6 | #ifdef PE_BLISS_WINDOWS 7 | #include "lib.h" 8 | #endif 9 | 10 | using namespace pe_bliss; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | PE_TEST_START 15 | 16 | std::auto_ptr pe_file; 17 | if(!open_pe_file(argc, argv, pe_file)) 18 | return -1; 19 | 20 | pe_base image(pe_factory::create_pe(*pe_file)); 21 | 22 | resource_directory root(get_resources(image)); 23 | 24 | pe_resource_manager res(root); 25 | resource_message_list_reader msg(res); 26 | 27 | resource_message_list messages; 28 | 29 | //Unicode tests 30 | PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1049, 1), "Message Table Parser test 1", test_level_critical); 31 | PE_TEST(messages.size() == 2, "Message Table Parser test 2", test_level_critical); 32 | PE_TEST(messages.find(0x01000000) != messages.end() 33 | && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 3", test_level_critical); 34 | PE_TEST(messages[0xC1000001].is_unicode(), "Message Table Parser test 4", test_level_normal); 35 | PE_TEST(messages[0xC1000001].get_unicode_string() == L"Ошибка!\r\n", "Message Table Parser test 5", test_level_normal); 36 | 37 | PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1033, 1), "Message Table Parser test 6", test_level_critical); 38 | PE_TEST(messages.size() == 2, "Message Table Parser test 7", test_level_critical); 39 | PE_TEST(messages.find(0x01000000) != messages.end() 40 | && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 8", test_level_critical); 41 | PE_TEST(messages[0xC1000001].is_unicode(), "Message Table Parser test 9", test_level_normal); 42 | PE_TEST(messages[0xC1000001].get_unicode_string() == L"Error!\r\n", "Message Table Parser test 10", test_level_normal); 43 | 44 | //ANSI Tests 45 | PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1049, 2), "Message Table Parser test 11", test_level_critical); 46 | PE_TEST(messages.size() == 2, "Message Table Parser test 12", test_level_critical); 47 | PE_TEST(messages.find(0x01000000) != messages.end() 48 | && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 13", test_level_critical); 49 | PE_TEST(!messages[0xC1000001].is_unicode(), "Message Table Parser test 14", test_level_normal); 50 | PE_TEST(messages[0xC1000001].get_ansi_string() == "\xCE\xF8\xE8\xE1\xEA\xE0!\r\n", "Message Table Parser test 15", test_level_normal); //"Ошибка!\r\n" 51 | 52 | PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1033, 2), "Message Table Parser test 16", test_level_critical); 53 | PE_TEST(messages.size() == 2, "Message Table Parser test 17", test_level_critical); 54 | PE_TEST(messages.find(0x01000000) != messages.end() 55 | && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 18", test_level_critical); 56 | PE_TEST(!messages[0xC1000001].is_unicode(), "Message Table Parser test 19", test_level_normal); 57 | PE_TEST(messages[0xC1000001].get_ansi_string() == "Error!\r\n", "Message Table Parser test 20", test_level_normal); 58 | 59 | PE_TEST_END 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /tests/test_resource_message_table/test_resource_message_table.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_string_table/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_string_table/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "test.h" 6 | #ifdef PE_BLISS_WINDOWS 7 | #include "lib.h" 8 | #endif 9 | 10 | using namespace pe_bliss; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | PE_TEST_START 15 | 16 | std::auto_ptr pe_file; 17 | if(!open_pe_file(argc, argv, pe_file)) 18 | return -1; 19 | 20 | pe_base image(pe_factory::create_pe(*pe_file)); 21 | 22 | resource_directory root(get_resources(image)); 23 | 24 | pe_resource_manager res(root); 25 | resource_string_table_reader str(res); 26 | 27 | resource_string_list strings; 28 | PE_TEST_EXCEPTION(strings = str.get_string_table_by_id_lang(1049, 7), "String List Parser test 1", test_level_critical); 29 | PE_TEST(strings.size() == 4, "String List Parser test 2", test_level_critical); 30 | PE_TEST(strings.find(111) != strings.end(), "String List Parser test 3", test_level_critical); 31 | PE_TEST(strings[111] == L"Test String 4", "String List Parser test 4", test_level_normal); 32 | 33 | std::wstring str_111; 34 | PE_TEST_EXCEPTION(str_111 = str.get_string_by_id(111), "String List Parser test 5", test_level_normal); 35 | PE_TEST(str_111 == L"Test String 4", "String List Parser test 6", test_level_normal); 36 | PE_TEST(str_111 == str.get_string_by_id_lang(1049, 111), "String List Parser test 7", test_level_normal); 37 | 38 | PE_TEST_END 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /tests/test_resource_string_table/test_resource_string_table.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_version_info/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_version_info/test_resource_version_info.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resource_viewer/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resource_viewer/test_resource_viewer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_resources/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_resources/test_resources.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_rich_data/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_rich_data/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #ifdef PE_BLISS_WINDOWS 6 | #include "lib.h" 7 | #endif 8 | 9 | using namespace pe_bliss; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | PE_TEST_START 14 | 15 | std::auto_ptr pe_file; 16 | if(!open_pe_file(argc, argv, pe_file)) 17 | return -1; 18 | 19 | pe_base image(pe_factory::create_pe(*pe_file)); 20 | 21 | rich_data_list data; 22 | PE_TEST_EXCEPTION(data = get_rich_data(image), "Rich Data test 1", test_level_critical); 23 | PE_TEST(data.size() == 8, "Rich Data test 2", test_level_normal); 24 | PE_TEST(data[0].get_number() == 158, "Rich Data test 3", test_level_normal); 25 | 26 | if(image.get_pe_type() == pe_type_32) 27 | { 28 | PE_TEST(data[1].get_times() == 47, "Rich Data test 4", test_level_normal); 29 | } 30 | else 31 | { 32 | PE_TEST(data[1].get_times() == 48, "Rich Data test 4", test_level_normal); 33 | } 34 | 35 | PE_TEST(data[2].get_version() == 40219, "Rich Data test 5", test_level_normal); 36 | 37 | PE_TEST_END 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/test_rich_data/test_rich_data.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_runner/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_runner/test_runner.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/test_tls/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/test_tls/test_tls.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/tests.mak: -------------------------------------------------------------------------------- 1 | PWD=$(shell pwd) 2 | OUTDIR = ../bin/ 3 | LIBPATH = ../../lib/libpebliss.a 4 | NAME=$(shell basename $(PWD)) 5 | CXXFLAGS = -O2 -Wall -I../../pe_lib -I../ 6 | 7 | ifdef PE_DEBUG 8 | CXXFLAGS += -g -O0 9 | endif 10 | 11 | all: $(OUTDIR)$(NAME) 12 | 13 | clean: 14 | rm -f $(NAME) *.o 15 | rm -f $(OUTDIR)$(NAME) 16 | 17 | $(NAME): main.o 18 | $(CXX) -Wall $^ -lpebliss -L../../lib -o $(NAME) 19 | 20 | main.o: $(LIBPATH) 21 | 22 | $(OUTDIR)$(NAME): $(NAME) 23 | cp -d $(NAME) $(OUTDIR) 24 | -------------------------------------------------------------------------------- /tests/tests_basic/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/tests_basic/tests_basic.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/tests_utils/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.mak 2 | -------------------------------------------------------------------------------- /tests/tests_utils/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define PE_FILES_UNUSED 5 | #include "test.h" 6 | #ifdef PE_BLISS_WINDOWS 7 | #include "lib.h" 8 | #endif 9 | 10 | using namespace pe_bliss; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | PE_TEST_START 15 | 16 | const char data[] = "abcdefgh"; 17 | PE_TEST(pe_utils::is_null_terminated(data, sizeof(data)), "is_null_terminated test 1", test_level_normal); 18 | PE_TEST(!pe_utils::is_null_terminated(data, sizeof(data) - 1), "is_null_terminated test 2", test_level_normal); 19 | 20 | std::string str("test\0\0\0"); 21 | PE_TEST_EXCEPTION(pe_utils::strip_nullbytes(str), "strip_nullbytes test 1", test_level_normal); 22 | PE_TEST(str == "test", "strip_nullbytes test 2", test_level_normal); 23 | 24 | PE_TEST(pe_utils::is_power_of_2(8), "is_power_of_2 test 1", test_level_normal); 25 | PE_TEST(!pe_utils::is_power_of_2(7), "is_power_of_2 test 2", test_level_normal); 26 | 27 | PE_TEST(pe_utils::align_down(99, 4) == 96, "align_down test 1", test_level_normal); 28 | PE_TEST(pe_utils::align_down(100, 4) == 100, "align_down test 2", test_level_normal); 29 | 30 | PE_TEST(pe_utils::align_up(99, 4) == 100, "align_up test 1", test_level_normal); 31 | PE_TEST(pe_utils::align_up(100, 4) == 100, "align_up test 2", test_level_normal); 32 | 33 | PE_TEST(pe_utils::is_sum_safe(100, 100), "is_sum_safe test 1", test_level_normal); 34 | PE_TEST(!pe_utils::is_sum_safe(pe_utils::max_dword - 1, 2), "is_sum_safe test 2", test_level_normal); 35 | 36 | std::ifstream file(argv[0]); 37 | file.seekg(0, std::ios::end); 38 | std::streamoff size = file.tellg(); 39 | file.seekg(123); 40 | 41 | PE_TEST(pe_utils::get_file_size(file) == size, "get_file_size test 1", test_level_normal); 42 | PE_TEST(static_cast(file.tellg()) == static_cast(123), "get_file_size test 2", test_level_normal); //Restore position test 43 | 44 | #ifndef PE_BLISS_WINDOWS 45 | PE_TEST(pe_utils::from_ucs2(pe_utils::to_ucs2(L"alala")) == L"alala", "to_ucs2 & from_ucs2 test 1", test_level_normal); 46 | PE_TEST(pe_utils::from_ucs2(pe_utils::to_ucs2(L"")) == L"", "to_ucs2 & from_ucs2 test 2", test_level_normal); 47 | #endif 48 | 49 | PE_TEST_END 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /tests/tests_utils/tests_utils.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | --------------------------------------------------------------------------------