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 "htanaly.h"            
00032 #include "le_analy.h"
00033 
00034 #include "htctrl.h"
00035 #include "htdebug.h"
00036 #include "htendian.h"
00037 #include "htiobox.h"
00038 #include "htle.h"
00039 #include "htstring.h"
00040 #include "nestruct.h"
00041 #include "snprintf.h"
00042 #include "x86asm.h"
00043 
00044 
00045 
00046 
00047 void    LEAnalyser::init(ht_le_shared_data *LE_shared, ht_streamfile *File)
00048 {
00049         le_shared = LE_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     LEAnalyser::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    LEAnalyser::done()
00082 {
00083         validarea->done();
00084         delete validarea;
00085         Analyser::done();
00086 }
00087 
00088 
00089 
00090 
00091 void LEAnalyser::beginAnalysis()
00092 {
00093 
00094 
00095         
00096 
00097 
00098 
00099         LEAddress a;
00100         Address *control = NULL;
00101         Address *v86control = NULL;
00102         Address *pmcontrol = NULL;
00103         if (le_shared->is_vxd) {
00104                 LEAddress addr;
00105                 int temp;
00106 
00107                 addr = le_shared->vxd_desc.v86_ctrl_ofs;
00108                 if (LE_addr_to_segment(le_shared, addr, &temp)) {
00109                         a = LE_MAKE_ADDR(le_shared, LE_ADDR_SEG(le_shared, addr),
00110                                 LE_ADDR_OFS(le_shared, addr));
00111                         v86control = createAddressFlat32(a);
00112                         le_shared->best_entrypoint = a;
00113                 }
00114 
00115                 addr = le_shared->vxd_desc.pm_ctrl_ofs;
00116                 if (LE_addr_to_segment(le_shared, addr, &temp)) {
00117                         a = LE_MAKE_ADDR(le_shared, LE_ADDR_SEG(le_shared, addr),
00118                                 LE_ADDR_OFS(le_shared, addr));
00119                         pmcontrol = createAddressFlat32(a);
00120                         le_shared->best_entrypoint = a;
00121                 }
00122                 
00123                 addr = le_shared->vxd_desc.ctrl_ofs;
00124                 if (LE_addr_to_segment(le_shared, addr, &temp)) {
00125                         a = LE_MAKE_ADDR(le_shared, LE_ADDR_SEG(le_shared, addr),
00126                                 LE_ADDR_OFS(le_shared, addr));
00127                         control = createAddressFlat32(a);
00128                         le_shared->best_entrypoint = a;
00129                 }
00130         }
00131 
00132         Address *entry = NULL;
00133         if (le_shared->hdr.startobj != 0) {
00134                 a = LE_MAKE_ADDR(le_shared, le_shared->hdr.startobj-1, le_shared->hdr.eip);
00135                 le_shared->best_entrypoint = a;
00136                 entry = createAddressFlat32(a);
00137         }
00138 
00139         if (v86control) pushAddress(v86control, v86control);
00140 
00141         if (pmcontrol) pushAddress(pmcontrol, pmcontrol);
00142 
00143         if (control) pushAddress(control, control);
00144 
00145         if (entry) pushAddress(entry, entry);
00146 
00147         
00148 
00149 
00150 
00151         LE_OBJECT *s = le_shared->objmap.header;
00152         char blub[100];
00153         for (UINT i = 0; i < le_shared->objmap.count; i++) {
00154                 LEAddress la = LE_get_seg_addr(le_shared, i);
00155                 Address *secaddr = createAddressFlat32(la);
00156 
00157 
00158                 UINT vsize = LE_get_seg_vsize(le_shared, i);
00159 
00160                 sprintf(blub, ";  section %d <%s> USE%d", i+1, getSegmentNameByAddress(secaddr), (le_shared->objmap.header[i].flags & LE_OBJECT_FLAG_USE32) ? 32 : 16);
00161                 addComment(secaddr, 0, "");
00162                 addComment(secaddr, 0, ";******************************************************************");
00163                 addComment(secaddr, 0, blub);
00164                 sprintf(blub, ";  virtual address  %08x  virtual size   %08x", LE_get_seg_addr(le_shared, i), vsize);
00165                 addComment(secaddr, 0, blub);
00166 
00167 
00168                 addComment(secaddr, 0, ";******************************************************************");
00169 
00170                 
00171                 sprintf(blub, ";  end of section <%s>", getSegmentNameByAddress(secaddr));
00172                 Address *secend_addr = (Address *)secaddr->duplicate();
00173                 secend_addr->add(vsize);
00174                 newLocation(secend_addr)->flags |= AF_FUNCTION_END;
00175                 addComment(secend_addr, 0, "");
00176                 addComment(secend_addr, 0, ";******************************************************************");
00177                 addComment(secend_addr, 0, blub);
00178                 addComment(secend_addr, 0, ";******************************************************************");
00179 
00180                 validarea->add(secaddr, secend_addr);
00181                 Address *seciniaddr = (Address *)secaddr->duplicate();
00182                 seciniaddr->add(vsize-1);
00183                 if (validAddress(secaddr, scinitialized) && validAddress(seciniaddr, scinitialized)) {
00184                         initialized->add(secaddr, seciniaddr);
00185                 }
00186                 delete secaddr;
00187                 delete secend_addr;
00188                 delete seciniaddr;
00189                 s++;
00190         }
00191 
00192         
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221         
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260         if (le_shared->is_vxd) {
00261                 if (v86control) {
00262                         addComment(v86control, 0, "");
00263                         addComment(v86control, 0, ";****************************");
00264                         addComment(v86control, 0, ";  VxD V86-control procedure");
00265                         addComment(v86control, 0, ";****************************");
00266                         assignSymbol(v86control, "VxD_v86_control", label_func);
00267                 }
00268                 if (pmcontrol) {
00269                         addComment(pmcontrol, 0, "");
00270                         addComment(pmcontrol, 0, ";****************************");
00271                         addComment(pmcontrol, 0, ";  VxD PM-control procedure");
00272                         addComment(pmcontrol, 0, ";****************************");
00273                         assignSymbol(pmcontrol, "VxD_pm_control", label_func);
00274                 }
00275                 if (control) {
00276                         addComment(control, 0, "");
00277                         addComment(control, 0, ";****************************");
00278                         addComment(control, 0, ";  VxD control procedure");
00279                         addComment(control, 0, ";****************************");
00280                         assignSymbol(control, "VxD_control", label_func);
00281                 }
00282         }
00283 
00284         if (entry) {
00285                 addComment(entry, 0, "");
00286                 addComment(entry, 0, ";****************************");
00287                 addComment(entry, 0, ";  program entry point");
00288                 addComment(entry, 0, ";****************************");
00289                 if (validCodeAddress(entry)) {
00290                         assignSymbol(entry, "entrypoint", label_func);
00291                 } else {
00292                         assignSymbol(entry, "entrypoint", label_data);
00293                 }
00294         }
00295 
00296         setLocationTreeOptimizeThreshold(1000);
00297         setSymbolTreeOptimizeThreshold(1000);
00298         delete entry;
00299 
00300         if (le_shared->best_entrypoint != LE_ADDR_INVALID) {
00301                 Address *tmpaddr = createAddressFlat32(le_shared->best_entrypoint);
00302                 ((ht_aviewer*)le_shared->v_image)->gotoAddress(tmpaddr, NULL);
00303                 delete tmpaddr;
00304         }
00305 
00306         Analyser::beginAnalysis();
00307 }
00308 
00309 
00310 
00311 
00312 OBJECT_ID       LEAnalyser::object_id() const
00313 {
00314         return ATOM_LE_ANALYSER;
00315 }
00316 
00317 
00318 
00319 
00320 FILEOFS LEAnalyser::addressToFileofs(Address *Addr)
00321 {
00322         if (validAddress(Addr, scinitialized)) {
00323                 FILEOFS ofs;
00324                 LEAddress na;
00325                 if (!convertAddressToLEAddress(Addr, &na)) return INVALID_FILE_OFS;
00326                 if (!LE_addr_to_ofs(le_shared, na, &ofs)) {
00327                         return INVALID_FILE_OFS;
00328                 }
00329                 return ofs;
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337         } else {
00338                 return INVALID_FILE_OFS;
00339         }
00340 }
00341 
00342 FILEOFS LEAnalyser::addressToRealFileofs(Address *Addr)
00343 {
00344         if (validAddress(Addr, scinitialized)) {
00345                 FILEOFS ofs;
00346                 LEAddress na;
00347                 if (!convertAddressToLEAddress(Addr, &na)) return INVALID_FILE_OFS;
00348                 if (!LE_addr_to_ofs(le_shared, na, &ofs)) {
00349                         return INVALID_FILE_OFS;
00350                 }
00351                 UINT m;
00352                 FILEOFS oo;
00353                 if (!le_shared->linear_file->map_ofs(ofs, &oo, &m)) {
00354                         return INVALID_FILE_OFS;
00355                 }
00356                 return oo;
00357         } else {
00358                 return INVALID_FILE_OFS;
00359         }
00360 }
00361 
00362 
00363 
00364 
00365 UINT LEAnalyser::bufPtr(Address *Addr, byte *buf, int size)
00366 {
00367         FILEOFS ofs = addressToFileofs(Addr);
00368 
00369 
00370 
00371 
00372         assert(ofs != INVALID_FILE_OFS);
00373         file->seek(ofs);
00374         return file->read(buf, size);
00375 }
00376 
00377 bool LEAnalyser::convertAddressToLEAddress(Address *addr, LEAddress *r)
00378 {
00379         if (addr->object_id()==ATOM_ADDRESS_X86_FLAT_32) {
00380 
00381                 *r = ((AddressX86Flat32*)addr)->addr;
00382                 return true;
00383         } else {
00384                 return false;
00385         }
00386 }
00387 
00388 Address *LEAnalyser::createAddress()
00389 {
00390         return new AddressX86Flat32(0);
00391 }
00392 
00393 Address *LEAnalyser::createAddressFlat32(uint32 ofs)
00394 {
00395         return new AddressX86Flat32(ofs);
00396 }
00397 
00398 
00399 
00400 
00401 Assembler *LEAnalyser::createAssembler()
00402 {
00403 
00404         Assembler *a = new x86asm(X86_OPSIZE32, X86_ADDRSIZE32);
00405         a->init();
00406         return a;
00407 }
00408 
00409 
00410 
00411 
00412 char *LEAnalyser::getSegmentNameByAddress(Address *Addr)
00413 {
00414         static char segmentname[16];
00415         int i;
00416         LEAddress na;
00417         if (!convertAddressToLEAddress(Addr, &na)) return NULL;
00418         if (!LE_addr_to_segment(le_shared, na, &i)) return NULL;
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426                 sprintf(segmentname, "seg%d", i+1);
00427 
00428         return segmentname;
00429 }
00430 
00431 
00432 
00433 
00434 const char *LEAnalyser::getName()
00435 {
00436         return file->get_desc();
00437 }
00438 
00439 
00440 
00441 
00442 const char *LEAnalyser::getType()
00443 {
00444         return "LE/Analyser";
00445 }
00446 
00447 
00448 
00449 
00450 void LEAnalyser::initCodeAnalyser()
00451 {
00452         Analyser::initCodeAnalyser();
00453 }
00454 
00455 
00456 
00457 
00458 void LEAnalyser::initUnasm()
00459 {
00460         DPRINTF("le_analy: ");
00461         DPRINTF("initing analy_x86_disassembler\n");
00462         analy_disasm = new AnalyX86Disassembler();
00463         ((AnalyX86Disassembler*)analy_disasm)->init(this, le_shared->is_vxd ? ANALYX86DISASSEMBLER_FLAGS_VXD_X86DIS : 0);
00464 }
00465 
00466 
00467 
00468 
00469 void LEAnalyser::log(const char *msg)
00470 {
00471         
00472 
00473 
00474 
00475 
00476 
00477 }
00478 
00479 
00480 
00481 
00482 Address *LEAnalyser::nextValid(Address *Addr)
00483 {
00484         return (Address *)validarea->findNext(Addr);
00485 }
00486 
00487 
00488 
00489 
00490 void LEAnalyser::store(ht_object_stream *st)
00491 {
00492         PUT_OBJECT(st, validarea);
00493         Analyser::store(st);
00494 }
00495 
00496 
00497 
00498 
00499 int     LEAnalyser::queryConfig(int mode)
00500 {
00501         switch (mode) {
00502                 case Q_DO_ANALYSIS:
00503                 case Q_ENGAGE_CODE_ANALYSER:
00504                 case Q_ENGAGE_DATA_ANALYSER:
00505                         return true;
00506                 default:
00507                         return 0;
00508         }
00509 }
00510 
00511 
00512 
00513 
00514 Address *LEAnalyser::fileofsToAddress(FILEOFS fileofs)
00515 {
00516         LEAddress a;
00517         if (LE_ofs_to_addr(le_shared, fileofs, &a)) {
00518                 return createAddressFlat32(a);
00519         } else {
00520                 return new InvalidAddress();
00521         }
00522 }
00523 
00524 
00525 
00526 
00527 
00528 
00529 Address *LEAnalyser::realFileofsToAddress(FILEOFS fileofs)
00530 {
00531         LEAddress a;
00532         UINT lofs;
00533         if (le_shared->linear_file->unmap_ofs(fileofs, &lofs) &&
00534         LE_ofs_to_addr(le_shared, lofs, &a)) {
00535                 return createAddressFlat32(a);
00536         } else {
00537                 return new InvalidAddress();
00538         }
00539 }
00540 
00541 
00542 
00543 
00544 bool LEAnalyser::validAddress(Address *Addr, tsectype action)
00545 {
00546         ht_le_objmap *objects = &le_shared->objmap;
00547         int sec;
00548         LEAddress na;
00549         if (!convertAddressToLEAddress(Addr, &na)) return false;
00550         if (!LE_addr_to_segment(le_shared, na, &sec)) return false;
00551         LEAddress temp;
00552         bool init = LE_addr_to_ofs(le_shared, na, &temp);
00553         LE_OBJECT *s = objects->header + sec;
00554 
00555         switch (action) {
00556                 case scvalid:
00557                         return true;
00558                 case scread:
00559                         return (s->flags & LE_OBJECT_FLAG_READABLE);
00560                 case scwrite:
00561                         return (s->flags & LE_OBJECT_FLAG_WRITEABLE);
00562                 case screadwrite:
00563                         return (s->flags & LE_OBJECT_FLAG_READABLE) && (s->flags & LE_OBJECT_FLAG_WRITEABLE);
00564                 case sccode:
00565                         return (s->flags & LE_OBJECT_FLAG_EXECUTABLE) && init;
00566                 case scinitialized:
00567                         return init;
00568         }
00569         return false;
00570 }
00571