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

htpedimp.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      htpedimp.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 "htanaly.h"
00023 #include "htctrl.h"
00024 #include "htendian.h"
00025 #include "htiobox.h"
00026 #include "htnewexe.h"
00027 #include "htpal.h"
00028 #include "htpe.h"
00029 #include "htpeimp.h"
00030 #include "htpedimp.h"
00031 #include "httag.h"
00032 #include "htstring.h"
00033 #include "log.h"
00034 #include "pe_analy.h"
00035 #include "snprintf.h"
00036 #include "stream.h"
00037 
00038 #include <stdlib.h>
00039 
00040 static ht_view *htpedelayimports_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00041 {
00042         ht_pe_shared_data *pe_shared=(ht_pe_shared_data *)group->get_shared_data();
00043 
00044         if (pe_shared->opt_magic!=COFF_OPTMAGIC_PE32) return NULL;
00045 
00046         RVA sec_rva = pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_DELAY_IMPORT].address;
00047         UINT sec_size = pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_DELAY_IMPORT].size;
00048         if (!sec_rva || !sec_size) return NULL;
00049 
00050         int h0=new_timer();
00051         start_timer(h0);
00052 
00053         UINT dll_count=0;
00054         UINT function_count=0;
00055 
00056         ht_group *g;
00057         bounds c;
00058         ht_statictext *head;
00059 
00060         c=*b;
00061         g=new ht_group();
00062         g->init(&c, VO_RESIZE, DESC_PE_DIMPORTS"-g");
00063 
00064         c.y++;
00065         c.h--;
00066         ht_pe_dimport_viewer *v=new ht_pe_dimport_viewer();
00067         v->init(&c, DESC_PE_DIMPORTS, group);
00068 
00069         PE_DELAY_IMPORT_DESCRIPTOR dimport;
00070         UINT dll_index;
00071         char iline[256];
00072 
00073         c.y--;
00074         c.h=1;
00075 /* get delay import directory offset */
00076         /* 1. get import directory rva */
00077         FILEOFS iofs;
00078         RVA irva=pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_DELAY_IMPORT].address;
00079 //      UINT isize=pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_DELAY_IMPORT].size;
00080         /* 2. transform it into an offset */
00081         if (!pe_rva_to_ofs(&pe_shared->sections, irva, &iofs)) goto pe_read_error;
00082         LOG("%s: PE: reading delay-import directory at offset %08x, rva %08x, size %08x...", file->get_filename(), iofs, irva, pe_shared->pe32.header_nt.directory[PE_DIRECTORY_ENTRY_DELAY_IMPORT].size);
00083 
00084 /*** read delay import directory ***/
00085         dll_index=0;
00086 
00087         while (1) {
00088                 file->seek(iofs);
00089                 file->read(&dimport, sizeof dimport);
00090                 create_host_struct(&dimport, PE_DELAY_IMPORT_DESCRIPTOR_struct, little_endian);
00091                 if (!dimport.name) break;
00092                 dword base = dimport.attributes & 1 ? 0 : pe_shared->pe32.header_nt.image_base;
00093 
00094                 FILEOFS dllname_ofs;
00095                 if (!pe_rva_to_ofs(&pe_shared->sections, dimport.name-base, &dllname_ofs)) goto pe_read_error;
00096                 file->seek(dllname_ofs);
00097                 char *dllname=fgetstrz(file);
00098                 ht_pe_import_library *lib=new ht_pe_import_library(dllname);
00099                 pe_shared->dimports.libs->insert(lib);
00100                 dll_count++;
00101 
00102                 FILEOFS ntofs, atofs;
00103                 UINT nva, ava;
00104                 if (!pe_rva_to_ofs(&pe_shared->sections, dimport.delay_int-base, &ntofs)) goto pe_read_error;
00105                 if (!pe_rva_to_ofs(&pe_shared->sections, dimport.delay_iat-base, &atofs)) goto pe_read_error;
00106                 while (1) {
00107                         ht_pe_import_function *func;
00108                         file->seek(ntofs);
00109                         file->read(&nva, 4);
00110                         nva = create_host_int(&nva, 4, little_endian);
00111                         if (!nva) break;
00112                         function_count++;
00113                         file->seek(atofs);
00114                         file->read(&ava, 4);
00115                         ava = create_host_int(&ava, 4, little_endian);
00116                         if (nva & 0x80000000) {
00117 /* import by ordinal */
00118                                 func=new ht_pe_import_function(dll_index, ava, nva&0xffff);
00119                         } else {
00120                                 FILEOFS nofs;
00121 /* import by name */
00122                                 if (!pe_rva_to_ofs(&pe_shared->sections, nva-base, &nofs)) goto pe_read_error;
00123                                 word hint=0;
00124                                 file->seek(nofs);
00125                                 file->read(&hint, 2);
00126                                 hint = create_host_int(&hint, 2, little_endian);
00127                                 char *name=fgetstrz(file);
00128                                 func=new ht_pe_import_function(dll_index, ava, name, hint);
00129                                 free(name);
00130                         }
00131                         pe_shared->dimports.funcs->insert(func);
00132                         ntofs+=4;
00133                         atofs+=4;
00134                 }
00135 
00136                 free(dllname);
00137                 iofs+=sizeof dimport;
00138                 dll_index++;
00139         }
00140 
00141         stop_timer(h0);
00142 //      LOG("%s: PE: %d ticks (%d msec) to read delay-imports", file->get_name(), get_timer_tick(h0), get_timer_msec(h0));
00143         delete_timer(h0);
00144 
00145         ht_snprintf(iline, sizeof iline, "* PE delay-import directory at offset %08x (%d delay-imports from %d libraries)", iofs, function_count, dll_count);
00146 
00147         head=new ht_statictext();
00148         head->init(&c, iline, align_left);
00149 
00150         g->insert(head);
00151         g->insert(v);
00152 //
00153         for (UINT i=0; i<pe_shared->dimports.funcs->count(); i++) {
00154                 ht_pe_import_function *func = (ht_pe_import_function*)pe_shared->dimports.funcs->get(i);
00155                 assert(func);
00156                 ht_pe_import_library *lib = (ht_pe_import_library*)pe_shared->dimports.libs->get(func->libidx);
00157                 assert(lib);
00158                 char addr[32], name[256];
00159                 ht_snprintf(addr, sizeof addr, "%08x", func->address);
00160                 if (func->byname) {
00161                         ht_snprintf(name, sizeof name, "%s", func->name.name);
00162                 } else {
00163                         ht_snprintf(name, sizeof name, "%04x (by ordinal)", func->ordinal);
00164                 }
00165                 v->insert_str(i, lib->name, addr, name);
00166         }
00167 //
00168         v->update();
00169 
00170         g->setpalette(palkey_generic_window_default);
00171 
00172         pe_shared->v_dimports=v;
00173 
00174         return g;
00175 pe_read_error:
00176         delete_timer(h0);
00177         errorbox("%s: PE delay-import directory seems to be corrupted.", file->get_filename());
00178         v->done();
00179         delete v;
00180         g->done();
00181         delete g;
00182         return NULL;
00183 }
00184 
00185 format_viewer_if htpedelayimports_if = {
00186         htpedelayimports_init,
00187         NULL
00188 };
00189 
00190 /*
00191  *      CLASS ht_pe_dimport_viewer
00192  */
00193 
00194 bool ht_pe_dimport_viewer::select_entry(void *entry)
00195 {
00196         ht_text_listbox_item *i = (ht_text_listbox_item *)entry;
00197 
00198         ht_pe_shared_data *pe_shared=(ht_pe_shared_data *)format_group->get_shared_data();
00199 
00200         ht_pe_import_function *e = (ht_pe_import_function*)pe_shared->dimports.funcs->get(i->id);
00201         if (!e) return true;
00202         if (pe_shared->v_image) {
00203                 ht_aviewer *av = (ht_aviewer*)pe_shared->v_image;
00204                 PEAnalyser *a = (PEAnalyser*)av->analy;
00205                 Address *addr;
00206                 if (pe_shared->opt_magic == COFF_OPTMAGIC_PE32) {
00207                         addr = a->createAddress32(e->address/*+pe_shared->pe32.header_nt.image_base*/);
00208                 } else {
00209                         addr = a->createAddress64(to_qword(e->address)/*+pe_shared->pe64.header_nt.image_base*/);
00210                 }
00211                 if (av->gotoAddress(addr, NULL)) {
00212                         app->focus(av);
00213                         vstate_save();
00214                 } else {
00215                         global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT | ADDRESS_STRING_FORMAT_ADD_0X;
00216                         errorbox("can't follow: %s %y is not valid !", "delay-import address", addr);
00217                 }
00218                 delete addr;
00219         } else errorbox("can't follow: no image viewer");
00220         return true;
00221 }
00222 

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