From 7ef225562563a3172999026910cda2a18de6fde3 Mon Sep 17 00:00:00 2001
From: rukaimi <rukaimi@985867f9-ca9c-e1f6-822d-e8a4186388af>
Date: Fri, 19 Oct 2012 16:45:48 +0000
Subject: [PATCH] 1. Small fix of pe parser for tricky binaries 2. The most
 compact resource rebuilder 3. Other small fixes

---
 pe_lib/pe_32_64.cpp            | 33 +++++++-------
 pe_lib/pe_32_64.h              | 19 +++++----
 pe_lib/pe_base.cpp             | 78 ++++++++++++++++++++++------------
 pe_lib/pe_base.h               | 56 ++++++++++++------------
 pe_lib/pe_resource_manager.cpp |  4 +-
 pe_lib/pe_structures.h         |  2 +-
 6 files changed, 111 insertions(+), 81 deletions(-)

diff --git a/pe_lib/pe_32_64.cpp b/pe_lib/pe_32_64.cpp
index 77035f6..e9ab74e 100644
--- a/pe_lib/pe_32_64.cpp
+++ b/pe_lib/pe_32_64.cpp
@@ -87,7 +87,7 @@ pe<PEClassType>::~pe()
 
 //Returns true if directory exists
 template<typename PEClassType>
-bool pe<PEClassType>::directory_exists(unsigned long id) const
+bool pe<PEClassType>::directory_exists(uint32_t id) const
 {
 	return (nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1) >= id &&
 		nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
@@ -95,7 +95,7 @@ bool pe<PEClassType>::directory_exists(unsigned long id) const
 
 //Removes directory
 template<typename PEClassType>
-void pe<PEClassType>::remove_directory(unsigned long id)
+void pe<PEClassType>::remove_directory(uint32_t id)
 {
 	if(directory_exists(id))
 	{
@@ -116,7 +116,7 @@ void pe<PEClassType>::remove_directory(unsigned long id)
 
 //Returns directory RVA
 template<typename PEClassType>
-uint32_t pe<PEClassType>::get_directory_rva(unsigned long id) const
+uint32_t pe<PEClassType>::get_directory_rva(uint32_t id) const
 {
 	//Check if directory exists
 	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
@@ -127,7 +127,7 @@ uint32_t pe<PEClassType>::get_directory_rva(unsigned long id) const
 
 //Returns directory size
 template<typename PEClassType>
-void pe<PEClassType>::set_directory_rva(unsigned long id, uint32_t va)
+void pe<PEClassType>::set_directory_rva(uint32_t id, uint32_t va)
 {
 	//Check if directory exists
 	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
@@ -137,7 +137,7 @@ void pe<PEClassType>::set_directory_rva(unsigned long id, uint32_t va)
 }
 
 template<typename PEClassType>
-void pe<PEClassType>::set_directory_size(unsigned long id, uint32_t size)
+void pe<PEClassType>::set_directory_size(uint32_t id, uint32_t size)
 {
 	//Check if directory exists
 	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
@@ -148,7 +148,7 @@ void pe<PEClassType>::set_directory_size(unsigned long id, uint32_t size)
 
 //Returns directory size
 template<typename PEClassType>
-uint32_t pe<PEClassType>::get_directory_size(unsigned long id) const
+uint32_t pe<PEClassType>::get_directory_size(uint32_t id) const
 {
 	//Check if directory exists
 	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
@@ -159,19 +159,20 @@ uint32_t pe<PEClassType>::get_directory_size(unsigned long id) const
 
 //Strips only zero DATA_DIRECTORY entries to count = min_count
 //Returns resulting number of data directories
+//strip_iat_directory - if true, even not empty IAT directory will be stripped
 template<typename PEClassType>
-unsigned long pe<PEClassType>::strip_data_directories(uint32_t min_count)
+uint32_t pe<PEClassType>::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
 {
-	uint32_t i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1;
+	int i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1;
 
 	//Enumerate all data directories from the end
 	for(; i >= 0; i--)
 	{
-		//If directory exists (and it is not IMAGE_DIRECTORY_ENTRY_IAT, we can strip it anyway), break
-		if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && i != image_directory_entry_iat)
+		//If directory exists, break
+		if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && (i != image_directory_entry_iat || !strip_iat_directory))
 			break;
 
-		if(i <= min_count - 2)
+		if(i <= static_cast<int>(min_count) - 2)
 			break;
 	}
 
@@ -609,14 +610,14 @@ char* pe<PEClassType>::get_nt_headers_ptr()
 
 //Returns size of NT header
 template<typename PEClassType>
-unsigned long pe<PEClassType>::get_sizeof_nt_header() const
+uint32_t pe<PEClassType>::get_sizeof_nt_header() const
 {
 	return sizeof(typename PEClassType::NtHeaders);
 }
 
 //Returns size of optional headers
 template<typename PEClassType>
-unsigned long pe<PEClassType>::get_sizeof_opt_headers() const
+uint32_t pe<PEClassType>::get_sizeof_opt_headers() const
 {
 	return sizeof(typename PEClassType::OptHeaders);
 }
@@ -1329,9 +1330,9 @@ const pe_base::image_directory pe<PEClassType>::rebuild_tls(const tls_info& info
 		//Convert TLS RVAs to VAs
 		for(tls_info::tls_callback_list::const_iterator it = info.get_tls_callbacks().begin(); it != info.get_tls_callbacks().end(); ++it)
 		{
-			typename PEClassType::BaseSize va = 0;
-			rva_to_va(*it, va);
-			callbacks_virtual_addresses.push_back(va);
+			typename PEClassType::BaseSize cb_va = 0;
+			rva_to_va(*it, cb_va);
+			callbacks_virtual_addresses.push_back(cb_va);
 		}
 
 		//Ending null element
diff --git a/pe_lib/pe_32_64.h b/pe_lib/pe_32_64.h
index fcfa43b..46b9081 100644
--- a/pe_lib/pe_32_64.h
+++ b/pe_lib/pe_32_64.h
@@ -51,24 +51,25 @@ public:
 
 public: //DIRECTORIES
 	//Returns true if directory exists
-	virtual bool directory_exists(unsigned long id) const;
+	virtual bool directory_exists(uint32_t id) const;
 
 	//Removes directory
-	virtual void remove_directory(unsigned long id);
+	virtual void remove_directory(uint32_t id);
 
 	//Returns directory RVA
-	virtual uint32_t get_directory_rva(unsigned long id) const;
+	virtual uint32_t get_directory_rva(uint32_t id) const;
 	//Returns directory size
-	virtual uint32_t get_directory_size(unsigned long id) const;
+	virtual uint32_t get_directory_size(uint32_t id) const;
 
 	//Sets directory RVA (just a value of PE header, no moving occurs)
-	virtual void set_directory_rva(unsigned long id, uint32_t rva);
+	virtual void set_directory_rva(uint32_t id, uint32_t rva);
 	//Sets directory size (just a value of PE header, no moving occurs)
-	virtual void set_directory_size(unsigned long id, uint32_t size);
+	virtual void set_directory_size(uint32_t id, uint32_t size);
 	
 	//Strips only zero DATA_DIRECTORY entries to count = min_count
 	//Returns resulting number of data directories
-	virtual unsigned long strip_data_directories(uint32_t min_count = 1);
+	//strip_iat_directory - if true, even not empty IAT directory will be stripped
+	virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
 
 
 public: //IMAGE
@@ -274,9 +275,9 @@ protected:
 	//Returns nt headers data pointer
 	virtual char* get_nt_headers_ptr();
 	//Returns size of NT header
-	virtual unsigned long get_sizeof_nt_header() const;
+	virtual uint32_t get_sizeof_nt_header() const;
 	//Returns size of optional headers
-	virtual unsigned long get_sizeof_opt_headers() const;
+	virtual uint32_t get_sizeof_opt_headers() const;
 	//Sets file alignment (no checks)
 	virtual void set_file_alignment_unchecked(uint32_t alignment);
 	//Sets base of code
diff --git a/pe_lib/pe_base.cpp b/pe_lib/pe_base.cpp
index 2dca9c6..ee555e0 100644
--- a/pe_lib/pe_base.cpp
+++ b/pe_lib/pe_base.cpp
@@ -295,7 +295,7 @@ const pe_base::section_list& pe_base::get_image_sections() const
 }
 
 //Realigns section by index
-void pe_base::realign_section(unsigned int index)
+void pe_base::realign_section(uint32_t index)
 {
 	//Check index
 	if(sections_.size() <= index)
@@ -377,13 +377,13 @@ const pe_base::section& pe_base::section_from_rva(uint32_t rva) const
 }
 
 //Returns section from directory ID
-pe_base::section& pe_base::section_from_directory(unsigned long directory_id)
+pe_base::section& pe_base::section_from_directory(uint32_t directory_id)
 {
 	return section_from_rva(get_directory_rva(directory_id));		
 }
 
 //Returns section from directory ID
-const pe_base::section& pe_base::section_from_directory(unsigned long directory_id) const
+const pe_base::section& pe_base::section_from_directory(uint32_t directory_id) const
 {
 	return section_from_rva(get_directory_rva(directory_id));	
 }
@@ -616,7 +616,7 @@ const char* pe_base::section_data_from_rva(const section& s, uint32_t rva, secti
 }
 
 //Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
-unsigned long pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
 {
 	//if RVA is inside of headers and we're searching them too...
 	if(include_headers && rva < full_headers_data_.length())
@@ -627,19 +627,19 @@ unsigned long pe_base::section_data_length_from_rva(uint32_t rva, section_data_t
 }
 
 //Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32
-unsigned long pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
 {
 	return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
 }
 
 //Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32/PE64
-unsigned long pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
 {
 	return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
 }
 
 //Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
-unsigned long pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const
 {
 	//if RVAs are inside of headers and we're searching them too...
 	if(include_headers && rva < full_headers_data_.length() && rva_inside < full_headers_data_.length())
@@ -657,19 +657,19 @@ unsigned long pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_i
 }
 
 //Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32
-unsigned long pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const
 {
 	return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
 }
 
 //Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32/PE64
-unsigned long pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const
+uint32_t pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const
 {
 	return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
 }
 
 //Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-unsigned long pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype)
+uint32_t pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype)
 {
 	//Check rva_inside
 	if(rva_inside >= s.header_.VirtualAddress && rva_inside < s.header_.VirtualAddress + s.virtual_size_aligned_)
@@ -688,13 +688,13 @@ unsigned long pe_base::section_data_length_from_rva(const section& s, uint32_t r
 }
 
 //Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 (checks bounds)
-unsigned long pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const
+uint32_t pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const
 {
 	return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
 }
 
 //Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32/PE64 (checks bounds)
-unsigned long pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const
+uint32_t pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const
 {
 	return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
 }
@@ -1167,12 +1167,15 @@ void pe_base::read_pe(std::istream& file, bool read_bound_import_raw_data, bool
 		}
 	}
 
-	//Additionally, read data from the beginning of istream to size of headers
-	file.seekg(0);
-	full_headers_data_.resize(get_size_of_headers());
-	file.read(&full_headers_data_[0], get_size_of_headers());
-	if(file.bad() || file.eof())
-		throw pe_exception("Error reading file", pe_exception::error_reading_file);
+	{
+		//Additionally, read data from the beginning of istream to size of headers
+		file.seekg(0);
+		uint32_t size_of_headers = std::min<uint32_t>(get_size_of_headers(), static_cast<uint32_t>(filesize));
+		full_headers_data_.resize(size_of_headers);
+		file.read(&full_headers_data_[0], size_of_headers);
+		if(file.bad() || file.eof())
+			throw pe_exception("Error reading file", pe_exception::error_reading_file);
+	}
 
 	//Moreover, if there's debug directory, read its raw data for some debug info types
 	while(read_debug_raw_data && has_debug())
@@ -3756,7 +3759,7 @@ const pe_base::resource_directory pe_base::process_resource_directory(uint32_t r
 }
 
 //Helper function to calculate needed space for resource data
-void pe_base::calculate_resource_data_space(const resource_directory& root, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings, uint32_t& needed_size_for_data)
+void pe_base::calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings)
 {
 	needed_size_for_structures += sizeof(image_resource_directory);
 	for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
@@ -3766,15 +3769,31 @@ void pe_base::calculate_resource_data_space(const resource_directory& root, uint
 		if((*it).is_named())
 			needed_size_for_strings += static_cast<uint32_t>(((*it).get_name().length() + 1) * 2 /* unicode */ + sizeof(uint16_t) /* for string length */);
 
+		if(!(*it).includes_data())
+			calculate_resource_data_space((*it).get_resource_directory(), aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
+	}
+}
+
+//Helper function to calculate needed space for resource data
+void pe_base::calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos)
+{
+	for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
+	{
 		if((*it).includes_data())
-			needed_size_for_data += static_cast<uint32_t>((*it).get_data_entry().get_data().length() + sizeof(image_resource_data_entry) + sizeof(uint32_t) /* overhead for alignment */);
+		{
+			uint32_t data_size = static_cast<uint32_t>((*it).get_data_entry().get_data().length() + sizeof(image_resource_data_entry) + (align_up(current_data_pos, sizeof(uint32_t)) - current_data_pos) /* alignment */);
+			needed_size_for_data += data_size;
+			current_data_pos += data_size;
+		}
 		else
-			calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data);
+		{
+			calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
+		}
 	}
 }
 
 //Helper function to rebuild resource directory
-void pe_base::rebuild_resource_directory(section& resource_section, resource_directory& root, unsigned long& current_structures_pos, unsigned long& current_data_pos, unsigned long& current_strings_pos, unsigned long offset_from_section_start)
+void pe_base::rebuild_resource_directory(section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start)
 {
 	//Create resource directory
 	image_resource_directory dir = {0};
@@ -3899,7 +3918,12 @@ const pe_base::image_directory pe_base::rebuild_resources(resource_directory& in
 	uint32_t needed_size_for_strings = 0;
 	uint32_t needed_size_for_data = 0;
 
-	calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data);
+	calculate_resource_data_space(info, aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
+
+	{
+		uint32_t current_data_pos = aligned_offset_from_section_start + needed_size_for_structures + needed_size_for_strings;
+		calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
+	}
 
 	uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data;
 
@@ -3915,9 +3939,9 @@ const pe_base::image_directory pe_base::rebuild_resources(resource_directory& in
 	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;
-	unsigned long current_strings_pos = current_structures_pos + needed_size_for_structures;
-	unsigned long current_data_pos = current_strings_pos + needed_size_for_strings;
+	uint32_t current_structures_pos = aligned_offset_from_section_start;
+	uint32_t current_strings_pos = current_structures_pos + needed_size_for_structures;
+	uint32_t current_data_pos = current_strings_pos + needed_size_for_strings;
 	rebuild_resource_directory(resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start);
 	
 	//Adjust section raw and virtual sizes
@@ -5287,7 +5311,7 @@ void pe_base::image_directory::set_size(uint32_t size)
 }
 
 //Realigns file (changes file alignment)
-void pe_base::realign_file(unsigned long new_file_alignment)
+void pe_base::realign_file(uint32_t new_file_alignment)
 {
 	//Checks alignment for correctness
 	set_file_alignment(new_file_alignment);
diff --git a/pe_lib/pe_base.h b/pe_lib/pe_base.h
index c49b3fc..c5b5e67 100644
--- a/pe_lib/pe_base.h
+++ b/pe_lib/pe_base.h
@@ -11,9 +11,9 @@
 #include "pe_structures.h"
 
 //Please don't remove this information from header
-//PEBliss 0.2.3
+//PEBliss 0.2.4
 //(c) DX 2011 - 2012, http://kaimi.ru
-//Free to use, modify and distribute
+//Free to use for commertial and non-commertial purposes, modify and distribute
 
 // == more important ==
 //TODO: create sample-based tests
@@ -199,23 +199,24 @@ public: //DIRECTORIES
 	};
 
 	//Returns true if directory exists
-	virtual bool directory_exists(unsigned long id) const = 0;
+	virtual bool directory_exists(uint32_t id) const = 0;
 	//Removes directory
-	virtual void remove_directory(unsigned long id) = 0;
+	virtual void remove_directory(uint32_t id) = 0;
 
 	//Returns directory RVA
-	virtual uint32_t get_directory_rva(unsigned long id) const = 0;
+	virtual uint32_t get_directory_rva(uint32_t id) const = 0;
 	//Returns directory size
-	virtual uint32_t get_directory_size(unsigned long id) const = 0;
+	virtual uint32_t get_directory_size(uint32_t id) const = 0;
 
 	//Sets directory RVA (just a value of PE header, no moving occurs)
-	virtual void set_directory_rva(unsigned long id, uint32_t rva) = 0;
+	virtual void set_directory_rva(uint32_t id, uint32_t rva) = 0;
 	//Sets directory size (just a value of PE header, no moving occurs)
-	virtual void set_directory_size(unsigned long id, uint32_t size) = 0;
+	virtual void set_directory_size(uint32_t id, uint32_t size) = 0;
 
 	//Strips only zero DATA_DIRECTORY entries to count = min_count
 	//Returns resulting number of data directories
-	virtual unsigned long strip_data_directories(uint32_t min_count = 1) = 0;
+	//strip_iat_directory - if true, even not empty IAT directory will be stripped
+	virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true) = 0;
 
 	//Returns true if image has import directory
 	bool has_imports() const;
@@ -431,14 +432,14 @@ public: //IMAGE SECTIONS
 	//Realigns all sections, if you made any changes to sections or alignments
 	void realign_all_sections();
 	//Resligns section with specified index
-	void realign_section(unsigned int index);
+	void realign_section(uint32_t index);
 
 	//Returns section from RVA inside it
 	section& section_from_rva(uint32_t rva);
 	const section& section_from_rva(uint32_t rva) const;
 	//Returns section from directory ID
-	section& section_from_directory(unsigned long directory_id);
-	const section& section_from_directory(unsigned long directory_id) const;
+	section& section_from_directory(uint32_t directory_id);
+	const section& section_from_directory(uint32_t directory_id) const;
 	//Returns section from VA inside it for PE32 and PE64 respectively
 	section& section_from_va(uint32_t va);
 	const section& section_from_va(uint32_t va) const;
@@ -450,25 +451,25 @@ public: //IMAGE SECTIONS
 
 	//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
 	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	unsigned long section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
 	//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 and PE64 respectively
 	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	unsigned long section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	unsigned long section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
 
 	//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-	static unsigned long section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw);
+	static uint32_t section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw);
 	//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 and PE64 respectively (checks bounds)
-	unsigned long section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const;
-	unsigned long section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const;
+	uint32_t section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const;
+	uint32_t section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const;
 
 	//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
 	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	unsigned long section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
 	//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 and PE64 respectively
 	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	unsigned long section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	unsigned long section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
+	uint32_t section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
 	
 	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
 	//Returns corresponding section data pointer from RVA inside section
@@ -612,7 +613,7 @@ public: //IMAGE
 	void rebuild_pe(std::ostream& out, bool strip_dos_header = false, bool change_size_of_headers = true);
 
 	//Realigns file (changes file alignment)
-	void realign_file(unsigned long new_file_alignment);
+	void realign_file(uint32_t new_file_alignment);
 
 public: //EXPORTS
 	//Structure representing exported function
@@ -2100,9 +2101,9 @@ protected:
 	//Returns nt headers data pointer
 	virtual char* get_nt_headers_ptr() = 0;
 	//Returns sizeof() nt headers
-	virtual unsigned long get_sizeof_nt_header() const = 0;
+	virtual uint32_t get_sizeof_nt_header() const = 0;
 	//Returns sizeof() optional headers
-	virtual unsigned long get_sizeof_opt_headers() const = 0;
+	virtual uint32_t get_sizeof_opt_headers() const = 0;
 	//Sets file alignment (no checks)
 	virtual void set_file_alignment_unchecked(uint32_t alignment) = 0;
 	//Sets base of code
@@ -2166,10 +2167,13 @@ private:
 	};
 
 	//Helper function to calculate needed space for resource data
-	void calculate_resource_data_space(const resource_directory& root, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings, uint32_t& needed_size_for_data);
+	void calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings);
+	
+	//Helper function to calculate needed space for resource data
+	void calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos);
 
 	//Helper function to rebuild resource directory
-	void rebuild_resource_directory(section& resource_section, resource_directory& root, unsigned long& current_structures_pos, unsigned long& current_data_pos, unsigned long& current_strings_pos, unsigned long offset_from_section_start);
+	void rebuild_resource_directory(section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start);
 
 	//Calculates entropy from bytes count
 	static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length);
diff --git a/pe_lib/pe_resource_manager.cpp b/pe_lib/pe_resource_manager.cpp
index d033df2..44ac390 100644
--- a/pe_lib/pe_resource_manager.cpp
+++ b/pe_lib/pe_resource_manager.cpp
@@ -393,7 +393,7 @@ const std::string pe_resource_viewer::create_bitmap(const std::string& resource_
 const std::string pe_resource_viewer::get_bitmap_by_name(const std::wstring& name, uint32_t index) const
 {
 	return create_bitmap(get_resource_data_by_name(resource_bitmap, name, index).get_data());
-};
+}
 
 //Returns bitmap data by name and language (minimum checks of format correctness)
 const std::string pe_resource_viewer::get_bitmap_by_name(uint32_t language, const std::wstring& name) const
@@ -405,7 +405,7 @@ const std::string pe_resource_viewer::get_bitmap_by_name(uint32_t language, cons
 const std::string pe_resource_viewer::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const
 {
 	return create_bitmap(get_resource_data_by_id(language, resource_bitmap, id).get_data());
-};
+}
 
 //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
 const std::string pe_resource_viewer::get_bitmap_by_id(uint32_t id, uint32_t index) const
diff --git a/pe_lib/pe_structures.h b/pe_lib/pe_structures.h
index fbd8dc6..4508341 100644
--- a/pe_lib/pe_structures.h
+++ b/pe_lib/pe_structures.h
@@ -933,7 +933,7 @@ enum replaces_cor_hdr_numeric_defines
 	// Max name lengths
 	//@todo: Change to unlimited name lengths.
 	max_class_name                      =1024,
-	max_package_name                    =1024,
+	max_package_name                    =1024
 };
 
 /// Load Configuration Directory Entry ///
-- 
GitLab