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 "htpal.h"
00024 #include "htxbeimg.h"
00025 #include "htstring.h"
00026 #include "xbe_analy.h"
00027 #include "xbestruct.h"
00028 #include "snprintf.h"
00029
00030 static ht_view *htxbeimage_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00031 {
00032 ht_xbe_shared_data *xbe_shared=(ht_xbe_shared_data *)group->get_shared_data();
00033
00034 LOG("%s: XBE: loading image (starting analyser)...", file->get_filename());
00035 XBEAnalyser *p = new XBEAnalyser();
00036 p->init(xbe_shared, file);
00037
00038 bounds c=*b;
00039 ht_group *g=new ht_group();
00040 g->init(&c, VO_RESIZE, DESC_XBE_IMAGE"-g");
00041 AnalyInfoline *head;
00042
00043 c.y+=2;
00044 c.h-=2;
00045 ht_xbe_aviewer *v=new ht_xbe_aviewer();
00046 v->init(&c, DESC_XBE_IMAGE, VC_EDIT | VC_GOTO | VC_SEARCH, file, group, p, xbe_shared);
00047
00048 c.y-=2;
00049 c.h=2;
00050 head=new AnalyInfoline();
00051 head->init(&c, v, ANALY_STATUS_DEFAULT);
00052
00053 v->attachInfoline(head);
00054
00055
00056 RVA l=(RVA)-1, h=0;
00057 XBE_SECTION_HEADER *s=xbe_shared->sections.sections;
00058 for (UINT i=0; i<xbe_shared->sections.number_of_sections; i++) {
00059 if (s->virtual_address < l) l = s->virtual_address;
00060 if ((s->virtual_address + s->virtual_size > h) && s->virtual_size) h = s->virtual_address + s->virtual_size - 1;
00061 s++;
00062 }
00063
00064 Address *low;
00065 Address *high;
00066 l+=xbe_shared->header.base_address;
00067 h+=xbe_shared->header.base_address;
00068 low = p->createAddress32(l);
00069 high = p->createAddress32(h);
00070
00071 ht_analy_sub *analy=new ht_analy_sub();
00072 analy->init(file, v, p, low, high);
00073
00074 delete low;
00075 delete high;
00076
00077 v->analy_sub = analy;
00078 v->insertsub(analy);
00079
00080 v->sendmsg(msg_complete_init, 0);
00081
00082 Address *tmpaddr;
00083 tmpaddr = p->createAddress32(xbe_shared->header.entry_point);
00084
00085 v->gotoAddress(tmpaddr, NULL);
00086 delete tmpaddr;
00087
00088 g->insert(head);
00089 g->insert(v);
00090
00091 g->setpalette(palkey_generic_window_default);
00092
00093 xbe_shared->v_image=v;
00094 return g;
00095 }
00096
00097 format_viewer_if htxbeimage_if = {
00098 htxbeimage_init,
00099 0
00100 };
00101
00102 static int xbe_viewer_func_rva(eval_scalar *result, eval_int *i)
00103 {
00104 ht_xbe_aviewer *aviewer = (ht_xbe_aviewer*)eval_get_context();
00105 RVA rva = QWORD_GET_INT(i->value);
00106 viewer_pos p;
00107 FILEOFS ofs;
00108 if (xbe_rva_to_ofs(&aviewer->xbe_shared->sections, rva, &ofs)
00109 && aviewer->offset_to_pos(ofs, &p)) {
00110 Address *a;
00111 int b;
00112 aviewer->convertViewerPosToAddress(p, &a);
00113 a->putIntoArray((byte*)&b);
00114 delete a;
00115 scalar_create_int_c(result, b);
00116 return 1;
00117 } else {
00118 set_eval_error("invalid file offset or no corresponding RVA for '0%xh'", rva);
00119 }
00120 return 0;
00121 }
00122
00123 static int xbe_viewer_func_section_int(eval_scalar *result, eval_int *q)
00124 {
00125 ht_xbe_aviewer *aviewer = (ht_xbe_aviewer*)eval_get_context();
00126 UINT i = QWORD_GET_INT(q->value)-1;
00127 if (!QWORD_GET_HI(q->value) && (i >= 0) &&
00128 (i < aviewer->xbe_shared->sections.number_of_sections)) {
00129 viewer_pos p;
00130 FILEOFS ofs;
00131 if (xbe_rva_to_ofs(&aviewer->xbe_shared->sections,
00132 aviewer->xbe_shared->sections.sections[i].virtual_address,
00133 &ofs)
00134 && aviewer->offset_to_pos(ofs, &p)) {
00135 Address *a;
00136 int b;
00137 aviewer->convertViewerPosToAddress(p, &a);
00138 a->putIntoArray((byte*)&b);
00139 delete a;
00140 scalar_create_int_c(result, b);
00141 return 1;
00142 } else {
00143
00144 }
00145 } else {
00146 set_eval_error("no section number %qd", &q->value);
00147 }
00148 return 0;
00149 }
00150
00151 static int xbe_viewer_func_section_str(eval_scalar *result, eval_str *str)
00152 {
00153 ht_xbe_aviewer *aviewer = (ht_xbe_aviewer*)eval_get_context();
00154 int section;
00155 if (xbe_section_name_to_section(&aviewer->xbe_shared->sections, str->value, §ion)) {
00156 eval_scalar i;
00157 scalar_create_int_c(&i, section+1);
00158 return xbe_viewer_func_section_int(result, &i.scalar.integer);
00159 }
00160 return 0;
00161 }
00162
00163 static int xbe_viewer_func_section(eval_scalar *result, eval_scalar *q)
00164 {
00165 if (q->type == SCALAR_STR)
00166 return xbe_viewer_func_section_str(result, &q->scalar.str);
00167 else {
00168 eval_int i;
00169 scalar_context_int(q, &i);
00170 return xbe_viewer_func_section_int(result, &i);
00171 }
00172 }
00173
00174
00175
00176
00177 void ht_xbe_aviewer::init(bounds *b, char *desc, int caps, ht_streamfile *File, ht_format_group *format_group, Analyser *Analy, ht_xbe_shared_data *XBE_shared)
00178 {
00179 ht_aviewer::init(b, desc, caps, File, format_group, Analy);
00180 xbe_shared = XBE_shared;
00181 }
00182
00183 int ht_xbe_aviewer::func_handler(eval_scalar *result, char *name, eval_scalarlist *params)
00184 {
00185 eval_func myfuncs[] = {
00186 {"rva", (void*)&xbe_viewer_func_rva, {SCALAR_INT},
00187 "returns address of rva"},
00188 {"section", (void*)&xbe_viewer_func_section, {SCALAR_ANY},
00189 "returns address of section named param1 if param1 is a string\n"
00190 "returns address of section with index param1 otherwise"},
00191 {NULL}
00192 };
00193 if (std_eval_func_handler(result, name, params, myfuncs)) return 1;
00194 return ht_aviewer::func_handler(result, name, params);
00195 }
00196
00197 void ht_xbe_aviewer::setAnalyser(Analyser *a)
00198 {
00199 ((XBEAnalyser *)a)->xbe_shared = xbe_shared;
00200 ((XBEAnalyser *)a)->file = file;
00201 analy = a;
00202 analy_sub->setAnalyser(a);
00203 }