From d1c5dfb60566bae7f740a1ac052bfa3daf1eff06 Mon Sep 17 00:00:00 2001 From: rukaimi <rukaimi@985867f9-ca9c-e1f6-822d-e8a4186388af> Date: Thu, 18 Oct 2012 15:42:37 +0000 Subject: [PATCH] 1. Some new constants in pe_structures.h 2. Some new functions in section class 3. Resource and TLS rebuilders bugfixes --- pe_lib/pe_32_64.cpp | 8 +++--- pe_lib/pe_base.cpp | 60 +++++++++++++++++++++++++++--------------- pe_lib/pe_base.h | 9 ++++++- pe_lib/pe_structures.h | 11 ++++++++ 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/pe_lib/pe_32_64.cpp b/pe_lib/pe_32_64.cpp index 9c578b4..77035f6 100644 --- a/pe_lib/pe_32_64.cpp +++ b/pe_lib/pe_32_64.cpp @@ -1214,9 +1214,9 @@ const pe_base::image_directory pe<PEClassType>::rebuild_tls(const tls_info& info //Check that tls_section is attached to this PE image if(!section_attached(tls_section)) throw pe_exception("TLS section must be attached to PE file", pe_exception::section_is_not_attached); - - uint32_t needed_size = sizeof(typename PEClassType::TLSStruct) + sizeof(typename PEClassType::BaseSize); //Calculate needed size for TLS table - //sizeof(typename PEClassType::BaseSize) = for DWORD/QWORD alignment + + uint32_t tls_data_pos = align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)); + uint32_t needed_size = sizeof(typename PEClassType::TLSStruct) + (tls_data_pos - offset_from_section_start); //Calculate needed size for TLS table //Check if tls_section is last one. If it's not, check if there's enough place for TLS data if(&tls_section != &*(sections_.end() - 1) && @@ -1233,8 +1233,6 @@ const pe_base::image_directory pe<PEClassType>::rebuild_tls(const tls_info& info if(raw_data.length() < needed_size + offset_from_section_start) raw_data.resize(needed_size + offset_from_section_start); //Expand section raw data - uint32_t tls_data_pos = align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)); - //Create and fill TLS structure typename PEClassType::TLSStruct tls_struct = {0}; diff --git a/pe_lib/pe_base.cpp b/pe_lib/pe_base.cpp index ada3630..2dca9c6 100644 --- a/pe_lib/pe_base.cpp +++ b/pe_lib/pe_base.cpp @@ -45,37 +45,45 @@ const std::string pe_base::section::get_name() const return std::string(buf); } -//Sets "readable" attribute of section -pe_base::section& pe_base::section::readable(bool readable) +//Set flag (attribute) of section +pe_base::section& pe_base::section::set_flag(uint32_t flag, bool setflag) { - if(readable) - header_.Characteristics |= image_scn_mem_read; + if(setflag) + header_.Characteristics |= flag; else - header_.Characteristics &= ~image_scn_mem_read; + header_.Characteristics &= ~flag; return *this; } +//Sets "readable" attribute of section +pe_base::section& pe_base::section::readable(bool readable) +{ + return set_flag(image_scn_mem_read, readable); +} + //Sets "writeable" attribute of section pe_base::section& pe_base::section::writeable(bool writeable) { - if(writeable) - header_.Characteristics |= image_scn_mem_write; - else - header_.Characteristics &= ~image_scn_mem_write; - - return *this; + return set_flag(image_scn_mem_write, writeable); } //Sets "executable" attribute of section pe_base::section& pe_base::section::executable(bool executable) { - if(executable) - header_.Characteristics |= image_scn_mem_execute; - else - header_.Characteristics &= ~image_scn_mem_execute; + return set_flag(image_scn_mem_execute, executable); +} - return *this; +//Sets "shared" attribute of section +pe_base::section& pe_base::section::shared(bool shared) +{ + return set_flag(image_scn_mem_shared, shared); +} + +//Sets "discardable" attribute of section +pe_base::section& pe_base::section::discardable(bool discardable) +{ + return set_flag(image_scn_mem_discardable, discardable); } //Returns true if section is readable @@ -96,6 +104,16 @@ bool pe_base::section::executable() const return (header_.Characteristics & image_scn_mem_execute) != 0; } +bool pe_base::section::shared() const +{ + return (header_.Characteristics & image_scn_mem_shared) != 0; +} + +bool pe_base::section::discardable() const +{ + return (header_.Characteristics & image_scn_mem_discardable) != 0; +} + //Returns true if section has no RAW data bool pe_base::section::empty() const { @@ -3875,15 +3893,15 @@ const pe_base::image_directory pe_base::rebuild_resources(resource_directory& in //Check resource directory correctness if(info.get_entry_list().empty()) throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory); - - uint32_t needed_size_for_structures = sizeof(uint32_t); //Calculate needed size for resource tables and data + + uint32_t aligned_offset_from_section_start = align_up(offset_from_section_start, sizeof(uint32_t)); + uint32_t needed_size_for_structures = aligned_offset_from_section_start - offset_from_section_start; //Calculate needed size for resource tables and data uint32_t needed_size_for_strings = 0; uint32_t needed_size_for_data = 0; - //sizeof(uint32_t) - for DWORD alignment + calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data); uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data; - uint32_t aligned_offset_from_section_start = align_up(offset_from_section_start, sizeof(uint32_t)); //Check if exports_section is last one. If it's not, check if there's enough place for resource data if(&resources_section != &*(sections_.end() - 1) && @@ -3894,7 +3912,7 @@ const pe_base::image_directory pe_base::rebuild_resources(resource_directory& in std::string& raw_data = resources_section.get_raw_data(); //This will be done only is resources_section is the last section of image or for section with unaligned raw length of data - if(raw_data.length() < needed_size + needed_size + aligned_offset_from_section_start) + if(raw_data.length() < needed_size + aligned_offset_from_section_start) raw_data.resize(needed_size + aligned_offset_from_section_start); //Expand section raw data unsigned long current_structures_pos = aligned_offset_from_section_start; diff --git a/pe_lib/pe_base.h b/pe_lib/pe_base.h index 018fa16..c49b3fc 100644 --- a/pe_lib/pe_base.h +++ b/pe_lib/pe_base.h @@ -11,7 +11,7 @@ #include "pe_structures.h" //Please don't remove this information from header -//PEBliss 0.2.2 +//PEBliss 0.2.3 //(c) DX 2011 - 2012, http://kaimi.ru //Free to use, modify and distribute @@ -83,11 +83,15 @@ public: //SECTIONS section& readable(bool readable); section& writeable(bool writeable); section& executable(bool executable); + section& shared(bool shared); + section& discardable(bool discardable); //Returns attributes of section bool readable() const; bool writeable() const; bool executable() const; + bool shared() const; + bool discardable() const; //Returns true if section has no RAW data bool empty() const; @@ -145,6 +149,9 @@ public: //SECTIONS //Unmaps virtual section data void unmap_virtual() const; + //Set flag (attribute) of section + section& set_flag(uint32_t flag, bool setflag); + //Old size of section (stored after mapping of virtual section memory) mutable std::size_t old_size_; diff --git a/pe_lib/pe_structures.h b/pe_lib/pe_structures.h index ba37fc5..fbd8dc6 100644 --- a/pe_lib/pe_structures.h +++ b/pe_lib/pe_structures.h @@ -17,6 +17,13 @@ const uint32_t image_resource_name_is_string = 0x80000000; const uint32_t image_resource_data_is_directory = 0x80000000; const uint32_t image_dllcharacteristics_dynamic_base = 0x0040; // DLL can move. +const uint32_t image_dllcharacteristics_force_integrity = 0x0080; // Code Integrity Image +const uint32_t image_dllcharacteristics_nx_compat = 0x0100; // Image is NX compatible +const uint32_t image_dllcharacteristics_no_isolation = 0x0200; // Image understands isolation and doesn't want it +const uint32_t image_dllcharacteristics_no_seh = 0x0400; // Image does not use SEH. No SE handler may reside in this image +const uint32_t image_dllcharacteristics_no_bind = 0x0800; // Do not bind this image. +const uint32_t image_dllcharacteristics_wdm_driver = 0x2000; // Driver uses WDM model +const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000; const uint32_t image_sizeof_file_header = 20; @@ -45,6 +52,10 @@ const uint32_t image_scn_mem_execute = 0x20000000; // Section is executable. const uint32_t image_scn_mem_read = 0x40000000; // Section is readable. const uint32_t image_scn_mem_write = 0x80000000; // Section is writeable. +const uint32_t image_scn_cnt_code = 0x00000020; // Section contains code. +const uint32_t image_scn_cnt_initialized_data = 0x00000040; // Section contains initialized data. +const uint32_t image_scn_cnt_uninitialized_data = 0x00000080; // Section contains uninitialized data. + //Directory Entries const uint32_t image_directory_entry_export = 0; // Export Directory const uint32_t image_directory_entry_import = 1; // Import Directory -- GitLab