summaryrefslogtreecommitdiff
path: root/tools/pe_bliss/pe_debug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pe_bliss/pe_debug.cpp')
-rw-r--r--tools/pe_bliss/pe_debug.cpp865
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;
-}
-}