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

htpeimg.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      htpeimg.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 "formats.h"
00023 #include "htnewexe.h"
00024 #include "htpal.h"
00025 #include "htpeimg.h"
00026 #include "htstring.h"
00027 #include "pe_analy.h"
00028 #include "pestruct.h"
00029 #include "snprintf.h"
00030 
00031 static ht_view *htpeimage_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00032 {
00033         ht_pe_shared_data *pe_shared=(ht_pe_shared_data *)group->get_shared_data();
00034 
00035         if (pe_shared->opt_magic!=COFF_OPTMAGIC_PE32 && pe_shared->opt_magic!=COFF_OPTMAGIC_PE64) return 0;
00036 
00037         bool pe32 = (pe_shared->opt_magic==COFF_OPTMAGIC_PE32);
00038 
00039         LOG("%s: PE: loading image (starting analyser)...", file->get_filename());
00040         PEAnalyser *p = new PEAnalyser();
00041         p->init(pe_shared, file);
00042 
00043         bounds c=*b;
00044         ht_group *g=new ht_group();
00045         g->init(&c, VO_RESIZE, DESC_PE_IMAGE"-g");
00046         AnalyInfoline *head;
00047 
00048         c.y+=2;
00049         c.h-=2;
00050         ht_pe_aviewer *v=new ht_pe_aviewer();
00051         v->init(&c, DESC_PE_IMAGE, VC_EDIT | VC_GOTO | VC_SEARCH, file, group, p, pe_shared);
00052 
00053         c.y-=2;
00054         c.h=2;
00055         head=new AnalyInfoline();
00056         head->init(&c, v, ANALY_STATUS_DEFAULT);
00057 
00058         v->attachInfoline(head);
00059 
00060 /* search for lowest/highest */
00061         RVA l=(RVA)-1, h=0;
00062         COFF_SECTION_HEADER *s=pe_shared->sections.sections;
00063         for (UINT i=0; i<pe_shared->sections.section_count; i++) {
00064                 if (s->data_address < l) l = s->data_address;
00065                 if ((s->data_address + s->data_size > h) && s->data_size) h = s->data_address + s->data_size - 1;
00066                 s++;
00067         }
00068 
00069         Address *low;
00070         Address *high;
00071         if (pe32) {
00072                 l += pe_shared->pe32.header_nt.image_base;
00073                 h += pe_shared->pe32.header_nt.image_base;
00074                 low = p->createAddress32(l);
00075                 high = p->createAddress32(h);
00076         } else {
00077                 low = p->createAddress64(to_qword(l) + pe_shared->pe64.header_nt.image_base);
00078                 high = p->createAddress64(to_qword(h) + pe_shared->pe64.header_nt.image_base);
00079         }
00080         
00081         ht_analy_sub *analy=new ht_analy_sub();
00082         analy->init(file, v, p, low, high);
00083         
00084         delete low;
00085         delete high;
00086         
00087         v->analy_sub = analy;
00088         v->insertsub(analy);
00089 
00090         v->sendmsg(msg_complete_init, 0);
00091 
00092         Address *tmpaddr;
00093         if (pe32) {
00094                 tmpaddr = p->createAddress32(pe_shared->pe32.header.entrypoint_address+pe_shared->pe32.header_nt.image_base);
00095         } else {
00096                 tmpaddr = p->createAddress64(to_qword(pe_shared->pe64.header.entrypoint_address)+pe_shared->pe64.header_nt.image_base);
00097         }
00098         v->gotoAddress(tmpaddr, NULL);
00099         delete tmpaddr;
00100         
00101         g->insert(head);
00102         g->insert(v);
00103 
00104         g->setpalette(palkey_generic_window_default);
00105 
00106         pe_shared->v_image=v;
00107         return g;
00108 }
00109 
00110 format_viewer_if htpeimage_if = {
00111         htpeimage_init,
00112         0
00113 };
00114 
00115 static int pe_viewer_func_rva(eval_scalar *result, eval_int *i)
00116 {
00117         ht_pe_aviewer *aviewer = (ht_pe_aviewer*)eval_get_context();
00118         RVA rva = QWORD_GET_INT(i->value);
00119         viewer_pos p;
00120         FILEOFS ofs;
00121         if (pe_rva_to_ofs(&aviewer->pe_shared->sections, rva, &ofs)
00122         && aviewer->offset_to_pos(ofs, &p)) {
00123                 Address *a;
00124                 int b;
00125                 aviewer->convertViewerPosToAddress(p, &a);
00126                 a->putIntoArray((byte*)&b);
00127                 delete a;
00128                 scalar_create_int_c(result, b);
00129                 return 1;
00130         } else {
00131                 set_eval_error("invalid file offset or no corresponding RVA for '0%xh'", rva);
00132         }
00133         return 0;
00134 }
00135 
00136 static int pe_viewer_func_section_int(eval_scalar *result, eval_int *q)
00137 {
00138         ht_pe_aviewer *aviewer = (ht_pe_aviewer*)eval_get_context();
00139         UINT i = QWORD_GET_INT(q->value)-1;
00140         if (!QWORD_GET_HI(q->value) && (i >= 0) &&
00141         (i < aviewer->pe_shared->sections.section_count)) {
00142                 viewer_pos p;
00143                 FILEOFS ofs;
00144                 if (pe_rva_to_ofs(&aviewer->pe_shared->sections,
00145                                             aviewer->pe_shared->sections.sections[i].data_address,
00146                                            &ofs)
00147                  && aviewer->offset_to_pos(ofs, &p)) {
00148                         Address *a;
00149                         int b;
00150                         aviewer->convertViewerPosToAddress(p, &a);
00151                         a->putIntoArray((byte*)&b);
00152                         delete a;
00153                         scalar_create_int_c(result, b);
00154                         return 1;
00155                 } else {
00156 //                      set_eval_error("invalid file offset or no corresponding RVA for '0%xh'", rva);
00157                 }     
00158         } else {
00159                 set_eval_error("no section number %qd", &q->value);
00160         }
00161         return 0;
00162 }
00163 
00164 static int pe_viewer_func_section_str(eval_scalar *result, eval_str *str)
00165 {
00166         ht_pe_aviewer *aviewer = (ht_pe_aviewer*)eval_get_context();
00167         int section;
00168         char str2[COFF_SIZEOF_SHORT_NAME+1];
00169         memset(str2, 0, COFF_SIZEOF_SHORT_NAME+1);
00170         memmove(str2, str->value, MIN(str->len, COFF_SIZEOF_SHORT_NAME));
00171         if (pe_section_name_to_section(&aviewer->pe_shared->sections, str2, &section)) {
00172                 eval_scalar i;
00173                 scalar_create_int_c(&i, section+1);
00174                 return pe_viewer_func_section_int(result, &i.scalar.integer);
00175         }
00176         return 0;
00177 }
00178 
00179 static int pe_viewer_func_section(eval_scalar *result, eval_scalar *q)
00180 {
00181         if (q->type == SCALAR_STR)
00182                 return pe_viewer_func_section_str(result, &q->scalar.str);
00183         else {
00184                 eval_int i;
00185                 scalar_context_int(q, &i);
00186                 return pe_viewer_func_section_int(result, &i);
00187         }
00188 }
00189 
00190 /*
00191  *      CLASS ht_pe_aviewer
00192  */
00193 void ht_pe_aviewer::init(bounds *b, char *desc, int caps, ht_streamfile *File, ht_format_group *format_group, Analyser *Analy, ht_pe_shared_data *PE_shared)
00194 {
00195         ht_aviewer::init(b, desc, caps, File, format_group, Analy);
00196         pe_shared = PE_shared;
00197 }
00198 
00199 int ht_pe_aviewer::func_handler(eval_scalar *result, char *name, eval_scalarlist *params)
00200 {
00201         eval_func myfuncs[] = {
00202                 {"rva", (void*)&pe_viewer_func_rva, {SCALAR_INT},
00203                         "returns address of rva"},
00204                 {"section", (void*)&pe_viewer_func_section, {SCALAR_ANY},
00205                         "returns address of section named param1 if param1 is a string\n"
00206                         "returns address of section with index param1 otherwise"},
00207                 {NULL}
00208         };
00209         if (std_eval_func_handler(result, name, params, myfuncs)) return 1;
00210         return ht_aviewer::func_handler(result, name, params);
00211 }
00212 
00213 void ht_pe_aviewer::setAnalyser(Analyser *a)
00214 {
00215         ((PEAnalyser *)a)->pe_shared = pe_shared;
00216         ((PEAnalyser *)a)->file = file;
00217         analy = a;
00218         analy_sub->setAnalyser(a);
00219 }
00220 

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