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

xbe_analy.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      xbe_analy.cc
00004  *
00005  *      Copyright (C) 2003 Stefan Esser
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 <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 #include "analy.h"
00026 #include "analy_alpha.h"
00027 #include "analy_ia64.h"
00028 #include "analy_il.h"
00029 #include "analy_names.h"
00030 #include "analy_register.h"
00031 #include "analy_ppc.h"
00032 #include "analy_x86.h"
00033 #include "global.h"
00034 #include "htctrl.h"
00035 #include "htdebug.h"
00036 #include "htiobox.h"
00037 #include "htxbeimp.h"
00038 #include "htxbe.h"
00039 #include "htstring.h"
00040 #include "ilopc.h"
00041 #include "xbe_analy.h"
00042 #include "xbestruct.h"
00043 #include "snprintf.h"
00044 #include "x86asm.h"
00045 
00046 /*
00047  *
00048  */
00049 void    XBEAnalyser::init(ht_xbe_shared_data *XBE_shared, ht_streamfile *File)
00050 {
00051         xbe_shared = XBE_shared;
00052         file = File;
00053 
00054         validarea = new Area();
00055         validarea->init();
00056 
00057         Analyser::init();
00058 }
00059 
00060 
00061 /*
00062  *
00063  */
00064 int     XBEAnalyser::load(ht_object_stream *f)
00065 {
00066         GET_OBJECT(f, validarea);
00067         return Analyser::load(f);
00068 }
00069 
00070 /*
00071  *
00072  */
00073 void    XBEAnalyser::done()
00074 {
00075         validarea->done();
00076         delete validarea;
00077         Analyser::done();
00078 }
00079 
00080 /*
00081  *
00082  */
00083 void XBEAnalyser::beginAnalysis()
00084 {
00085         char    buffer[1024];
00086 
00087         setLocationTreeOptimizeThreshold(100);
00088         setSymbolTreeOptimizeThreshold(100);
00089 
00090         /*
00091          *      entrypoint
00092          */
00093         Address *entry;
00094 
00095         entry = createAddress32(xbe_shared->header.entry_point);
00096         pushAddress(entry, entry);
00097         
00098         /*
00099          * give all sections a descriptive comment:
00100          */
00101 
00102         XBE_SECTION_HEADER *s=xbe_shared->sections.sections;
00103         char blub[100];
00104         for (UINT i=0; i<xbe_shared->sections.number_of_sections; i++) {
00105                 Address *secaddr;
00106 
00107                 secaddr = createAddress32(s->virtual_address);
00108 
00109                 ht_snprintf(blub, sizeof blub, ";  TEST section %d <%s>", i+1, getSegmentNameByAddress(secaddr));
00110                 addComment(secaddr, 0, "");
00111                 addComment(secaddr, 0, ";******************************************************************");
00112                 addComment(secaddr, 0, blub);
00113                 ht_snprintf(blub, sizeof blub, ";  virtual address  %08x  virtual size   %08x", s->virtual_address, s->virtual_size);
00114                 addComment(secaddr, 0, blub);
00115                 ht_snprintf(blub, sizeof blub, ";  file offset      %08x  file size      %08x", s->raw_address, s->raw_size);
00116                 addComment(secaddr, 0, blub);
00117                 addComment(secaddr, 0, ";******************************************************************");
00118 
00119                 // mark end of sections
00120                 ht_snprintf(blub, sizeof blub, ";  end of section <%s>", getSegmentNameByAddress(secaddr));
00121                 Address *secend_addr = (Address *)secaddr->duplicate();
00122                 secend_addr->add(MAX(s->virtual_size, s->raw_size));
00123                 newLocation(secend_addr)->flags |= AF_FUNCTION_END;
00124                 addComment(secend_addr, 0, "");
00125                 addComment(secend_addr, 0, ";******************************************************************");
00126                 addComment(secend_addr, 0, blub);
00127                 addComment(secend_addr, 0, ";******************************************************************");
00128 
00129                 validarea->add(secaddr, secend_addr);
00130                 Address *seciniaddr = (Address *)secaddr->duplicate();
00131                 seciniaddr->add(MIN(s->virtual_size, s->raw_size));
00132                 if (validAddress(secaddr, scinitialized) && validAddress(seciniaddr, scinitialized)) {
00133                         initialized->add(secaddr, seciniaddr);
00134                 }
00135                 s++;
00136                 delete secaddr;
00137                 delete secend_addr;
00138                 delete seciniaddr;
00139         }
00140 
00141         int import_count=xbe_shared->imports.funcs->count();
00142         int *entropy = random_permutation(import_count);
00143         for (int i=0; i<import_count; i++) {
00144                 ht_xbe_import_function *f=(ht_xbe_import_function *)xbe_shared->imports.funcs->get(*(entropy+i));
00145 //              ht_pe_import_library *d=(ht_pe_import_library *)pe_shared->imports.libs->get(f->libidx);
00146                 char *label;
00147                 label = import_func_name("NTOSKRNL.EXE", (f->byname) ? f->name.name : NULL, f->ordinal);
00148                 Address *faddr;
00149 
00150                 faddr = createAddress32(f->address+xbe_shared->header.base_address);
00151 
00152                 addComment(faddr, 0, "");
00153                 if (!assignSymbol(faddr, label, label_func)) {
00154                         // multiple import of a function (duplicate labelname)
00155                         // -> mangle name a bit more
00156                         addComment(faddr, 0, "; duplicate import");               
00157                         ht_snprintf(buffer, sizeof buffer, "%s_%x", label, f->address);
00158                         assignSymbol(faddr, buffer, label_func);
00159                 }
00160                 data->setIntAddressType(faddr, dst_idword, 4);
00161                 free(label);
00162                 delete faddr;
00163         }
00164         if (entropy) free(entropy);
00165 
00166 
00167         addComment(entry, 0, "");
00168         addComment(entry, 0, ";****************************");
00169         addComment(entry, 0, ";  program entry point");
00170         addComment(entry, 0, ";****************************");
00171         assignSymbol(entry, "entrypoint", label_func);
00172 
00173         setLocationTreeOptimizeThreshold(1000);
00174         setSymbolTreeOptimizeThreshold(1000);
00175         delete entry;
00176 
00177         Address *tls;
00178         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+0);
00179         assignSymbol(tls, "tls.data_start_address", label_data);
00180         free(tls);
00181         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+4);
00182         assignSymbol(tls, "tls.data_end_address", label_data);
00183         free(tls);
00184         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+8);
00185         assignSymbol(tls, "tls.index_address", label_data);
00186         free(tls);
00187         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+12);
00188         assignSymbol(tls, "tls.callback_address", label_data);
00189         free(tls);
00190         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+16);
00191         assignSymbol(tls, "tls.size_of_zero_fill", label_data);
00192         free(tls);
00193         tls = createAddress32(xbe_shared->header.tls_address+xbe_shared->header.base_address+20);
00194         assignSymbol(tls, "tls.characteristics", label_data);
00195         free(tls);
00196 
00197         Analyser::beginAnalysis();
00198 }
00199 
00200 /*
00201  *
00202  */
00203 OBJECT_ID       XBEAnalyser::object_id() const
00204 {
00205         return ATOM_XBE_ANALYSER;
00206 }
00207 
00208 /*
00209  *
00210  */
00211 UINT XBEAnalyser::bufPtr(Address *Addr, byte *buf, int size)
00212 {
00213         FILEOFS ofs = addressToFileofs(Addr);
00214 /*      if (ofs == INVALID_FILE_OFS) {
00215                 int as=0;
00216         }*/
00217         assert(ofs != INVALID_FILE_OFS);
00218         file->seek(ofs);
00219         return file->read(buf, size);
00220 }
00221 
00222 bool XBEAnalyser::convertAddressToRVA(Address *addr, RVA *r)
00223 {
00224         OBJECT_ID oid = addr->object_id();
00225         if (oid==ATOM_ADDRESS_FLAT_32) {
00226                 *r = ((AddressFlat32*)addr)->addr - xbe_shared->header.base_address;
00227                 return true;
00228         } else if (oid == ATOM_ADDRESS_X86_FLAT_32) {
00229                 *r = ((AddressX86Flat32*)addr)->addr - xbe_shared->header.base_address;
00230                 return true;
00231         }
00232 //      *r = ((AddressFlat32*)addr)->addr - xbe_shared->header.base_address;
00233 //      *r = ((AddressX86Flat32*)addr)->addr - xbe_shared->header.base_address;
00234         return false;
00235 }
00236 
00237 /*
00238  *
00239  */
00240 Address *XBEAnalyser::createAddress32(dword addr)
00241 {
00242         return new AddressX86Flat32(addr);
00243 //      return new AddressFlat32(addr);
00244 }
00245 
00246 /*
00247  *
00248  */
00249 Address *XBEAnalyser::createAddress64(qword addr)
00250 {
00251         return NULL;
00252 }
00253 
00254 Address *XBEAnalyser::createAddress()
00255 {
00256         return new AddressX86Flat32();
00257 //      return new AddressFlat32();
00258 }
00259 
00260 /*
00261  *
00262  */
00263 Assembler *XBEAnalyser::createAssembler()
00264 {
00265         Assembler *a = new x86asm(X86_OPSIZE32, X86_ADDRSIZE32);
00266         a->init();
00267         return a;
00268 }
00269 
00270 /*
00271  *
00272  */
00273 FILEOFS XBEAnalyser::addressToFileofs(Address *Addr)
00274 {
00275 /*     char tbuf[1024];
00276         Addr->stringify(tbuf, 1024, 0);
00277         printf("ADDR=%s", tbuf);*/
00278         if (validAddress(Addr, scinitialized)) {
00279 //      printf(" v1\n");
00280                 FILEOFS ofs;
00281                 RVA r;
00282                 if (!convertAddressToRVA(Addr, &r)) return INVALID_FILE_OFS;
00283                 if (!xbe_rva_to_ofs(&xbe_shared->sections, r, &ofs)) return INVALID_FILE_OFS;
00284                 return ofs;
00285         } else {
00286 //      printf(" IV1\n");
00287                 return INVALID_FILE_OFS;
00288         }
00289 }
00290 
00291 /*
00292  *
00293  */
00294 char *XBEAnalyser::getSegmentNameByAddress(Address *Addr)
00295 {
00296         static char sectionname[9];
00297         xbe_section_headers *sections=&xbe_shared->sections;
00298         int i;
00299         RVA r;
00300         bool b;
00301 
00302 //      Addr-=pe_shared->pe32.header_nt.image_base;
00303         if (!convertAddressToRVA(Addr, &r)) return NULL;
00304         
00305 //      { FILE *f;f=fopen("/tmp/rva","a+");if (f){fprintf(f,"rva: %08x\n",r);fclose(f);} }
00306         
00307         xbe_rva_to_section(sections, r, &i);
00308 //      XBE_SECTION_HEADER *s=sections->sections+i;
00309         b = xbe_rva_is_valid(sections, r);
00310 //      { FILE *f;f=fopen("/tmp/rva","a+");if (f){fprintf(f,"rva: %08x %u\n",r,(UINT)b);fclose(f);} }
00311         
00312         if (!b) return NULL;
00313 
00314         memmove(sectionname, "<notyet>", 8);
00315         sectionname[8]=0;
00316         return sectionname;
00317 }
00318 
00319 /*
00320  *
00321  */
00322 const char *XBEAnalyser::getName()
00323 {
00324         return file->get_desc();
00325 }
00326 
00327 /*
00328  *
00329  */
00330 const char *XBEAnalyser::getType()
00331 {
00332         return "XBE/Analyser";
00333 }
00334 
00335 /*
00336  *
00337  */
00338 void XBEAnalyser::initCodeAnalyser()
00339 {
00340         Analyser::initCodeAnalyser();
00341 }
00342 /*
00343 static char *string_func(dword ofs, void *context)
00344 {
00345         char str[1024];
00346         static char str2[1024];
00347         ht_pe_shared_data *pe = (ht_pe_shared_data*)context;
00348         if (ofs < pe->il->string_pool_size) {
00349                 dword length;
00350                 dword o = ILunpackDword(length, (byte*)&pe->il->string_pool[ofs], 10);
00351                 wide_char_to_multi_byte(str, (byte*)&pe->il->string_pool[ofs+o], length/2+1);
00352                 escape_special_str(str2, sizeof str2, str, "\"");
00353                 return str2;
00354         } else {
00355                 return NULL;
00356         }
00357 }
00358 
00359 static char *token_func(dword token, void *context)
00360 {
00361         static char tokenstr[1024];
00362         switch (token & IL_META_TOKEN_MASK) {
00363                 case IL_META_TOKEN_TYPE_REF:
00364                 case IL_META_TOKEN_TYPE_DEF: {
00365                         sprintf(tokenstr, "typedef");
00366                         break;
00367                 }
00368                 case IL_META_TOKEN_FIELD_DEF: {
00369                         sprintf(tokenstr, "fielddef");
00370                         break;
00371                 }
00372                 case IL_META_TOKEN_METHOD_DEF: {
00373                         sprintf(tokenstr, "methoddef");
00374                         break;
00375                 }
00376                 case IL_META_TOKEN_MEMBER_REF: {
00377                         sprintf(tokenstr, "memberref");
00378                         break;
00379                 }
00380                 case IL_META_TOKEN_TYPE_SPEC: {
00381                         sprintf(tokenstr, "typespec");
00382                         break;
00383                 }
00384                 default:
00385                         return NULL;
00386         }
00387         return tokenstr;
00388 }
00389 */
00390 
00391 /*
00392  *
00393  */
00394 void XBEAnalyser::initUnasm()
00395 {
00396         DPRINTF("xbe_analy: ");
00397 
00398         DPRINTF("initing analy_x86_disassembler\n");
00399         analy_disasm = new AnalyX86Disassembler();
00400         ((AnalyX86Disassembler *)analy_disasm)->init(this, 0);
00401 }
00402 
00403 /*
00404  *
00405  */
00406 void XBEAnalyser::log(const char *msg)
00407 {
00408         /*
00409          *      log() creates to much traffic so dont log
00410          *   perhaps we reactivate this later
00411          *
00412          */
00413 /*      LOG(msg);*/
00414 }
00415 
00416 /*
00417  *
00418  */
00419 Address *XBEAnalyser::nextValid(Address *Addr)
00420 {
00421         return (Address *)validarea->findNext(Addr);
00422 }
00423 
00424 /*
00425  *
00426  */
00427 void XBEAnalyser::store(ht_object_stream *st)
00428 {
00429         /*
00430         ht_pe_shared_data       *pe_shared;
00431         ht_stream               *file;
00432         area                            *validarea;
00433         */
00434         PUT_OBJECT(st, validarea);
00435         Analyser::store(st);
00436 }
00437 
00438 /*
00439  *
00440  */
00441 int     XBEAnalyser::queryConfig(int mode)
00442 {
00443         switch (mode) {
00444                 case Q_DO_ANALYSIS:
00445                 case Q_ENGAGE_CODE_ANALYSER:
00446                 case Q_ENGAGE_DATA_ANALYSER:
00447                         return true;
00448                 default:
00449                         return 0;
00450         }
00451 }
00452 
00453 /*
00454  *
00455  */
00456 Address *XBEAnalyser::fileofsToAddress(FILEOFS fileofs)
00457 {
00458         RVA r;
00459         if (xbe_ofs_to_rva(&xbe_shared->sections, fileofs, &r)) {
00460                 return createAddress32(r+xbe_shared->header.base_address);
00461         } else {
00462                 return new InvalidAddress();
00463         }
00464 }
00465 
00466 /*
00467  *
00468  */
00469 bool XBEAnalyser::validAddress(Address *Addr, tsectype action)
00470 {
00471         xbe_section_headers *sections=&xbe_shared->sections;
00472         int sec;
00473         RVA r;
00474         if (!convertAddressToRVA(Addr, &r)) return false;
00475         if (!xbe_rva_to_section(sections, r, &sec)) return false;
00476         XBE_SECTION_HEADER *s=sections->sections+sec;
00477         switch (action) {
00478                 case scvalid:
00479                         return true;
00480                 case scread:
00481                         return true;
00482                 case scwrite:
00483                         return s->section_flags & XBE_SECTION_FLAGS_WRITABLE;
00484                 case screadwrite:
00485                         return s->section_flags & XBE_SECTION_FLAGS_WRITABLE;
00486                 case sccode:
00487                         if (!xbe_rva_is_physical(sections, r)) return false;
00488                         return s->section_flags & XBE_SECTION_FLAGS_EXECUTABLE;
00489                 case scinitialized:
00490                         if (!xbe_rva_is_physical(sections, r)) return false;
00491                         return true;
00492         }
00493         return false;
00494 }

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