00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
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 
00092 
00093         Address *entry;
00094 
00095         entry = createAddress32(xbe_shared->header.entry_point);
00096         pushAddress(entry, entry);
00097         
00098         
00099 
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                 
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 
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                         
00155                         
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 
00215 
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 
00233 
00234         return false;
00235 }
00236 
00237 
00238 
00239 
00240 Address *XBEAnalyser::createAddress32(dword addr)
00241 {
00242         return new AddressX86Flat32(addr);
00243 
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 
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 
00276 
00277 
00278         if (validAddress(Addr, scinitialized)) {
00279 
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 
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 
00303         if (!convertAddressToRVA(Addr, &r)) return NULL;
00304         
00305 
00306         
00307         xbe_rva_to_section(sections, r, &i);
00308 
00309         b = xbe_rva_is_valid(sections, r);
00310 
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 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
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 
00410 
00411 
00412 
00413 
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 
00431 
00432 
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 }