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

htpeil.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      htpeil.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 "formats.h"
00022 #include "htapp.h"
00023 #include "htatom.h"
00024 #include "htcoff.h"
00025 #include "htctrl.h"
00026 #include "htendian.h"
00027 #include "hthex.h"
00028 #include "htiobox.h"
00029 #include "htnewexe.h"
00030 #include "htpe.h"
00031 #include "htpehead.h"
00032 #include "htpeil.h"
00033 #include "httag.h"
00034 #include "htstring.h"
00035 #include "snprintf.h"
00036 
00037 #include "pestruct.h"
00038 #include "ilopc.h"
00039 #include "ilstruct.h"
00040 
00041 #include <string.h>
00042 
00043 static ht_mask_ptable il_directory[] = {
00044         {"size",           STATICTAG_EDIT_DWORD_LE("00000000")},
00045         {"major version",  STATICTAG_EDIT_WORD_LE("00000004")},
00046         {"minor version",  STATICTAG_EDIT_WORD_LE("00000006")},
00047         {"metadata rva",   STATICTAG_EDIT_DWORD_LE("00000008")},
00048         {"metadata size",  STATICTAG_EDIT_DWORD_LE("0000000c")},
00049         {"attributes",     STATICTAG_EDIT_DWORD_LE("00000010")},
00050         {0, 0}
00051 };
00052 
00053 static ht_mask_ptable metadata_section[] = {
00054         {"magic",                 STATICTAG_EDIT_DWORD_LE("00000000")},
00055         {"major_version",         STATICTAG_EDIT_WORD_LE("00000004")},
00056         {"minor_version",         STATICTAG_EDIT_WORD_LE("00000006")},
00057         {"unknown",               STATICTAG_EDIT_DWORD_LE("00000008")},
00058         {"version_string_length", STATICTAG_EDIT_DWORD_LE("00000010")},
00059         {0, 0}
00060 };
00061 
00062 static ht_view *htpeil_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00063 {
00064         ht_pe_shared_data *pe_shared=(ht_pe_shared_data *)group->get_shared_data();
00065 
00066         if (pe_shared->opt_magic!=COFF_OPTMAGIC_PE32) return NULL;
00067 
00068         dword sec_rva, sec_size;
00069         FILEOFS sec_ofs;
00070         sec_rva = pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_IL].address;
00071         sec_size = pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_IL].size;
00072         if (!sec_rva || !sec_size) return NULL;
00073 
00074         PE_IL_DIRECTORY dir;
00075         bool pe_bigendian = false;
00076         ht_pe_il_viewer *v;
00077 
00078         if (!pe_rva_to_ofs(&pe_shared->sections, sec_rva, &sec_ofs)) goto read_error;
00079                 
00080         file->seek(sec_ofs);
00081         if (file->read(&dir, sizeof dir) != sizeof dir) goto read_error;
00082 
00083         create_host_struct(&dir, PE_IL_DIRECTORY_struct, little_endian);
00084         
00085         if (sec_size != dir.size) goto read_error;
00086         
00087         pe_shared->il = new ht_pe_il();
00088         pe_shared->il->dir = dir;
00089 
00090         v=new ht_pe_il_viewer();
00091         v->init(b, DESC_PE_IL, VC_EDIT | VC_SEARCH, file, group);
00092         pe_shared->v_il = v;
00093         ht_mask_sub *s;
00094 //      ht_collapsable_sub *cs;
00095         
00096         s=new ht_mask_sub();
00097         s->init(file, 0);
00098         char info[128];
00099         ht_snprintf(info, sizeof info, "* COM+ directory at offset %08x", sec_ofs);
00100         s->add_mask(info);
00101         v->insertsub(s);
00102 
00103 /* FIXME: */
00104         
00105         s=new ht_mask_sub();
00106         s->init(file, 1);
00107         s->add_staticmask_ptable(il_directory, sec_ofs, pe_bigendian);
00108         v->insertsub(s);
00109         
00110         FILEOFS metadata_ofs;
00111         if (pe_rva_to_ofs(&pe_shared->sections, dir.metadata_section_rva, &metadata_ofs)) {
00112                 /* read metadata section*/
00113                 IL_METADATA_SECTION metadata;
00114                 file->seek(metadata_ofs);
00115                 if (file->read(&metadata, sizeof metadata) == sizeof metadata) {
00116                         create_host_struct(&metadata, IL_METADATA_SECTION_struct, little_endian);
00117                         pe_shared->il->metadata = metadata;
00118                         dword add = 2;
00119                         if (metadata.minor_version == 1) {
00120                                 // FIXME: align metadata.version_string_length
00121                                 dword version_string_length;
00122                                 file->read(&version_string_length, 4); // dummy
00123                                 file->read(&version_string_length, 4);
00124                                 version_string_length = create_host_int(&version_string_length, 4, little_endian);
00125                                 add += version_string_length + 8;
00126                         }
00127                         FILEOFS ofs = metadata_ofs + sizeof metadata + add;
00128                         file->seek(ofs);
00129                         word count;
00130                         file->read(&count, 2);
00131                         count = create_host_int(&count, 2, little_endian);
00132                         pe_shared->il->entries = new ht_clist();
00133                         pe_shared->il->entries->init();
00134                         for (UINT i=0; i<count; i++) {
00135                                 IL_METADATA_SECTION_ENTRY sec_entry;
00136                                 ht_il_metadata_entry *entry;
00137                                 // FIXME: error handling
00138                                 file->read(&sec_entry, sizeof sec_entry);
00139                                 create_host_struct(&sec_entry, IL_METADATA_SECTION_ENTRY_struct, little_endian);
00140                                 char *name = fgetstrz(file);
00141                                 int nlen = strlen(name)+1;
00142                                 dword dummy;
00143                                 if (nlen % 4) {
00144                                         // align properly
00145                                         file->read(&dummy, 4 - nlen % 4);
00146                                 }
00147                                 entry = new ht_il_metadata_entry(name, metadata_ofs+sec_entry.offset, sec_entry.size);
00148 //                              fprintf(stderr, "%s %x %x\n", name, metadata_ofs+sec_entry.offset, sec_entry.size);
00149                                 pe_shared->il->entries->insert(entry);
00150 
00151                                 free(name);
00152                         }
00153                         for (UINT i=0; i<count; i++) {
00154                                 ht_il_metadata_entry *entry = (ht_il_metadata_entry *)pe_shared->il->entries->get(i);
00155                                 if (strcmp(entry->name, "#~") == 0) {
00156                                         // token index
00157                                         char dummy[8];
00158                                         qword types;
00159                                         file->seek(entry->offset);
00160                                         file->read(&dummy, 8);
00161                                         file->read(&types, 8);
00162 //                                      file->read();
00163                                 } else if (strcmp(entry->name, "#US")==0) {
00164                                         // stringpool
00165                                         pe_shared->il->string_pool = (char*)malloc(entry->size);
00166                                         file->seek(entry->offset);
00167                                         pe_shared->il->string_pool_size = file->read(pe_shared->il->string_pool, entry->size);
00168                                 }
00169                         }
00170                 }               
00171         }
00172         
00173         return v;
00174 
00175 read_error:
00176         return NULL;
00177 }
00178 
00179 format_viewer_if htpeil_if = {
00180         htpeil_init,
00181         0
00182 };
00183 
00184 /*
00185  *      CLASS ht_pe_header_viewer
00186  */
00187 
00188 void ht_pe_il_viewer::init(bounds *b, char *desc, int caps, ht_streamfile *file, ht_format_group *group)
00189 {
00190         ht_uformat_viewer::init(b, desc, caps, file, group);
00191         VIEW_DEBUG_NAME("ht_pe_il_viewer");
00192 }
00193 
00194 void ht_pe_il_viewer::done()
00195 {
00196         ht_pe_shared_data *pe_shared=(ht_pe_shared_data *)format_group->get_shared_data();
00197         if (pe_shared && pe_shared->il) {
00198                 if (pe_shared->il->string_pool) free(pe_shared->il->string_pool);
00199                 if (pe_shared->il->entries) {
00200                     pe_shared->il->entries->destroy();
00201                     delete pe_shared->il->entries;
00202                 }
00203                 delete pe_shared->il;
00204         }
00205         ht_uformat_viewer::done();
00206 }
00207 
00208 ht_il_metadata_entry::ht_il_metadata_entry(char *n, dword o, dword s)
00209 {
00210         name = ht_strdup(n);
00211         offset = o;
00212         size = s;
00213 }
00214 
00215 ht_il_metadata_entry::~ht_il_metadata_entry()
00216 {
00217         free(name);
00218 }
00219 
00220 /*
00221  *      NOTE: ILunpack returns result in host-endianess
00222  */
00223 int ILunpackDword(dword &result, const byte *buf, int len)
00224 {
00225         if (len) {
00226                 result = *(buf++);
00227                 len--;
00228                 if (result < 0x80) return 1; // one byte form
00229                 if (!len) return 0;
00230                 if ((result & 0xc0) == 0x80) {
00231                         // two byte form
00232                         result = ((result & 0x3f) << 8) | buf[0];
00233                         return 2;
00234                 } else if ((result & 0xe0) == 0xc0) {
00235                         // four byte form
00236                         if (len < 2) return 0;
00237                         result = ((result & 0x1F) << 24) |
00238                                     (((dword)buf[0]) << 16) |
00239                                     (((dword)buf[1]) << 8) |
00240                                          (dword)buf[2];
00241                         return 4;
00242                 } else if ((result & 0xf0) == 0xe0) {
00243                         // five byte form
00244                         if (len < 3) return 0;
00245                         result = (((dword)buf[0]) << 24) |
00246                                     (((dword)buf[1]) << 16) |
00247                                     (((dword)buf[2]) << 8) |
00248                                          (dword)buf[3];
00249                         return 5;
00250                 }
00251         }
00252         return 0;
00253 }
00254 
00255 int ILunpackToken(dword &result, const byte *buf, int len)
00256 {
00257         int read = ILunpackDword(result, buf, len);
00258         if (!read) return 0;
00259         dword type;
00260         switch (result & 0x03) {
00261                 case 0x00:
00262                         type = IL_META_TOKEN_TYPE_DEF;
00263                         break;
00264                 case 0x01:
00265                         type = IL_META_TOKEN_TYPE_REF;
00266                         break;
00267                 case 0x02:
00268                         type = IL_META_TOKEN_TYPE_SPEC;
00269                         break;
00270                 default:
00271                         type = IL_META_TOKEN_BASE_TYPE;
00272         }
00273         result = (result >> 2) | type;
00274         return read;
00275 }

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