00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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, §ion)) {
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
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