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 }