00001 /* 00002 PeRdr - PE file disassembler 00003 Copyright (C) 1999-2002 Frediano Ziglio 00004 ----- 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ----- 00020 00021 INFORMATION 00022 www: https://freddy77.tripod.com/perdr/ 00023 e-mail: freddy77@angelfire.com 00024 */ 00025 #include "global.h" 00026 #ifdef HAVE_HDRSTOP 00027 #pragma hdrstop 00028 #endif 00029 00030 #include "peformat.h" 00031 #include "rva.h" 00032 00033 void PeSection::operator=(const PE_IMAGE_SECTION_HEADER& section) 00034 { 00035 RvaSize = section.Misc.VirtualSize; 00036 RvaAddress = section.VirtualAddress; 00037 RawSize = section.SizeOfRawData; 00038 RawAddress = section.PointerToRawData; 00039 Characteristics = section.Characteristics; 00040 } 00041 00042 bool PeSection::IsCode() const 00043 { 00044 return (Characteristics & IMAGE_SCN_CNT_CODE) != 0; 00045 } 00046 00047 RVAFileTranslator::RVAFileTranslator(const PE_IMAGE_SECTION_HEADER* _sections,unsigned _num_section): 00048 num(_num_section),section_infos(NULL) 00049 { 00050 unsigned n; 00051 00052 // check order and size 00053 uint32_t prevVirtualEnd = 0,prevFileEnd = 0; 00054 for( n=0; n<num; ++n ) 00055 { 00056 // vedi se sezione inizializzata 00057 if (!(_sections[n].Characteristics&IMAGE_SCN_CNT_UNINITIALIZED_DATA) || _sections[n].PointerToRawData != 0) 00058 // !!! una sezione puo' essere vuota e non avere il flag uninitialized settato 00059 if(_sections[n].PointerToRawData != 0 || _sections[n].SizeOfRawData != 0) 00060 { 00061 if (prevVirtualEnd > _sections[n].VirtualAddress || 00062 prevFileEnd > _sections[n].PointerToRawData ) 00063 throw std::runtime_error("Invalid order of sections"); 00064 prevVirtualEnd = _sections[n].VirtualAddress+_sections[n].Misc.VirtualSize; 00065 prevFileEnd = _sections[n].PointerToRawData+_sections[n].SizeOfRawData; 00066 } 00067 } 00068 00069 // copy 00070 section_infos = new PeSection[num]; 00071 for( n=0; n<num; ++n ) 00072 section_infos[n] = _sections[n]; 00073 } 00074 00075 RVAFileTranslator::~RVAFileTranslator() 00076 { 00077 delete[] section_infos; 00078 } 00079 00080 long RVAFileTranslator::RVA2File(uint32_t rva) const 00081 { 00082 for( unsigned n=0; n<num; ++n ) 00083 { 00084 if (rva >= section_infos[n].RvaAddress && rva < (section_infos[n].RvaAddress+section_infos[n].RvaSize) ) 00085 return rva - section_infos[n].RvaAddress + section_infos[n].RawAddress; 00086 } 00087 return 0; 00088 } 00089 00090 uint32_t RVAFileTranslator::File2RVA(long _file) const 00091 { 00092 if (_file < 0) return 0; 00093 unsigned long file = static_cast<unsigned long>(_file); 00094 for( unsigned n=0; n<num; ++n ) 00095 { 00096 if (file >= section_infos[n].RawAddress && file < (section_infos[n].RawAddress+section_infos[n].RawSize) ) 00097 return file - section_infos[n].RawAddress + section_infos[n].RvaAddress; 00098 } 00099 return 0; 00100 } 00101 00102 void RVAFileTranslator::operator=(const RVAFileTranslator& rhs) 00103 { 00104 delete section_infos; 00105 section_infos = new PeSection[rhs.num]; 00106 num = rhs.num; 00107 for(unsigned n=0; n<num; ++n) 00108 section_infos[n] = rhs.section_infos[n]; 00109 } 00110