diff options
Diffstat (limited to 'tools/pe_bliss/pe_debug.cpp')
-rw-r--r-- | tools/pe_bliss/pe_debug.cpp | 865 |
1 files changed, 0 insertions, 865 deletions
diff --git a/tools/pe_bliss/pe_debug.cpp b/tools/pe_bliss/pe_debug.cpp deleted file mode 100644 index a0ed3f5af1..0000000000 --- a/tools/pe_bliss/pe_debug.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/*************************************************************************/ -/* Copyright (c) 2015 dx, http://kaimi.ru */ -/* */ -/* Permission is hereby granted, free of charge, to any person */ -/* obtaining a copy of this software and associated documentation */ -/* files (the "Software"), to deal in the Software without */ -/* restriction, including without limitation the rights to use, */ -/* copy, modify, merge, publish, distribute, sublicense, and/or */ -/* sell copies of the Software, and to permit persons to whom the */ -/* Software is furnished to do so, subject to the following conditions: */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include <string.h> -#include "pe_debug.h" -#include "utils.h" - -namespace pe_bliss -{ -using namespace pe_win; -//DEBUG -//Default constructor -debug_info::debug_info() - :characteristics_(0), - time_stamp_(0), - major_version_(0), minor_version_(0), - type_(0), - size_of_data_(0), - address_of_raw_data_(0), - pointer_to_raw_data_(0), - advanced_info_type_(advanced_info_none) -{} - -//Constructor from data -debug_info::debug_info(const image_debug_directory& debug) - :characteristics_(debug.Characteristics), - time_stamp_(debug.TimeDateStamp), - major_version_(debug.MajorVersion), minor_version_(debug.MinorVersion), - type_(debug.Type), - size_of_data_(debug.SizeOfData), - address_of_raw_data_(debug.AddressOfRawData), - pointer_to_raw_data_(debug.PointerToRawData), - advanced_info_type_(advanced_info_none) -{} - -//Returns debug characteristics -uint32_t debug_info::get_characteristics() const -{ - return characteristics_; -} - -//Returns debug datetimestamp -uint32_t debug_info::get_time_stamp() const -{ - return time_stamp_; -} - -//Returns major version -uint32_t debug_info::get_major_version() const -{ - return major_version_; -} - -//Returns minor version -uint32_t debug_info::get_minor_version() const -{ - return minor_version_; -} - -//Returns type of debug info (unchecked) -uint32_t debug_info::get_type_raw() const -{ - return type_; -} - -//Returns type of debug info from debug_info_type enumeration -debug_info::debug_info_type debug_info::get_type() const -{ - //Determine debug type - switch(type_) - { - case image_debug_type_coff: - return debug_type_coff; - - case image_debug_type_codeview: - return debug_type_codeview; - - case image_debug_type_fpo: - return debug_type_fpo; - - case image_debug_type_misc: - return debug_type_misc; - - case image_debug_type_exception: - return debug_type_exception; - - case image_debug_type_fixup: - return debug_type_fixup; - - case image_debug_type_omap_to_src: - return debug_type_omap_to_src; - - case image_debug_type_omap_from_src: - return debug_type_omap_from_src; - - case image_debug_type_borland: - return debug_type_borland; - - case image_debug_type_clsid: - return debug_type_clsid; - - case image_debug_type_reserved10: - return debug_type_reserved10; - } - - return debug_type_unknown; -} - -//Returns size of debug data (internal, .pdb or other file doesn't count) -uint32_t debug_info::get_size_of_data() const -{ - return size_of_data_; -} - -//Returns RVA of debug info when mapped to memory or zero, if info is not mapped -uint32_t debug_info::get_rva_of_raw_data() const -{ - return address_of_raw_data_; -} - -//Returns raw file pointer to raw data -uint32_t debug_info::get_pointer_to_raw_data() const -{ - return pointer_to_raw_data_; -} - -//Copy constructor -debug_info::debug_info(const debug_info& info) - :characteristics_(info.characteristics_), - time_stamp_(info.time_stamp_), - major_version_(info.major_version_), minor_version_(info.minor_version_), - type_(info.type_), - size_of_data_(info.size_of_data_), - address_of_raw_data_(info.address_of_raw_data_), - pointer_to_raw_data_(info.pointer_to_raw_data_), - advanced_info_type_(info.advanced_info_type_) -{ - copy_advanced_info(info); -} - -//Copy assignment operator -debug_info& debug_info::operator=(const debug_info& info) -{ - copy_advanced_info(info); - - characteristics_ = info.characteristics_; - time_stamp_ = info.time_stamp_; - major_version_ = info.major_version_; - minor_version_ = info.minor_version_; - type_ = info.type_; - size_of_data_ = info.size_of_data_; - address_of_raw_data_ = info.address_of_raw_data_; - pointer_to_raw_data_ = info.pointer_to_raw_data_; - advanced_info_type_ = info.advanced_info_type_; - - return *this; -} - -//Default constructor -debug_info::advanced_info::advanced_info() - :adv_pdb_7_0_info(0) //Zero pointer to advanced data -{} - -//Returns true if advanced debug info is present -bool debug_info::advanced_info::is_present() const -{ - return adv_pdb_7_0_info != 0; -} - -//Helper for advanced debug information copying -void debug_info::copy_advanced_info(const debug_info& info) -{ - free_present_advanced_info(); - - switch(info.advanced_info_type_) - { - case advanced_info_pdb_7_0: - advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(*info.advanced_debug_info_.adv_pdb_7_0_info); - break; - case advanced_info_pdb_2_0: - advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(*info.advanced_debug_info_.adv_pdb_2_0_info); - break; - case advanced_info_misc: - advanced_debug_info_.adv_misc_info = new misc_debug_info(*info.advanced_debug_info_.adv_misc_info); - break; - case advanced_info_coff: - advanced_debug_info_.adv_coff_info = new coff_debug_info(*info.advanced_debug_info_.adv_coff_info); - break; - default: - break; - } - - advanced_info_type_ = info.advanced_info_type_; -} - -//Helper for clearing any present advanced debug information -void debug_info::free_present_advanced_info() -{ - switch(advanced_info_type_) - { - case advanced_info_pdb_7_0: - delete advanced_debug_info_.adv_pdb_7_0_info; - break; - case advanced_info_pdb_2_0: - delete advanced_debug_info_.adv_pdb_2_0_info; - break; - case advanced_info_misc: - delete advanced_debug_info_.adv_misc_info; - break; - case advanced_info_coff: - delete advanced_debug_info_.adv_coff_info; - break; - default: - break; - } - - advanced_debug_info_.adv_pdb_7_0_info = 0; - advanced_info_type_ = advanced_info_none; -} - -//Destructor -debug_info::~debug_info() -{ - free_present_advanced_info(); -} - -//Sets advanced debug information -void debug_info::set_advanced_debug_info(const pdb_7_0_info& info) -{ - free_present_advanced_info(); - advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(info); - advanced_info_type_ = advanced_info_pdb_7_0; -} - -void debug_info::set_advanced_debug_info(const pdb_2_0_info& info) -{ - free_present_advanced_info(); - advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(info); - advanced_info_type_ = advanced_info_pdb_2_0; -} - -void debug_info::set_advanced_debug_info(const misc_debug_info& info) -{ - free_present_advanced_info(); - advanced_debug_info_.adv_misc_info = new misc_debug_info(info); - advanced_info_type_ = advanced_info_misc; -} - -void debug_info::set_advanced_debug_info(const coff_debug_info& info) -{ - free_present_advanced_info(); - advanced_debug_info_.adv_coff_info = new coff_debug_info(info); - advanced_info_type_ = advanced_info_coff; -} - -//Returns advanced debug information type -debug_info::advanced_info_type debug_info::get_advanced_info_type() const -{ - return advanced_info_type_; -} - -//Returns advanced debug information or throws an exception, -//if requested information type is not contained by structure -template<> -const pdb_7_0_info debug_info::get_advanced_debug_info<pdb_7_0_info>() const -{ - if(advanced_info_type_ != advanced_info_pdb_7_0) - throw pe_exception("Debug info structure does not contain PDB 7.0 data", pe_exception::advanced_debug_information_request_error); - - return *advanced_debug_info_.adv_pdb_7_0_info; -} - -template<> -const pdb_2_0_info debug_info::get_advanced_debug_info<pdb_2_0_info>() const -{ - if(advanced_info_type_ != advanced_info_pdb_2_0) - throw pe_exception("Debug info structure does not contain PDB 2.0 data", pe_exception::advanced_debug_information_request_error); - - return *advanced_debug_info_.adv_pdb_2_0_info; -} - -template<> -const misc_debug_info debug_info::get_advanced_debug_info<misc_debug_info>() const -{ - if(advanced_info_type_ != advanced_info_misc) - throw pe_exception("Debug info structure does not contain MISC data", pe_exception::advanced_debug_information_request_error); - - return *advanced_debug_info_.adv_misc_info; -} - -template<> -const coff_debug_info debug_info::get_advanced_debug_info<coff_debug_info>() const -{ - if(advanced_info_type_ != advanced_info_coff) - throw pe_exception("Debug info structure does not contain COFF data", pe_exception::advanced_debug_information_request_error); - - return *advanced_debug_info_.adv_coff_info; -} - -//Sets advanced debug information type, if no advanced info structure available -void debug_info::set_advanced_info_type(advanced_info_type type) -{ - free_present_advanced_info(); - if(advanced_info_type_ >= advanced_info_codeview_4_0) //Don't set info type for those types, which have advanced info structures - advanced_info_type_ = type; -} - -//Default constructor -pdb_7_0_info::pdb_7_0_info() - :age_(0) -{ - memset(&guid_, 0, sizeof(guid_)); -} - -//Constructor from data -pdb_7_0_info::pdb_7_0_info(const CV_INFO_PDB70* info) - :age_(info->Age), guid_(info->Signature), - pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination -{} - -//Returns debug PDB 7.0 structure GUID -const guid pdb_7_0_info::get_guid() const -{ - return guid_; -} - -//Returns age of build -uint32_t pdb_7_0_info::get_age() const -{ - return age_; -} - -//Returns PDB file name / path -const std::string& pdb_7_0_info::get_pdb_file_name() const -{ - return pdb_file_name_; -} - -//Default constructor -pdb_2_0_info::pdb_2_0_info() - :age_(0), signature_(0) -{} - -//Constructor from data -pdb_2_0_info::pdb_2_0_info(const CV_INFO_PDB20* info) - :age_(info->Age), signature_(info->Signature), - pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination -{} - -//Returns debug PDB 2.0 structure signature -uint32_t pdb_2_0_info::get_signature() const -{ - return signature_; -} - -//Returns age of build -uint32_t pdb_2_0_info::get_age() const -{ - return age_; -} - -//Returns PDB file name / path -const std::string& pdb_2_0_info::get_pdb_file_name() const -{ - return pdb_file_name_; -} - -//Default constructor -misc_debug_info::misc_debug_info() - :data_type_(0), unicode_(false) -{} - -//Constructor from data -misc_debug_info::misc_debug_info(const image_debug_misc* info) - :data_type_(info->DataType), unicode_(info->Unicode ? true : false) -{ - //IMAGE_DEBUG_MISC::Data must be checked before! - if(info->Unicode) - { -#ifdef PE_BLISS_WINDOWS - debug_data_unicode_ = std::wstring(reinterpret_cast<const wchar_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2); -#else - debug_data_unicode_ = pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2)); -#endif - - pe_utils::strip_nullbytes(debug_data_unicode_); //Strip nullbytes in the end of string - } - else - { - debug_data_ansi_ = std::string(reinterpret_cast<const char*>(info->Data), info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */); - pe_utils::strip_nullbytes(debug_data_ansi_); //Strip nullbytes in the end of string - } -} - -//Returns debug data type -uint32_t misc_debug_info::get_data_type() const -{ - return data_type_; -} - -//Returns true if data type is exe name -bool misc_debug_info::is_exe_name() const -{ - return data_type_ == image_debug_misc_exename; -} - -//Returns true if debug data is UNICODE -bool misc_debug_info::is_unicode() const -{ - return unicode_; -} - -//Returns debug data (ANSI) -const std::string& misc_debug_info::get_data_ansi() const -{ - return debug_data_ansi_; -} - -//Returns debug data (UNICODE) -const std::wstring& misc_debug_info::get_data_unicode() const -{ - return debug_data_unicode_; -} - -//Default constructor -coff_debug_info::coff_debug_info() - :number_of_symbols_(0), - lva_to_first_symbol_(0), - number_of_line_numbers_(0), - lva_to_first_line_number_(0), - rva_to_first_byte_of_code_(0), - rva_to_last_byte_of_code_(0), - rva_to_first_byte_of_data_(0), - rva_to_last_byte_of_data_(0) -{} - -//Constructor from data -coff_debug_info::coff_debug_info(const image_coff_symbols_header* info) - :number_of_symbols_(info->NumberOfSymbols), - lva_to_first_symbol_(info->LvaToFirstSymbol), - number_of_line_numbers_(info->NumberOfLinenumbers), - lva_to_first_line_number_(info->LvaToFirstLinenumber), - rva_to_first_byte_of_code_(info->RvaToFirstByteOfCode), - rva_to_last_byte_of_code_(info->RvaToLastByteOfCode), - rva_to_first_byte_of_data_(info->RvaToFirstByteOfData), - rva_to_last_byte_of_data_(info->RvaToLastByteOfData) -{} - -//Returns number of symbols -uint32_t coff_debug_info::get_number_of_symbols() const -{ - return number_of_symbols_; -} - -//Returns virtual address of the first symbol -uint32_t coff_debug_info::get_lva_to_first_symbol() const -{ - return lva_to_first_symbol_; -} - -//Returns number of line-number entries -uint32_t coff_debug_info::get_number_of_line_numbers() const -{ - return number_of_line_numbers_; -} - -//Returns virtual address of the first line-number entry -uint32_t coff_debug_info::get_lva_to_first_line_number() const -{ - return lva_to_first_line_number_; -} - -//Returns relative virtual address of the first byte of code -uint32_t coff_debug_info::get_rva_to_first_byte_of_code() const -{ - return rva_to_first_byte_of_code_; -} - -//Returns relative virtual address of the last byte of code -uint32_t coff_debug_info::get_rva_to_last_byte_of_code() const -{ - return rva_to_last_byte_of_code_; -} - -//Returns relative virtual address of the first byte of data -uint32_t coff_debug_info::get_rva_to_first_byte_of_data() const -{ - return rva_to_first_byte_of_data_; -} - -//Returns relative virtual address of the last byte of data -uint32_t coff_debug_info::get_rva_to_last_byte_of_data() const -{ - return rva_to_last_byte_of_data_; -} - -//Returns COFF symbols list -const coff_debug_info::coff_symbols_list& coff_debug_info::get_symbols() const -{ - return symbols_; -} - -//Adds COFF symbol -void coff_debug_info::add_symbol(const coff_symbol& sym) -{ - symbols_.push_back(sym); -} - -//Default constructor -coff_debug_info::coff_symbol::coff_symbol() - :storage_class_(0), - index_(0), - section_number_(0), rva_(0), - type_(0), - is_filename_(false) -{} - -//Returns storage class -uint32_t coff_debug_info::coff_symbol::get_storage_class() const -{ - return storage_class_; -} - -//Returns symbol index -uint32_t coff_debug_info::coff_symbol::get_index() const -{ - return index_; -} - -//Returns section number -uint32_t coff_debug_info::coff_symbol::get_section_number() const -{ - return section_number_; -} - -//Returns RVA -uint32_t coff_debug_info::coff_symbol::get_rva() const -{ - return rva_; -} - -//Returns true if structure contains file name -bool coff_debug_info::coff_symbol::is_file() const -{ - return is_filename_; -} - -//Returns text data (symbol or file name) -const std::string& coff_debug_info::coff_symbol::get_symbol() const -{ - return name_; -} - -//Sets storage class -void coff_debug_info::coff_symbol::set_storage_class(uint32_t storage_class) -{ - storage_class_ = storage_class; -} - -//Sets symbol index -void coff_debug_info::coff_symbol::set_index(uint32_t index) -{ - index_ = index; -} - -//Sets section number -void coff_debug_info::coff_symbol::set_section_number(uint32_t section_number) -{ - section_number_ = section_number; -} - -//Sets RVA -void coff_debug_info::coff_symbol::set_rva(uint32_t rva) -{ - rva_ = rva; -} - -//Sets file name -void coff_debug_info::coff_symbol::set_file_name(const std::string& file_name) -{ - name_ = file_name; - is_filename_ = true; -} - -//Sets symbol name -void coff_debug_info::coff_symbol::set_symbol_name(const std::string& symbol_name) -{ - name_ = symbol_name; - is_filename_ = false; -} - -//Returns type -uint16_t coff_debug_info::coff_symbol::get_type() const -{ - return type_; -} - -//Sets type -void coff_debug_info::coff_symbol::set_type(uint16_t type) -{ - type_ = type; -} - -//Returns debug information list -const debug_info_list get_debug_information(const pe_base& pe) -{ - debug_info_list ret; - - //If there's no debug directory, return empty list - if(!pe.has_debug()) - return ret; - - //Check the length in bytes of the section containing debug directory - if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_rva(image_directory_entry_debug), section_data_virtual, true) - < sizeof(image_debug_directory)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - unsigned long current_pos = pe.get_directory_rva(image_directory_entry_debug); - - //First IMAGE_DEBUG_DIRECTORY table - image_debug_directory directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); - - if(!pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_size(image_directory_entry_debug))) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Iterate over all IMAGE_DEBUG_DIRECTORY directories - while(directory.PointerToRawData - && current_pos < pe.get_directory_rva(image_directory_entry_debug) + pe.get_directory_size(image_directory_entry_debug)) - { - //Create debug information structure - debug_info info(directory); - - //Find raw debug data - const pe_base::debug_data_list& debug_datas = pe.get_raw_debug_data_list(); - pe_base::debug_data_list::const_iterator it = debug_datas.find(directory.PointerToRawData); - if(it != debug_datas.end()) //If it exists, we'll do some detailed debug info research - { - const std::string& debug_data = (*it).second; - switch(directory.Type) - { - case image_debug_type_coff: - { - //Check data length - if(debug_data.length() < sizeof(image_coff_symbols_header)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Get coff header structure pointer - const image_coff_symbols_header* coff = reinterpret_cast<const image_coff_symbols_header*>(debug_data.data()); - - //Check possible overflows - if(coff->NumberOfSymbols >= pe_utils::max_dword / sizeof(image_symbol) - || !pe_utils::is_sum_safe(coff->NumberOfSymbols * sizeof(image_symbol), coff->LvaToFirstSymbol)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Check data length again - if(debug_data.length() < coff->NumberOfSymbols * sizeof(image_symbol) + coff->LvaToFirstSymbol) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Create COFF debug info structure - coff_debug_info coff_info(coff); - - //Enumerate debug symbols data - for(uint32_t i = 0; i < coff->NumberOfSymbols; ++i) - { - //Safe sum (checked above) - const image_symbol* sym = reinterpret_cast<const image_symbol*>(debug_data.data() + i * sizeof(image_symbol) + coff->LvaToFirstSymbol); - - coff_debug_info::coff_symbol symbol; - symbol.set_index(i); //Save symbol index - symbol.set_storage_class(sym->StorageClass); //Save storage class - symbol.set_type(sym->Type); //Save storage class - - //Check data length again - if(!pe_utils::is_sum_safe(i, sym->NumberOfAuxSymbols) - || (i + sym->NumberOfAuxSymbols) > coff->NumberOfSymbols - || debug_data.length() < (i + 1) * sizeof(image_symbol) + coff->LvaToFirstSymbol + sym->NumberOfAuxSymbols * sizeof(image_symbol)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //If symbol is filename - if(sym->StorageClass == image_sym_class_file) - { - //Save file name, it is situated just after this IMAGE_SYMBOL structure - std::string file_name(reinterpret_cast<const char*>(debug_data.data() + (i + 1) * sizeof(image_symbol)), sym->NumberOfAuxSymbols * sizeof(image_symbol)); - pe_utils::strip_nullbytes(file_name); - symbol.set_file_name(file_name); - - //Save symbol info - coff_info.add_symbol(symbol); - - //Move to next symbol - i += sym->NumberOfAuxSymbols; - continue; - } - - //Dump some other symbols - if(((sym->StorageClass == image_sym_class_static) - && (sym->NumberOfAuxSymbols == 0) - && (sym->SectionNumber == 1)) - || - ((sym->StorageClass == image_sym_class_external) - && ISFCN(sym->Type) - && (sym->SectionNumber > 0)) - ) - { - //Save RVA and section number - symbol.set_section_number(sym->SectionNumber); - symbol.set_rva(sym->Value); - - //If symbol has short name - if(sym->N.Name.Short) - { - //Copy and save symbol name - char name_buff[9]; - memcpy(name_buff, sym->N.ShortName, 8); - name_buff[8] = '\0'; - symbol.set_symbol_name(name_buff); - } - else - { - //Symbol has long name - - //Check possible overflows - if(!pe_utils::is_sum_safe(coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol), sym->N.Name.Long)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Here we have an offset to the string table - uint32_t symbol_offset = coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol) + sym->N.Name.Long; - - //Check data length - if(debug_data.length() < symbol_offset) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Check symbol name for null-termination - if(!pe_utils::is_null_terminated(debug_data.data() + symbol_offset, debug_data.length() - symbol_offset)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Save symbol name - symbol.set_symbol_name(debug_data.data() + symbol_offset); - } - - //Save symbol info - coff_info.add_symbol(symbol); - - //Move to next symbol - i += sym->NumberOfAuxSymbols; - continue; - } - } - - info.set_advanced_debug_info(coff_info); - } - break; - - case image_debug_type_codeview: - { - //Check data length - if(debug_data.length() < sizeof(OMFSignature*)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Get POMFSignature structure pointer from the very beginning of debug data - const OMFSignature* sig = reinterpret_cast<const OMFSignature*>(debug_data.data()); - if(!memcmp(sig->Signature, "RSDS", 4)) - { - //Signature is "RSDS" - PDB 7.0 - - //Check data length - if(debug_data.length() < sizeof(CV_INFO_PDB70)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - const CV_INFO_PDB70* pdb_data = reinterpret_cast<const CV_INFO_PDB70*>(debug_data.data()); - - //Check PDB file name null-termination - if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB70) - 1 /* BYTE of filename in structure */))) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - info.set_advanced_debug_info(pdb_7_0_info(pdb_data)); - } - else if(!memcmp(sig->Signature, "NB10", 4)) - { - //Signature is "NB10" - PDB 2.0 - - //Check data length - if(debug_data.length() < sizeof(CV_INFO_PDB20)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - const CV_INFO_PDB20* pdb_data = reinterpret_cast<const CV_INFO_PDB20*>(debug_data.data()); - - //Check PDB file name null-termination - if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB20) - 1 /* BYTE of filename in structure */))) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - info.set_advanced_debug_info(pdb_2_0_info(pdb_data)); - } - else if(!memcmp(sig->Signature, "NB09", 4)) - { - //CodeView 4.0, no structures available - info.set_advanced_info_type(debug_info::advanced_info_codeview_4_0); - } - else if(!memcmp(sig->Signature, "NB11", 4)) - { - //CodeView 5.0, no structures available - info.set_advanced_info_type(debug_info::advanced_info_codeview_5_0); - } - else if(!memcmp(sig->Signature, "NB05", 4)) - { - //Other CodeView, no structures available - info.set_advanced_info_type(debug_info::advanced_info_codeview); - } - } - - break; - - case image_debug_type_misc: - { - //Check data length - if(debug_data.length() < sizeof(image_debug_misc)) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Get misc structure pointer - const image_debug_misc* misc_data = reinterpret_cast<const image_debug_misc*>(debug_data.data()); - - //Check misc data length - if(debug_data.length() < misc_data->Length /* Total length of record */) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Save advanced information - info.set_advanced_debug_info(misc_debug_info(misc_data)); - } - break; - } - } - - //Save debug information structure - ret.push_back(info); - - //Check possible overflow - if(!pe_utils::is_sum_safe(current_pos, sizeof(image_debug_directory))) - throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); - - //Go to next debug entry - current_pos += sizeof(image_debug_directory); - directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); - } - - return ret; -} -} |