本文整理汇总了C++中pe_base::get_file_alignment方法的典型用法代码示例。如果您正苦于以下问题:C++ pe_base::get_file_alignment方法的具体用法?C++ pe_base::get_file_alignment怎么用?C++ pe_base::get_file_alignment使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类pe_base
的用法示例。
在下文中一共展示了pe_base::get_file_alignment方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: rebuild_bound_imports
//imports - bound imported modules list
//imports_section - section where export directory will be placed (must be attached to PE image)
//offset_from_section_start - offset from imports_section raw data start
//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
{
//Check that exports_section is attached to this PE image
if(!pe.section_attached(imports_section))
throw pe_exception("Bound import section must be attached to PE file", pe_exception::section_is_not_attached);
uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
uint32_t needed_size = sizeof(image_bound_import_descriptor) /* Ending null descriptor */;
uint32_t needed_size_for_strings = 0;
//Calculate needed size for bound import data
for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
{
const bound_import& import = *it;
needed_size += sizeof(image_bound_import_descriptor);
needed_size_for_strings += static_cast<uint32_t>((*it).get_module_name().length()) + 1 /* nullbyte */;
const bound_import::ref_list& refs = import.get_module_ref_list();
for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
{
needed_size_for_strings += static_cast<uint32_t>((*ref_it).get_module_name().length()) + 1 /* nullbyte */;
needed_size += sizeof(image_bound_forwarder_ref);
}
}
needed_size += needed_size_for_strings;
//Check if imports_section is last one. If it's not, check if there's enough place for bound import data
if(&imports_section != &*(pe.get_image_sections().end() - 1) &&
(imports_section.empty() || pe_utils::align_up(imports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
throw pe_exception("Insufficient space for bound import directory", pe_exception::insufficient_space);
std::string& raw_data = imports_section.get_raw_data();
//This will be done only if imports_section is the last section of image or for section with unaligned raw length of data
if(raw_data.length() < needed_size + directory_pos)
raw_data.resize(needed_size + directory_pos); //Expand section raw data
uint32_t current_pos_for_structures = directory_pos;
uint32_t current_pos_for_strings = current_pos_for_structures + needed_size - needed_size_for_strings;
for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
{
const bound_import& import = *it;
image_bound_import_descriptor descriptor;
descriptor.NumberOfModuleForwarderRefs = static_cast<uint16_t>(import.get_module_ref_list().size());
descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
descriptor.TimeDateStamp = import.get_timestamp();
memcpy(&raw_data[current_pos_for_structures], &descriptor, sizeof(descriptor));
current_pos_for_structures += sizeof(descriptor);
size_t length = import.get_module_name().length() + 1 /* nullbyte */;
memcpy(&raw_data[current_pos_for_strings], import.get_module_name().c_str(), length);
current_pos_for_strings += static_cast<uint32_t>(length);
const bound_import::ref_list& refs = import.get_module_ref_list();
for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
{
const bound_import_ref& ref = *ref_it;
image_bound_forwarder_ref ref_descriptor = {0};
ref_descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
ref_descriptor.TimeDateStamp = ref.get_timestamp();
memcpy(&raw_data[current_pos_for_structures], &ref_descriptor, sizeof(ref_descriptor));
current_pos_for_structures += sizeof(ref_descriptor);
length = ref.get_module_name().length() + 1 /* nullbyte */;
memcpy(&raw_data[current_pos_for_strings], ref.get_module_name().c_str(), length);
current_pos_for_strings += static_cast<uint32_t>(length);
}
}
//Adjust section raw and virtual sizes
pe.recalculate_section_sizes(imports_section, auto_strip_last_section);
image_directory ret(pe.rva_from_section_offset(imports_section, directory_pos), needed_size);
//If auto-rewrite of PE headers is required
if(save_to_pe_header)
{
pe.set_directory_rva(image_directory_entry_bound_import, ret.get_rva());
pe.set_directory_size(image_directory_entry_bound_import, ret.get_size());
}
return ret;
}
示例2: rebuild_image_config_base
const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
{
//Check that image_config_section is attached to this PE image
if(!pe.section_attached(image_config_section))
throw pe_exception("Image Config section must be attached to PE file", pe_exception::section_is_not_attached);
uint32_t alignment = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)) - offset_from_section_start;
uint32_t needed_size = sizeof(typename PEClassType::ConfigStruct); //Calculate needed size for Image Config table
uint32_t image_config_data_pos = offset_from_section_start + alignment;
uint32_t current_pos_of_se_handlers = 0;
uint32_t current_pos_of_lock_prefixes = 0;
if(write_se_handlers)
{
current_pos_of_se_handlers = needed_size + image_config_data_pos;
needed_size += static_cast<uint32_t>(info.get_se_handler_rvas().size()) * sizeof(uint32_t); //RVAs of SE Handlers
}
if(write_lock_prefixes)
{
current_pos_of_lock_prefixes = needed_size + image_config_data_pos;
needed_size += static_cast<uint32_t>((info.get_lock_prefix_rvas().size() + 1) * sizeof(typename PEClassType::BaseSize)); //VAs of Lock Prefixes (and ending null element)
}
//Check if image_config_section is last one. If it's not, check if there's enough place for Image Config data
if(&image_config_section != &*(pe.get_image_sections().end() - 1) &&
(image_config_section.empty() || pe_utils::align_up(image_config_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + image_config_data_pos))
throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
std::string& raw_data = image_config_section.get_raw_data();
//This will be done only if image_config_section is the last section of image or for section with unaligned raw length of data
if(raw_data.length() < needed_size + image_config_data_pos)
raw_data.resize(needed_size + image_config_data_pos); //Expand section raw data
//Create and fill Image Config structure
typename PEClassType::ConfigStruct image_config_section_struct = {0};
image_config_section_struct.Size = sizeof(image_config_section_struct);
image_config_section_struct.TimeDateStamp = info.get_time_stamp();
image_config_section_struct.MajorVersion = info.get_major_version();
image_config_section_struct.MinorVersion = info.get_minor_version();
image_config_section_struct.GlobalFlagsClear = info.get_global_flags_clear();
image_config_section_struct.GlobalFlagsSet = info.get_global_flags_set();
image_config_section_struct.CriticalSectionDefaultTimeout = info.get_critical_section_default_timeout();
image_config_section_struct.DeCommitFreeBlockThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_free_block_threshold());
image_config_section_struct.DeCommitTotalFreeThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_total_free_threshold());
image_config_section_struct.MaximumAllocationSize = static_cast<typename PEClassType::BaseSize>(info.get_max_allocation_size());
image_config_section_struct.VirtualMemoryThreshold = static_cast<typename PEClassType::BaseSize>(info.get_virtual_memory_threshold());
image_config_section_struct.ProcessHeapFlags = info.get_process_heap_flags();
image_config_section_struct.ProcessAffinityMask = static_cast<typename PEClassType::BaseSize>(info.get_process_affinity_mask());
image_config_section_struct.CSDVersion = info.get_service_pack_version();
image_config_section_struct.EditList = static_cast<typename PEClassType::BaseSize>(info.get_edit_list_va());
image_config_section_struct.SecurityCookie = static_cast<typename PEClassType::BaseSize>(info.get_security_cookie_va());
image_config_section_struct.SEHandlerCount = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_rvas().size());
if(write_se_handlers)
{
if(info.get_se_handler_rvas().empty())
{
write_se_handlers = false;
image_config_section_struct.SEHandlerTable = 0;
}
else
{
typename PEClassType::BaseSize va;
pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_se_handlers), va);
image_config_section_struct.SEHandlerTable = va;
}
}
else
{
image_config_section_struct.SEHandlerTable = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_table_va());
}
if(write_lock_prefixes)
{
if(info.get_lock_prefix_rvas().empty())
{
write_lock_prefixes = false;
image_config_section_struct.LockPrefixTable = 0;
}
else
{
typename PEClassType::BaseSize va;
pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_lock_prefixes), va);
image_config_section_struct.LockPrefixTable = va;
}
}
else
{
image_config_section_struct.LockPrefixTable = static_cast<typename PEClassType::BaseSize>(info.get_lock_prefix_table_va());
}
//Write image config section
memcpy(&raw_data[image_config_data_pos], &image_config_section_struct, sizeof(image_config_section_struct));
//.........这里部分代码省略.........
示例3: rebuild_exports
//Export directory rebuilder
//info - export information
//exported_functions_list - list of exported functions
//exports_section - section where export directory will be placed (must be attached to PE image)
//offset_from_section_start - offset from exports_section raw data start
//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
//Returns new export directory information
//exported_functions_list is copied intentionally to be sorted by ordinal values later
//Name ordinals in exported function don't matter, they will be recalculated
const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
{
//Check that exports_section is attached to this PE image
if(!pe.section_attached(exports_section))
throw pe_exception("Exports section must be attached to PE file", pe_exception::section_is_not_attached);
//Needed space for strings
uint32_t needed_size_for_strings = static_cast<uint32_t>(info.get_name().length() + 1);
uint32_t number_of_names = 0; //Number of named functions
uint32_t max_ordinal = 0; //Maximum ordinal number
uint32_t ordinal_base = static_cast<uint32_t>(-1); //Minimum ordinal value
if(exports.empty())
ordinal_base = info.get_ordinal_base();
uint32_t needed_size_for_function_names = 0; //Needed space for function name strings
uint32_t needed_size_for_function_forwards = 0; //Needed space for function forwards names
//List all exported functions
//Calculate needed size for function list
{
//Also check that there're no duplicate names and ordinals
std::set<std::string> used_function_names;
std::set<uint16_t> used_function_ordinals;
for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
{
const exported_function& func = (*it);
//Calculate maximum and minimum ordinal numbers
max_ordinal = std::max<uint32_t>(max_ordinal, func.get_ordinal());
ordinal_base = std::min<uint32_t>(ordinal_base, func.get_ordinal());
//Check if ordinal is unique
if(!used_function_ordinals.insert(func.get_ordinal()).second)
throw pe_exception("Duplicate exported function ordinal", pe_exception::duplicate_exported_function_ordinal);
if(func.has_name())
{
//If function is named
++number_of_names;
needed_size_for_function_names += static_cast<uint32_t>(func.get_name().length() + 1);
//Check if it's name and name ordinal are unique
if(!used_function_names.insert(func.get_name()).second)
throw pe_exception("Duplicate exported function name", pe_exception::duplicate_exported_function_name);
}
//If function is forwarded to another DLL
if(func.is_forwarded())
needed_size_for_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
}
}
//Sort functions by ordinal value
std::sort(exports.begin(), exports.end(), ordinal_sorter());
//Calculate needed space for different things...
needed_size_for_strings += needed_size_for_function_names;
needed_size_for_strings += needed_size_for_function_forwards;
uint32_t needed_size_for_function_name_ordinals = number_of_names * sizeof(uint16_t);
uint32_t needed_size_for_function_name_rvas = number_of_names * sizeof(uint32_t);
uint32_t needed_size_for_function_addresses = (max_ordinal - ordinal_base + 1) * sizeof(uint32_t);
//Export directory header will be placed first
uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
uint32_t needed_size = sizeof(image_export_directory); //Calculate needed size for export tables and strings
//sizeof(IMAGE_EXPORT_DIRECTORY) = export directory header
//Total needed space...
needed_size += needed_size_for_function_name_ordinals; //For list of names ordinals
needed_size += needed_size_for_function_addresses; //For function RVAs
needed_size += needed_size_for_strings; //For all strings
needed_size += needed_size_for_function_name_rvas; //For function name strings RVAs
//Check if exports_section is last one. If it's not, check if there's enough place for exports data
if(&exports_section != &*(pe.get_image_sections().end() - 1) &&
(exports_section.empty() || pe_utils::align_up(exports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
throw pe_exception("Insufficient space for export directory", pe_exception::insufficient_space);
std::string& raw_data = exports_section.get_raw_data();
//This will be done only if exports_section is the last section of image or for section with unaligned raw length of data
if(raw_data.length() < needed_size + directory_pos)
raw_data.resize(needed_size + directory_pos); //Expand section raw data
//Library name will be placed after it
uint32_t current_pos_of_function_names = static_cast<uint32_t>(info.get_name().length() + 1 + directory_pos + sizeof(image_export_directory));
//.........这里部分代码省略.........
示例4: rebuild_pe
//Rebuilds PE image headers
//If strip_dos_header is true, DOS headers partially will be used for PE headers
//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
void rebuild_pe(pe_base& pe, image_dos_header& dos_header, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
{
dos_header = pe.get_dos_header();
if(strip_dos_header)
{
//Strip stub overlay
pe.strip_stub_overlay();
//BaseOfCode NT Headers field now overlaps
//e_lfanew field, so we're acrually setting
//e_lfanew with this call
pe.set_base_of_code(8 * sizeof(uint16_t));
}
else
{
//Set start of PE headers
dos_header.e_lfanew = sizeof(image_dos_header)
+ pe_utils::align_up(static_cast<uint32_t>(pe.get_stub_overlay().size()), sizeof(uint32_t));
}
section_list& sections = pe.get_image_sections();
//Calculate pointer to section data
size_t ptr_to_section_data = (strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)) + pe.get_sizeof_nt_header()
+ pe_utils::align_up(pe.get_stub_overlay().size(), sizeof(uint32_t))
- sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())
+ sections.size() * sizeof(image_section_header);
if(save_bound_import && pe.has_bound_import())
{
//It will be aligned to DWORD, because we're aligning to DWORD everything above it
pe.set_directory_rva(image_directory_entry_bound_import, static_cast<uint32_t>(ptr_to_section_data));
ptr_to_section_data += pe.get_directory_size(image_directory_entry_bound_import);
}
ptr_to_section_data = pe_utils::align_up(ptr_to_section_data, pe.get_file_alignment());
//Set size of headers and size of optional header
if(change_size_of_headers)
{
if(!pe.get_image_sections().empty())
{
if(static_cast<uint32_t>(ptr_to_section_data) > (*sections.begin()).get_virtual_address())
throw pe_exception("Headers of PE file are too long. Try to strip STUB or don't build bound import", pe_exception::cannot_rebuild_image);
}
pe.set_size_of_headers(static_cast<uint32_t>(ptr_to_section_data));
}
//Set number of sections in PE header
pe.update_number_of_sections();
pe.update_image_size();
pe.set_size_of_optional_header(static_cast<uint16_t>(pe.get_sizeof_opt_headers()
- sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())));
//Recalculate pointer to raw data according to section list
for(section_list::iterator it = sections.begin(); it != sections.end(); ++it)
{
//Save section headers PointerToRawData
if((*it).get_size_of_raw_data())
{
(*it).set_pointer_to_raw_data(static_cast<uint32_t>(ptr_to_section_data));
ptr_to_section_data += (*it).get_aligned_raw_size(pe.get_file_alignment());
}
}
}
示例5: rebuild_relocations
//Simple relocations rebuilder
//To keep PE file working, don't remove any of existing relocations in
//relocation_table_list returned by a call to get_relocations() function
//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
//If save_to_pe_header is true, PE header will be modified automatically
const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
{
//Check that reloc_section is attached to this PE image
if(!pe.section_attached(reloc_section))
throw pe_exception("Relocations section must be attached to PE file", pe_exception::section_is_not_attached);
uint32_t current_reloc_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
uint32_t needed_size = current_reloc_data_pos - offset_from_section_start; //Calculate needed size for relocation tables
uint32_t size_delta = needed_size;
uint32_t start_reloc_pos = current_reloc_data_pos;
//Enumerate relocation tables
for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
{
needed_size += static_cast<uint32_t>((*it).get_relocations().size() * sizeof(uint16_t) /* relocations */ + sizeof(image_base_relocation) /* table header */);
//End of each table will be DWORD-aligned
if((start_reloc_pos + needed_size - size_delta) % sizeof(uint32_t))
needed_size += sizeof(uint16_t); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
}
//Check if reloc_section is last one. If it's not, check if there's enough place for relocations data
if(&reloc_section != &*(pe.get_image_sections().end() - 1) &&
(reloc_section.empty() || pe_utils::align_up(reloc_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + current_reloc_data_pos))
throw pe_exception("Insufficient space for relocations directory", pe_exception::insufficient_space);
std::string& raw_data = reloc_section.get_raw_data();
//This will be done only if reloc_section is the last section of image or for section with unaligned raw length of data
if(raw_data.length() < needed_size + current_reloc_data_pos)
raw_data.resize(pe_utils::align_up(needed_size + current_reloc_data_pos, pe.get_file_alignment())); //Expand section raw data
//Enumerate relocation tables
for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
{
//Create relocation table header
image_base_relocation reloc;
reloc.VirtualAddress = (*it).get_rva();
const relocation_table::relocation_list& reloc_list = (*it).get_relocations();
reloc.SizeOfBlock = static_cast<uint32_t>(sizeof(image_base_relocation) + sizeof(uint16_t) * reloc_list.size());
if((reloc_list.size() * sizeof(uint16_t)) % sizeof(uint32_t)) //If we must align end of relocation table
reloc.SizeOfBlock += sizeof(uint16_t);
memcpy(&raw_data[current_reloc_data_pos], &reloc, sizeof(reloc));
current_reloc_data_pos += sizeof(reloc);
//Enumerate relocations in table
for(relocation_table::relocation_list::const_iterator r = reloc_list.begin(); r != reloc_list.end(); ++r)
{
//Save relocations
uint16_t reloc_value = (*r).get_item();
memcpy(&raw_data[current_reloc_data_pos], &reloc_value, sizeof(reloc_value));
current_reloc_data_pos += sizeof(reloc_value);
}
if(current_reloc_data_pos % sizeof(uint32_t)) //If end of table is not DWORD-aligned
{
memset(&raw_data[current_reloc_data_pos], 0, sizeof(uint16_t)); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
current_reloc_data_pos += sizeof(uint16_t);
}
}
image_directory ret(pe.rva_from_section_offset(reloc_section, start_reloc_pos), needed_size - size_delta);
//Adjust section raw and virtual sizes
pe.recalculate_section_sizes(reloc_section, auto_strip_last_section);
//If auto-rewrite of PE headers is required
if(save_to_pe_header)
{
pe.set_directory_rva(image_directory_entry_basereloc, ret.get_rva());
pe.set_directory_size(image_directory_entry_basereloc, ret.get_size());
pe.clear_characteristics_flags(image_file_relocs_stripped);
pe.set_dll_characteristics(pe.get_dll_characteristics() | image_dllcharacteristics_dynamic_base);
}
return ret;
}
示例6: rebuild_resources
//Resources rebuilder
//resource_directory - root resource directory
//resources_section - section where resource directory will be placed (must be attached to PE image)
//offset_from_section_start - offset from resources_section raw data start
//resource_directory is non-constant, because it will be sorted
//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
{
//Check that resources_section is attached to this PE image
if(!pe.section_attached(resources_section))
throw pe_exception("Resource section must be attached to PE file", pe_exception::section_is_not_attached);
//Check resource directory correctness
if(info.get_entry_list().empty())
throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory);
uint32_t aligned_offset_from_section_start = pe_utils::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;
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;
//Check if resources_section is last one. If it's not, check if there's enough place for resource data
if(&resources_section != &*(pe.get_image_sections().end() - 1) &&
(resources_section.empty() || pe_utils::align_up(resources_section.get_size_of_raw_data(), pe.get_file_alignment())
< needed_size + aligned_offset_from_section_start))
throw pe_exception("Insufficient space for resource directory", pe_exception::insufficient_space);
std::string& raw_data = resources_section.get_raw_data();
//This will be done only if resources_section is the last section of image or for section with unaligned raw length of data
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
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(pe, resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start);
//Adjust section raw and virtual sizes
pe.recalculate_section_sizes(resources_section, auto_strip_last_section);
image_directory ret(pe.rva_from_section_offset(resources_section, aligned_offset_from_section_start), needed_size);
//If auto-rewrite of PE headers is required
if(save_to_pe_header)
{
pe.set_directory_rva(image_directory_entry_resource, ret.get_rva());
pe.set_directory_size(image_directory_entry_resource, ret.get_size());
}
return ret;
}