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_names.h"
00028 #include "analy_register.h"
00029 #include "analy_x86.h"
00030 #include "global.h"
00031 #include "ne_analy.h"
00032 
00033 #include "htctrl.h"
00034 #include "htdebug.h"
00035 #include "htendian.h"
00036 #include "htiobox.h"
00037 #include "htne.h"
00038 #include "htneent.h"
00039 #include "htstring.h"
00040 #include "nestruct.h"
00041 #include "snprintf.h"
00042 #include "x86asm.h"
00043 
00044 
00045 
00046 
00047 void    NEAnalyser::init(ht_ne_shared_data *NE_shared, ht_streamfile *File)
00048 {
00049         ne_shared = NE_shared;
00050         file = File;
00051 
00052         validarea = new Area();
00053         validarea->init();
00054 
00055         Analyser::init();
00056 
00058 
00059         setLocationTreeOptimizeThreshold(100);
00060         setSymbolTreeOptimizeThreshold(100);
00061 }
00062 
00063 
00064 
00065 
00066 
00067 int     NEAnalyser::load(ht_object_stream *f)
00068 {
00069         
00070 
00071 
00072 
00073 
00074         GET_OBJECT(f, validarea);
00075         return Analyser::load(f);
00076 }
00077 
00078 
00079 
00080 
00081 void    NEAnalyser::done()
00082 {
00083         validarea->done();
00084         delete validarea;
00085         Analyser::done();
00086 }
00087 
00088 
00089 
00090 
00091 void NEAnalyser::beginAnalysis()
00092 {
00093         char    buffer[1024];
00094 
00095         
00096 
00097 
00098          
00099         Address *entry = createAddress1616(NE_ADDR_SEG(ne_shared->hdr.csip), NE_ADDR_OFS(ne_shared->hdr.csip));
00100         
00101         if (ne_shared->hdr.flags & NE_FLAGS_SELFLOAD) {
00102                 
00103                 struct bla {
00104                     NEAddress a;
00105                     char *b;
00106                     char *c;
00107                 };
00108                 bla blabla[] = {
00109                         { NE_MAKE_ADDR(0x0001, 0x0004), "loader_ptr_1", "loader_entry_1"},
00110                         { NE_MAKE_ADDR(0x0001, 0x0008), "loader_ptr_2", "loader_entry_2"},
00111                         { NE_MAKE_ADDR(0x0001, 0x0018), "loader_ptr_3", "loader_entry_3"},
00112                         { 0, 0, 0 },
00113                 };
00114                 bla *blla = blabla;
00115                 while (blla->b) {
00116                         Address *bllaa = createAddress1616(NE_ADDR_SEG(blla->a), NE_ADDR_OFS(blla->a));
00117                         addComment(bllaa, 0, "");
00118                         assignSymbol(bllaa, blla->b, label_data);
00119                         data->setIntAddressType(bllaa, dst_idword, 4);
00120                         NEAddress addr;
00121                         byte buf[4];
00122                         if (validAddress(bllaa, scinitialized) && bufPtr(bllaa, buf, 4)==4) {
00123                                 sprintf(buffer, "; pointer to %s", blla->c);
00124                                 addComment(bllaa, 0, buffer);
00125                                 addr = create_host_int(buf, 4, little_endian);
00126                                 Address *a = createAddress1616(NE_ADDR_SEG(addr), NE_ADDR_OFS(addr));
00127                                 addComment(a, 0, "");
00128                                 assignSymbol(a, blla->c, label_func);
00129                                 pushAddress(a, a);
00130                                 delete a;
00131                         }
00132                         blla++;
00133                         delete bllaa;
00134                 }
00135         } else {
00136                 pushAddress(entry, entry);
00137         }
00138         
00139         
00140 
00141 
00142 
00143         NE_SEGMENT *s = ne_shared->segments.segments;
00144         char blub[100];
00145         for (UINT i = 0; i < ne_shared->segments.segment_count; i++) {
00146                 Address *secaddr = createAddress1616(NE_ADDR_SEG(NE_get_seg_addr(ne_shared, i)), NE_ADDR_OFS(NE_get_seg_addr(ne_shared, i)));
00147 
00148                 UINT epsize = MIN(NE_get_seg_vsize(ne_shared, i), NE_get_seg_psize(ne_shared, i));
00149                 UINT evsize = MAX(NE_get_seg_vsize(ne_shared, i), NE_get_seg_psize(ne_shared, i));
00150 
00151                 sprintf(blub, ";  section %d <%s>", i+1, getSegmentNameByAddress(secaddr));
00152                 addComment(secaddr, 0, "");
00153                 addComment(secaddr, 0, ";******************************************************************");
00154                 addComment(secaddr, 0, blub);
00155                 sprintf(blub, ";  virtual address  %08x  virtual size   %08x", NE_get_seg_addr(ne_shared, i), evsize);
00156                 addComment(secaddr, 0, blub);
00157                 sprintf(blub, ";  file offset      %08x  file size      %08x", NE_get_seg_ofs(ne_shared, i), epsize);
00158                 addComment(secaddr, 0, blub);
00159                 addComment(secaddr, 0, ";******************************************************************");
00160 
00161                 
00162                 sprintf(blub, ";  end of section <%s>", getSegmentNameByAddress(secaddr));
00163                 Address *secend_addr = (Address *)secaddr->duplicate();
00164                 secend_addr->add(evsize);
00165                 newLocation(secend_addr)->flags |= AF_FUNCTION_END;
00166                 addComment(secend_addr, 0, "");
00167                 addComment(secend_addr, 0, ";******************************************************************");
00168                 addComment(secend_addr, 0, blub);
00169                 addComment(secend_addr, 0, ";******************************************************************");
00170 
00171                 validarea->add(secaddr, secend_addr);
00172                 Address *seciniaddr = (Address *)secaddr->duplicate();
00173                 seciniaddr->add(epsize);
00174                 if (validAddress(secaddr, scinitialized) && validAddress(seciniaddr, scinitialized)) {
00175                         initialized->add(secaddr, seciniaddr);
00176                 }
00177                 delete secaddr;
00178                 delete secend_addr;
00179                 delete seciniaddr;
00180                 s++;
00181         }
00182 
00183         
00184 
00185         int entrypoint_count = ne_shared->entrypoints->count();
00186         int *entropy = random_permutation(entrypoint_count);
00187         for (int i=0; i<entrypoint_count; i++) {
00188                 ht_ne_entrypoint *f = (ht_ne_entrypoint*)ne_shared->entrypoints->get(*(entropy+i));
00189                 if (f) {
00190                         Address *address = createAddress1616(f->seg, f->offset);
00191                         if (validAddress(address, scvalid)) {
00192                                 char *label;
00193                                 if (f->name) {
00194                                         sprintf(buffer, "; exported function %s, ordinal %04x", f->name, f->ordinal);
00195                                 } else {
00196                                         sprintf(buffer, "; unnamed exported function, ordinal %04x", f->ordinal);
00197                                 }
00198                                 label = export_func_name(f->name, f->ordinal);
00199                                 addComment(address, 0, "");
00200                                 addComment(address, 0, ";********************************************************");
00201                                 addComment(address, 0, buffer);
00202                                 addComment(address, 0, ";********************************************************");
00203                                 pushAddress(address, address);
00204                                 assignSymbol(address, label, label_func);
00205                                 free(label);
00206                         }
00207                         delete address;
00208                 }
00209         }
00210         if (entropy) free(entropy);
00211 
00212         
00213 
00214         if (ne_shared->imports) {
00215                 ht_tree *t = ne_shared->imports;
00216                 Object *v;
00217                 ne_import_rec *imp = NULL;
00218                 FILEOFS h = ne_shared->hdr_ofs + ne_shared->hdr.imptab;
00219                 while ((imp = (ne_import_rec*)t->enum_next(&v, imp))) {
00220                         char *name = NULL;
00221                         char *mod = (imp->module-1 < ne_shared->modnames_count) ? ne_shared->modnames[imp->module-1] : (char*)"invalid!";
00222                         if (imp->byname) {
00223                                 file->seek(h+imp->name_ofs);
00224                                 name = getstrp(file);
00225                         }
00226                         char *label = import_func_name(mod, name, imp->byname ? 0 : imp->ord);
00227                         if (name) free(name);
00228                         Address *addr = createAddress1616(ne_shared->fake_segment+1, imp->addr);
00229                         addComment(addr, 0, "");
00230                         assignSymbol(addr, label, label_func);
00231                         data->setIntAddressType(addr, dst_ibyte, 1);
00232                         free(label);
00233                         delete addr;
00234                 }
00235         }
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250         addComment(entry, 0, "");
00251         addComment(entry, 0, ";****************************");
00252         if (ne_shared->hdr.flags & NE_FLAGS_NOTAPROCESS) {
00253                 addComment(entry, 0, ";  library entry point");
00254         } else {
00255                 addComment(entry, 0, ";  program entry point");
00256         }
00257         addComment(entry, 0, ";****************************");
00258         if (validCodeAddress(entry)) {
00259                 assignSymbol(entry, "entrypoint", label_func);
00260         } else {
00261                 assignSymbol(entry, "entrypoint", label_data);
00262         }
00263 
00264         setLocationTreeOptimizeThreshold(1000);
00265         setSymbolTreeOptimizeThreshold(1000);
00266         delete entry;
00267         
00268         Analyser::beginAnalysis();
00269 }
00270 
00271 
00272 
00273 
00274 OBJECT_ID       NEAnalyser::object_id() const
00275 {
00276         return ATOM_NE_ANALYSER;
00277 }
00278 
00279 
00280 
00281 
00282 UINT NEAnalyser::bufPtr(Address *Addr, byte *buf, int size)
00283 {
00284         FILEOFS ofs = addressToFileofs(Addr);
00285 
00286 
00287 
00288         assert(ofs != INVALID_FILE_OFS);
00289         file->seek(ofs);
00290         return file->read(buf, size);
00291 }
00292 
00293 bool NEAnalyser::convertAddressToNEAddress(Address *addr, NEAddress *r)
00294 {
00295         if (addr->object_id()==ATOM_ADDRESS_X86_1616) {
00296                 *r = NE_MAKE_ADDR(((AddressX86_1616*)addr)->seg, ((AddressX86_1616*)addr)->addr);
00297                 return true;
00298         } else {
00299                 return false;
00300         }
00301 }
00302 
00303 Address *NEAnalyser::createAddress()
00304 {
00305         return new AddressX86_1616(0, 0);
00306 }
00307 
00308 Address *NEAnalyser::createAddress1616(word seg, word ofs)
00309 {
00310         return new AddressX86_1616(seg, ofs);
00311 }
00312 
00313 
00314 
00315 
00316 Assembler *NEAnalyser::createAssembler()
00317 {
00318 
00319         Assembler *a = new x86asm(X86_OPSIZE16, X86_ADDRSIZE16);
00320         a->init();
00321         return a;
00322 }
00323 
00324 
00325 
00326 
00327 FILEOFS NEAnalyser::addressToFileofs(Address *Addr)
00328 {
00329         if (validAddress(Addr, scinitialized)) {
00330                 FILEOFS ofs;
00331                 NEAddress na;
00332                 if (!convertAddressToNEAddress(Addr, &na)) return INVALID_FILE_OFS;
00333                 if (!NE_addr_to_ofs(ne_shared, na, &ofs)) {
00334                         return INVALID_FILE_OFS;
00335                 }
00336                 return ofs;
00337         } else {
00338                 return INVALID_FILE_OFS;
00339         }
00340 }
00341 
00342 
00343 
00344 
00345 char *NEAnalyser::getSegmentNameByAddress(Address *Addr)
00346 {
00347         static char segmentname[16];
00348         int i;
00349         NEAddress na;
00350         if (!convertAddressToNEAddress(Addr, &na)) return NULL;
00351         if (!NE_addr_to_segment(ne_shared, na, &i)) return NULL;
00352         if (i == (int)ne_shared->fake_segment) {
00353                 strcpy(segmentname, "faked names");
00354         } else {
00355                 sprintf(segmentname, "seg%d", i+1);
00356         }
00357         return segmentname;
00358 }
00359 
00360 
00361 
00362 
00363 const char *NEAnalyser::getName()
00364 {
00365         return file->get_desc();
00366 }
00367 
00368 
00369 
00370 
00371 const char *NEAnalyser::getType()
00372 {
00373         return "NE/Analyser";
00374 }
00375 
00376 
00377 
00378 
00379 void NEAnalyser::initCodeAnalyser()
00380 {
00381         Analyser::initCodeAnalyser();
00382 }
00383 
00384 
00385 
00386 
00387 void NEAnalyser::initUnasm()
00388 {
00389         DPRINTF("ne_analy: ");
00390         DPRINTF("initing analy_x86_disassembler\n");
00391         analy_disasm = new AnalyX86Disassembler();
00392         ((AnalyX86Disassembler*)analy_disasm)->init(this, ANALYX86DISASSEMBLER_FLAGS_16BIT | ANALYX86DISASSEMBLER_FLAGS_SEGMENTED);
00393 }
00394 
00395 
00396 
00397 
00398 void NEAnalyser::log(const char *msg)
00399 {
00400         
00401 
00402 
00403 
00404 
00405 
00406 }
00407 
00408 
00409 
00410 
00411 Address *NEAnalyser::nextValid(Address *Addr)
00412 {
00413         return (Address *)validarea->findNext(Addr);
00414 }
00415 
00416 
00417 
00418 
00419 void NEAnalyser::store(ht_object_stream *st)
00420 {
00421         PUT_OBJECT(st, validarea);
00422         Analyser::store(st);
00423 }
00424 
00425 
00426 
00427 
00428 int     NEAnalyser::queryConfig(int mode)
00429 {
00430         switch (mode) {
00431                 case Q_DO_ANALYSIS:
00432                 case Q_ENGAGE_CODE_ANALYSER:
00433                 case Q_ENGAGE_DATA_ANALYSER:
00434                         return true;
00435                 default:
00436                         return 0;
00437         }
00438 }
00439 
00440 
00441 
00442 
00443 Address *NEAnalyser::fileofsToAddress(FILEOFS fileofs)
00444 {
00445         NEAddress a;
00446         if (NE_ofs_to_addr(ne_shared, fileofs, &a)) {
00447                 return createAddress1616(NE_ADDR_SEG(a), NE_ADDR_OFS(a));
00448         } else {
00449                 return new InvalidAddress();
00450         }
00451 }
00452 
00453 
00454 
00455 
00456 bool NEAnalyser::validAddress(Address *Addr, tsectype action)
00457 {
00458         ne_segment_headers *segments = &ne_shared->segments;
00459         int sec;
00460         NEAddress na;
00461         if (!convertAddressToNEAddress(Addr, &na)) return false;
00462         if (!NE_addr_to_segment(ne_shared, na, &sec)) return false;
00463         NE_SEGMENT *s = segments->segments + sec;
00464         switch (action) {
00465                 case scvalid:
00466                         return true;
00467                 case scread:
00468                         return !(s->flags & NE_READONLY) || (s->flags & NE_DATA);
00469                 case scwrite:
00470                         return !(s->flags & NE_READONLY) && (s->flags & NE_DATA);
00471                 case screadwrite:
00472                         return !(s->flags & NE_READONLY) && (s->flags & NE_DATA);
00473                 case sccode:
00474                         return (!(s->flags & NE_DATA)) && NE_addr_is_physical(ne_shared, na);
00475                 case scinitialized:
00476                         return NE_addr_is_physical(ne_shared, na);
00477         }
00478         return false;
00479 }
00480