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