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