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