Make your own free website on Tripod.com
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: http://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