Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htpe.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      htpe.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
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 #include "log.h"
00022 #include "htendian.h"
00023 #include "htnewexe.h"
00024 #include "htpe.h"
00025 #include "htpehead.h"
00026 #include "htpeexp.h"
00027 #include "htpeil.h"
00028 #include "htpeimp.h"
00029 #include "htpedimp.h"
00030 #include "htpeimg.h"
00031 #include "htperes.h"
00032 #include "stream.h"
00033 #include "tools.h"
00034 
00035 #include <stdlib.h>
00036 #include <string.h>
00037 
00038 static format_viewer_if *htpe_ifs[] = {
00039         &htpeheader_if,
00040         &htpeexports_if,
00041         &htpeimports_if,
00042         &htpedelayimports_if,
00043         &htperesources_if,
00044         &htpeil_if,
00045         &htpeimage_if,
00046         0
00047 };
00048 
00049 static ht_view *htpe_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00050 {
00051         byte pemagic[4];
00052         FILEOFS h = get_newexe_header_ofs(file);
00053         file->seek(h);
00054         file->read(pemagic, 4);
00055         if ((pemagic[0]!=PE_MAGIC0) || (pemagic[1]!=PE_MAGIC1) ||
00056            (pemagic[2]!=PE_MAGIC2) || (pemagic[3]!=PE_MAGIC3)) return 0;
00057 
00058         ht_pe *g = new ht_pe();
00059         g->init(b, file, htpe_ifs, format_group, h);
00060         return g;
00061 }
00062 
00063 format_viewer_if htpe_if = {
00064         htpe_init,
00065         0
00066 };
00067 
00068 /*
00069  *      CLASS ht_pe
00070  */
00071 void ht_pe::init(bounds *b, ht_streamfile *file, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs)
00072 {
00073         ht_format_group::init(b, VO_BROWSABLE | VO_SELECTABLE | VO_RESIZE, DESC_PE, file, false, true, 0, format_group);
00074         VIEW_DEBUG_NAME("ht_pe");
00075 
00076         LOG("%s: PE: found header at %08x", file->get_filename(), header_ofs);
00077 
00078         ht_pe_shared_data *pe_shared = (ht_pe_shared_data*)malloc(sizeof (ht_pe_shared_data));
00079         shared_data = pe_shared;
00080         pe_shared->header_ofs = header_ofs;
00081 
00082         pe_shared->exports.funcs = new ht_clist();
00083         pe_shared->exports.funcs->init();
00084 
00085         pe_shared->dimports.funcs = new ht_clist();
00086         pe_shared->dimports.funcs->init();
00087 
00088         pe_shared->dimports.libs = new ht_clist();
00089         pe_shared->dimports.libs->init();
00090 
00091         pe_shared->imports.funcs = new ht_clist();
00092         pe_shared->imports.funcs->init();
00093 
00094         pe_shared->imports.libs = new ht_clist();
00095         pe_shared->imports.libs->init();
00096 
00097         pe_shared->il = NULL;
00098         pe_shared->v_image = NULL;
00099         pe_shared->v_dimports = NULL;
00100         pe_shared->v_imports = NULL;
00101         pe_shared->v_exports = NULL;
00102         pe_shared->v_resources = NULL;
00103         pe_shared->v_header = NULL;
00104 
00105         /* read header */
00106         file->seek(header_ofs+4);
00107         file->read(&pe_shared->coffheader, sizeof pe_shared->coffheader);
00108         create_host_struct(&pe_shared->coffheader, COFF_HEADER_struct, little_endian);
00109         file->read(&pe_shared->opt_magic, sizeof pe_shared->opt_magic);
00110         pe_shared->opt_magic = create_host_int(&pe_shared->opt_magic, sizeof pe_shared->opt_magic, little_endian);
00111         file->seek(header_ofs+4+sizeof pe_shared->coffheader);
00112         switch (pe_shared->opt_magic) {
00113                 case COFF_OPTMAGIC_PE32: {
00114                         file->read(&pe_shared->pe32.header, sizeof pe_shared->pe32.header);
00115                         create_host_struct(&pe_shared->pe32.header, COFF_OPTIONAL_HEADER32_struct, little_endian);
00116                         file->read(&pe_shared->pe32.header_nt, sizeof pe_shared->pe32.header_nt);
00117                         create_host_struct(&pe_shared->pe32.header_nt, PE_OPTIONAL_HEADER32_NT_struct, little_endian);
00118                         for (UINT i=0; i<PE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
00119                                 create_host_struct(&pe_shared->pe32.header_nt.directory[i], PE_DATA_DIRECTORY_struct, little_endian);
00120                         }
00121                         break;
00122                 }
00123                 case COFF_OPTMAGIC_PE64: {
00124                         file->read(&pe_shared->pe64.header, sizeof pe_shared->pe64.header);
00125                         create_host_struct(&pe_shared->pe64.header, COFF_OPTIONAL_HEADER64_struct, little_endian);
00126                         file->read(&pe_shared->pe64.header_nt, sizeof pe_shared->pe64.header_nt);
00127                         create_host_struct(&pe_shared->pe64.header_nt, PE_OPTIONAL_HEADER64_NT_struct, little_endian);
00128                         for (UINT i=0; i<PE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
00129                                 create_host_struct(&pe_shared->pe64.header_nt.directory[i], PE_DATA_DIRECTORY_struct, little_endian);
00130                         }
00131                         break;
00132                 }
00133         }
00134 
00135         /* read section headers */
00136         int os=pe_shared->coffheader.optional_header_size;
00137         pe_shared->sections.section_count=pe_shared->coffheader.section_count;
00138 
00139         file->seek(header_ofs+os+sizeof(COFF_HEADER)+4/*magic*/);
00140         pe_shared->sections.sections=(COFF_SECTION_HEADER*)malloc(pe_shared->sections.section_count * sizeof *pe_shared->sections.sections);
00141         file->read(pe_shared->sections.sections, pe_shared->sections.section_count*sizeof *pe_shared->sections.sections);
00142 
00143         for (UINT i=0; i<pe_shared->sections.section_count; i++) {
00144                 create_host_struct(&pe_shared->sections.sections[i], COFF_SECTION_HEADER_struct, little_endian);
00145                 /*
00146                  *      To make those uninitialized/initialized flags
00147                  *      correct we guess a little
00148                  *
00149                 if (pe_shared->sections.sections[i].data_size &&
00150                         pe_shared->sections.sections[i].data_offset) {
00151 
00152                         pe_shared->sections.sections[i].characteristics |= ;
00153                         pe_shared->sections.sections[i].characteristics ~= ;
00154                 } else {
00155                         pe_shared->sections.sections[i].characteristics |= ;
00156                         pe_shared->sections.sections[i].characteristics ~= ;
00157                 }*/
00158         }
00159 
00160         shared_data = pe_shared;
00161 
00162         ht_format_group::init_ifs(ifs);
00163 }
00164 
00165 void ht_pe::done()
00166 {
00167         ht_format_group::done();
00168 
00169         ht_pe_shared_data *pe_shared = (ht_pe_shared_data*)shared_data;
00170 
00171         if (pe_shared->exports.funcs) {
00172                 pe_shared->exports.funcs->destroy();
00173                 delete pe_shared->exports.funcs;
00174         }
00175         if (pe_shared->dimports.funcs) {
00176                 pe_shared->dimports.funcs->destroy();
00177                 delete pe_shared->dimports.funcs;
00178         }
00179         if (pe_shared->dimports.libs) {
00180                 pe_shared->dimports.libs->destroy();
00181                 delete pe_shared->dimports.libs;
00182         }
00183         if (pe_shared->imports.funcs) {
00184                 pe_shared->imports.funcs->destroy();
00185                 delete pe_shared->imports.funcs;
00186         }
00187         if (pe_shared->imports.libs) {
00188                 pe_shared->imports.libs->destroy();
00189                 delete pe_shared->imports.libs;
00190         }
00191         free(pe_shared->sections.sections);
00192 
00193         free(shared_data);
00194 }
00195 
00196 void ht_pe::loc_enum_start()
00197 {
00198 /*
00199         ht_pe_shared_data *sh=(ht_pe_shared_data*)shared_data;
00200         if (sh->opt_magic==COFF_OPTMAGIC_PE32) {
00201                 loc_enum=1;
00202         } else {
00203                 loc_enum=0;
00204         }
00205 */
00206 }
00207 
00208 bool ht_pe::loc_enum_next(ht_format_loc *loc)
00209 {
00210 #if 0
00211         ht_pe_shared_data *sh=(ht_pe_shared_data*)shared_data;
00212         if (loc_enum) {
00213                 loc->name="pe";
00214                 loc->start=sh->header_ofs;
00215                 // calc pe size
00216                 UINT l=sizeof (COFF_HEADER) + sh->coffheader.optional_header_size;
00217                 // go through directories
00218                 for (UINT i=0; i<16; i++) {
00219                         FILEOFS o;
00220                         if (pe_rva_to_ofs(&sh->sections, sh->pe32.header_nt.directory[i].address, &o)) {
00221                                 UINT k=o+sh->pe32.header_nt.directory[i].size-sh->header_ofs;
00222                                 l=MAX(k, l);
00223                         }
00224                 }
00225                 // go through sections
00226                 for (UINT i=0; i<sh->sections.section_count; i++) {
00227                         UINT k=sh->sections.sections[i].data_offset+sh->sections.sections[i].data_size-sh->header_ofs;
00228                         l=MAX(k, l);
00229                 }
00230                 loc->length=l;
00231                 
00232                 loc_enum=0;
00233                 return true;
00234         }
00235         return false;
00236 #endif
00237         return false;
00238 }
00239 
00240 /*
00241  *      rva conversion routines
00242  */
00243 
00244 bool pe_rva_to_ofs(pe_section_headers *section_headers, RVA rva, FILEOFS *ofs)
00245 {
00246         COFF_SECTION_HEADER *s=section_headers->sections;
00247         for (UINT i=0; i<section_headers->section_count; i++) {
00248                 if ((rva>=s->data_address) &&
00249                 (rva<s->data_address+s->data_size)) {
00250                         *ofs=rva-s->data_address+s->data_offset;
00251                         return true;
00252                 }
00253                 s++;
00254         }
00255         return false;
00256 }
00257 
00258 bool pe_rva_to_section(pe_section_headers *section_headers, RVA rva, int *section)
00259 {
00260         COFF_SECTION_HEADER *s=section_headers->sections;
00261         for (UINT i=0; i<section_headers->section_count; i++) {
00262                 if ((rva>=s->data_address) &&
00263                 (rva<s->data_address+MAX(s->data_size, s->data_vsize))) {
00264                         *section=i;
00265                         return true;
00266                 }
00267                 s++;
00268         }
00269         return false;
00270 }
00271 
00272 bool pe_rva_is_valid(pe_section_headers *section_headers, RVA rva)
00273 {
00274         COFF_SECTION_HEADER *s=section_headers->sections;
00275         for (UINT i=0; i<section_headers->section_count; i++) {
00276                 if ((rva>=s->data_address) &&
00277                 (rva<s->data_address+MAX(s->data_size, s->data_vsize))) {
00278                         return true;
00279                 }
00280                 s++;
00281         }
00282         return false;
00283 }
00284 
00285 bool pe_rva_is_physical(pe_section_headers *section_headers, RVA rva)
00286 {
00287         COFF_SECTION_HEADER *s=section_headers->sections;
00288         for (UINT i=0; i<section_headers->section_count; i++) {
00289                 if ((rva>=s->data_address) &&
00290                 (rva<s->data_address+s->data_size)) {
00291                         return true;
00292                 }
00293                 s++;
00294         }
00295         return false;
00296 }
00297 
00298 /*
00299  *      ofs conversion routines
00300  */
00301 
00302 bool pe_ofs_to_rva(pe_section_headers *section_headers, FILEOFS ofs, RVA *rva)
00303 {
00304         COFF_SECTION_HEADER *s=section_headers->sections;
00305         for (UINT i=0; i<section_headers->section_count; i++) {
00306                 if ((ofs>=s->data_offset) &&
00307                 (ofs<s->data_offset+s->data_size)) {
00308                         *rva=ofs-s->data_offset+s->data_address;
00309                         return true;
00310                 }
00311                 s++;
00312         }
00313         return false;
00314 }
00315 
00316 bool pe_ofs_to_section(pe_section_headers *section_headers, FILEOFS ofs, int *section)
00317 {
00318         COFF_SECTION_HEADER *s=section_headers->sections;
00319         for (UINT i=0; i<section_headers->section_count; i++) {
00320                 if ((ofs>=s->data_offset) &&
00321                 (ofs<s->data_offset+s->data_size)) {
00322                         *section=i;
00323                         return true;
00324                 }
00325                 s++;
00326         }
00327         return false;
00328 }
00329 
00330 bool pe_ofs_to_rva_and_section(pe_section_headers *section_headers, FILEOFS ofs, RVA *rva, int *section)
00331 {
00332         bool r = pe_ofs_to_rva(section_headers, ofs, rva);
00333         if (r) {
00334                 r = pe_ofs_to_section(section_headers, ofs, section);
00335         }
00336         return r;
00337 }
00338 
00339 bool pe_ofs_is_valid(pe_section_headers *section_headers, FILEOFS ofs)
00340 {
00341         RVA rva;
00342         return pe_ofs_to_rva(section_headers, ofs, &rva);
00343 }
00344 
00345 /*
00346  *
00347  */
00348  
00349 bool pe_section_name_to_section(pe_section_headers *section_headers, const char *name, int *section)
00350 {
00351         COFF_SECTION_HEADER *s = section_headers->sections;
00352         int slen = strlen(name);
00353         slen = MIN(slen, COFF_SIZEOF_SHORT_NAME);
00354         for (UINT i=0; i < section_headers->section_count; i++) {
00355                 if (strncmp(name, (char*)&s->name, slen) == 0) {
00356                         *section = i;
00357                         return true;
00358                 }
00359                 s++;
00360         }
00361         return false;
00362 }

Generated on Fri May 7 21:15:36 2004 by doxygen 1.3.5