Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

module.cpp

Go to the documentation of this file.
00001 /*
00002 PeRdr - PE file disassembler
00003 Copyright (C) 1999-2003 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 "module.h"
00031 
00032 
00033 // sezione errata. non contiene ne dati ne codice
00034 const ObjectModule::Section ObjectModule::errorSection;
00035 
00036 ObjectModule::ObjectModule(CFile& file,const RVAFileTranslator& rva,uint32_t imageBase,
00037                    bool _hasRelocation,const RelocationInfos& _relocationInfos,
00038                                                                          const Symbols& _symbols, const Symbols& _exportSymbols,
00039                                                                          vma_t _entryPoint):
00040   sections(rva.GetSectionCount()),
00041   hasRelocation(_hasRelocation),relocationInfos(_relocationInfos),
00042         symbols(_symbols),exportSymbols(_exportSymbols)
00043 {
00044         entryPoint  = _entryPoint==0?0:_entryPoint+imageBase;
00045         
00046   unsigned numSection = rva.GetSectionCount();
00047         uint8_t *buffer;
00048   for (unsigned n=0;n<numSection;++n)
00049   {
00050     // se RawSize > RvaSize altri bytes non utilizzati (indirizzi invalidi)
00051     // se RvaSize > RawSize altri bytes non inizializzati
00052     // calcola dimensione sezione
00053           unsigned size = rva.GetSection(n)->RvaSize;
00054     // inizializza valori
00055     sections[n].begin = rva.GetSection(n)->RvaAddress + imageBase;
00056     sections[n].end   = rva.GetSection(n)->RvaAddress + imageBase + size;
00057     if ( rva.GetSection(n)->IsCode() )
00058       sections[n].SetIsCode();
00059     else
00060       sections[n].SetIsData();
00061 
00062     // inizializza buffer
00063     buffer = new uint8_t[size];
00064     memset(buffer,0,size);
00065                 
00066     // se puntatore valido leggi da memoria
00067     if ( rva.GetSection(n)->RawAddress != 0 )
00068     {
00069       unsigned rawSize = rva.GetSection(n)->RawSize;
00070       file.Seek( rva.GetSection(n)->RawAddress );
00071       file.RawRead( buffer,size<rawSize?size:rawSize );
00072     }
00073                 
00074                 sections[n].data = buffer;
00075                 sections[n].data_end = buffer+size;
00076                 if (n != 0)
00077                         sections[n-1].next = &sections[n];
00078   }
00079 }
00080 
00081 ObjectModule::ObjectModule(vma_t start,const unsigned char *ptr, unsigned len):
00082   sections(1),hasRelocation(false)
00083 {
00084         entryPoint  = start;
00085         
00086         uint8_t *buffer;
00087   // inizializza valori
00088   sections[0].begin = start;
00089   sections[0].end   = start + len;
00090   sections[0].SetIsCode();
00091 
00092   // inizializza buffer
00093   buffer = new uint8_t[len];
00094   memcpy(buffer, ptr, len);
00095                 
00096         sections[0].data = buffer;
00097         sections[0].data_end = buffer+len;
00098 }
00099 
00100 ObjectModule::~ObjectModule()
00101 {
00102 }
00103 
00104 // implementazione simile a SeekTo
00105 bool ObjectModule::IsValid(vma_t address)
00106 {
00107   // prova con la sezione corrente
00108 //  if ( currSection && currSection->begin <= address && address < currSection->end )
00109 //    return true;
00110 
00111   // cerca sezione
00112   for( TSections::size_type n=0; n < sections.size(); ++n )
00113   {
00114     vma_t begin = sections[n].begin;
00115     vma_t end   = sections[n].end;
00116     if (begin <= address && address < end)
00117     {
00118       return true;
00119     }
00120   }
00121         return false;
00122 }
00123 
00124 /*
00125 vma_t ObjectModule::GetNextValid()
00126 {
00127   if (IsValid(currPos))
00128     return currPos;
00129 
00130   vma_t pos = VMA_MAX;
00131 
00132   // trova il minimo fra le sezioni maggiori
00133   for( TSections::size_type n=0; n < sections.size(); ++n )
00134   {
00135     vma_t begin = sections[n].begin;
00136     if (begin < pos && begin >= currPos)
00137       pos = begin;
00138   }
00139   _PRG_ASSERT(IsValid(pos));
00140   return pos;
00141 }
00142 */
00143 
00144 const ObjectModule::Section* ObjectModule::GetSection(vma_t address) const
00145 {
00146   // cerca sezione
00147   for( TSections::size_type n=0; n < sections.size(); ++n )
00148   {
00149     vma_t begin = sections[n].begin;
00150     vma_t end   = sections[n].end;
00151     if (begin <= address && address < end)
00152     {
00153       return &sections[n];
00154     }
00155   }
00156   return &errorSection;
00157 }
00158 
00159 ObjectModule::DataReader ObjectModule::GetDataReader(vma_t address)
00160 {
00161         // !!! optimize saving last searched section 
00162         // find sectionBuffer
00163         Section* sec;
00164   for( TSections::size_type n=0; n < sections.size(); ++n )
00165   {
00166     vma_t begin = sections[n].begin;
00167     vma_t end   = sections[n].end;
00168     if (begin <= address && address < end)
00169     {
00170                         sec = &sections[n];
00171       return DataReader(sec,sec->data + (address - begin));
00172     }
00173   }
00174         
00175   throw OutOfAddress(address);
00176 }
00177 
00178 uint8_t ObjectModule::ReadByte(vma_t address)
00179 {
00180         DataReader reader = GetDataReader(address);
00181         return reader.ReadByte();
00182 }
00183 
00184 uint16_t ObjectModule::ReadWord(vma_t address)
00185 {
00186         DataReader reader = GetDataReader(address);
00187         return reader.ReadWord();
00188 }
00189 
00190 uint32_t ObjectModule::ReadDword(vma_t address)
00191 {
00192         DataReader reader = GetDataReader(address);
00193         return reader.ReadDword();
00194 }
00195 
00196 ObjectModule::DataReader::DataReader(const Section* _sec,unsigned char* _ptr):
00197         sec(_sec),ptr(_ptr)
00198 {
00199 }
00200 
00201 uint8_t ObjectModule::DataReader::ReadByte()
00202 {
00203         _PRG_ASSERT(sec);
00204         _PRG_ASSERT(ptr >= sec->data && ptr <= sec->data_end);
00205 
00206   // test cell valid
00207         if (ptr < sec->data_end)
00208                 return *ptr++;
00209                 
00210         // next section continue this ??
00211         if (sec->next && sec->end == sec->next->begin)
00212         {
00213                 /* !!! is posible a empty section ??? */
00214                 sec = sec->next;
00215                 ptr = sec->data;
00216                 return *ptr++;
00217         }
00218 
00219   throw OutOfAddress(sec->end);
00220 }
00221 
00222 uint16_t ObjectModule::DataReader::ReadWord()
00223 {
00224   // !!! define uint8fast_t
00225   uint8_t u = ReadByte();
00226   return uint16_t(u|(uint16_t(ReadByte())<<8));
00227 }
00228 
00229 uint32_t ObjectModule::DataReader::ReadDword()
00230 {
00231   // !!! define uint16fast_t
00232   uint16_t u = ReadWord();
00233   return u|(uint32_t(ReadWord())<<16);
00234 }
00235 
00236 vma_t ObjectModule::DataReader::Tell()
00237 {
00238         return sec->begin + (ptr - sec->data);
00239 }
00240 
00241 void ObjectModule::DataReader::UnReadByte()
00242 {
00243         _PRG_ASSERT(sec);
00244         _PRG_ASSERT(ptr >= sec->data && ptr <= sec->data_end);
00245 
00246   // test cell valid
00247         if (ptr >= sec->data)
00248         {
00249                 --ptr;
00250                 return;
00251         }
00252                 
00253         // !!! finish, go to other section
00254   throw OutOfAddress(sec->begin);
00255 }
00256 
00257 ObjectModule::Section::~Section()
00258 {
00259         delete data;
00260 }

Generated on Mon Jan 13 22:20:34 2003 for perdr by doxygen1.2.15