00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define WIN32_LEAN_AND_MEAN
00032
00033 #include <windows.h>
00034 #include <cvconst.h>
00035 #include <oleauto.h>
00036 #if !defined __out_ecount_opt
00037 #define __out_ecount_opt(x)
00038 #endif
00039 #include <dbghelp.h>
00040
00041 #include <iostream>
00042 #include <iomanip>
00043 #include <limits.h>
00044 #include <crtdbg.h>
00045 #include <winnt.h>
00046
00047 #include "symtabAPI/src/Object.h"
00048 #include "symtabAPI/src/Object-nt.h"
00049
00050 #include "LineInformation.h"
00051 #include "Collections.h"
00052 #include "Symtab.h"
00053 #include "Module.h"
00054 #include "Function.h"
00055 #include "Variable.h"
00056 #include "emitWin.h"
00057
00058 #include "common/h/headers.h"
00059
00060 using namespace Dyninst;
00061 using namespace Dyninst::SymtabAPI;
00062
00063 Type *getType(HANDLE p, Offset mod_base, int typeIndex, Module *mod = NULL);
00064 bool pd_debug_export_symbols = false;
00065 using namespace std;
00066
00067 std::string convertCharToString(const char *ptr){
00068 std::string str;
00069 if(ptr)
00070 str = ptr;
00071 else
00072 str = "";
00073 return str;
00074 }
00075
00076 static void printSysError(unsigned errNo) {
00077 char buf[1000];
00078
00079 int result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errNo,
00080 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00081 buf, 1000, NULL);
00082 if (!result) {
00083 fprintf(stderr, "Couldn't print error message\n");
00084 printSysError(GetLastError());
00085 }
00086 fprintf(stderr, "*** System error [%d]: %s\n", errNo, buf);
00087 fflush(stderr);
00088 }
00089
00090
00091
00092
00093 BOOL CALLBACK SymEnumSymbolsCallback( PSYMBOL_INFO pSymInfo,
00094 ULONG symSize,
00095 PVOID userContext );
00096
00097
00098
00099
00100
00101
00102
00103
00104 static void stripAtSuffix(char *str)
00105 {
00106
00107
00108
00109
00110 char *p = strrchr(str, '@');
00111 if (p) {
00112 char *q = p+1;
00113 strtoul(p+1, &q, 10);
00114 if (q > p+1 && *q == '\0') {
00115 *p = '\0';
00116 }
00117 }
00118 }
00119
00120 char *cplus_demangle(char *c, int, bool includeTypes) {
00121
00122 char buf[1000];
00123 if (c[0]=='_') {
00124
00125
00126
00127
00128
00129 unsigned i;
00130 for (i=1; i<sizeof(buf) && c[i]!='$' && c[i]!='\0'; i++)
00131 buf[i-1]=c[i];
00132 buf[i-1]='\0';
00133 stripAtSuffix(buf);
00134 if (buf[0] == '\0')
00135 return 0;
00136 return P_strdup(buf);
00137 }
00138 else {
00139 if (includeTypes) {
00140 if (UnDecorateSymbolName(c, buf, 1000, UNDNAME_COMPLETE| UNDNAME_NO_ACCESS_SPECIFIERS|UNDNAME_NO_MEMBER_TYPE|UNDNAME_NO_MS_KEYWORDS)) {
00141
00142 stripAtSuffix(buf);
00143 return P_strdup(buf);
00144 }
00145 }
00146 else if (UnDecorateSymbolName(c, buf, 1000, UNDNAME_NAME_ONLY)) {
00147
00148
00149 stripAtSuffix(buf);
00150 return P_strdup(buf);
00151 }
00152 }
00153 return 0;
00154 }
00155
00156
00157
00158
00159 struct CompareSymAddresses: public binary_function<const Object::intSymbol*, const Object::intSymbol*, bool>
00160 {
00161 bool operator()(const Object::intSymbol *s1, const Object::intSymbol* s2) {
00162 bool ret = false;
00163
00164 if( s1->GetAddr() < s2->GetAddr() )
00165 {
00166 ret = true;
00167 }
00168 else if( s1->GetAddr() > s2->GetAddr() )
00169 {
00170 ret = false;
00171 }
00172 else
00173 {
00174
00175
00176
00177
00178
00179 if( (s1->GetSize() != 0) && (s2->GetSize() == 0) )
00180 {
00181 ret = true;
00182 }
00183 else if( (s1->GetSize() == 0) && (s2->GetSize() != 0) )
00184 {
00185 ret = false;
00186 }
00187 }
00188 return ret;
00189 }
00190 };
00191
00192 Object::Module::Module( std::string _name, DWORD64 _baseAddr, DWORD64 _extent ) :
00193 name(_name),
00194 baseAddr(_baseAddr),
00195 extent(_extent),
00196 isDll( false )
00197 {
00198 defFile = new Object::File();
00199 files.push_back( defFile );
00200 }
00201
00202 Object::File*
00203 Object::Module::FindFile( std::string name )
00204 {
00205 File* ret = NULL;
00206 for( std::vector<File *>::iterator iter = files.begin();
00207 iter != files.end();
00208 iter++ )
00209 {
00210 if( (*iter)->GetName() == name )
00211 {
00212 ret = *iter;
00213 break;
00214 }
00215 }
00216 return ret;
00217 }
00218
00219 void
00220 Object::File::DefineSymbols( dyn_hash_map<std::string, std::vector< Symbol *> >& allSyms,
00221 map<Symbol *, std::string> &symsToMods,
00222 const std::string& modName ) const
00223 {
00224 for( std::vector<Object::intSymbol*>::const_iterator iter = syms.begin(); iter != syms.end(); iter++ ) {
00225 const Object::intSymbol* curSym = * iter;
00226 assert( curSym != NULL );
00227 curSym->DefineSymbol( allSyms, symsToMods, modName );
00228 }
00229 }
00230
00231 void
00232 Object::intSymbol::DefineSymbol(dyn_hash_map<std::string,std::vector<Symbol *> >&allSyms,
00233 map<Symbol *, std::string> &symsToMods,
00234 const std::string& modName ) const
00235 {
00236 Symbol *sym = new Symbol(GetName(),
00237 (Symbol::SymbolType) GetType(),
00238 (Symbol::SymbolLinkage) GetLinkage(),
00239 Symbol::SV_UNKNOWN,
00240 (Offset)GetAddr(),
00241 NULL,
00242 GetRegion(),
00243 GetSize());
00244 allSyms[GetName()].push_back(sym);
00245 symsToMods[sym] = modName;
00246 }
00247
00248 void
00249 Object::Module::DefineSymbols( const Object* obj,
00250 dyn_hash_map<std::string, std::vector< Symbol *> > & syms,
00251 map<Symbol *, std::string> &symsToMods ) const
00252 {
00253
00254 if( !isDll )
00255 {
00256
00257 for( std::vector<Object::File*>::const_iterator iter = files.begin();
00258 iter != files.end();
00259 iter++ ) {
00260 const File* curFile = *iter;
00261 assert( curFile != NULL );
00262
00263
00264
00265 Symbol *sym = new Symbol( curFile->GetName(),
00266 Symbol::ST_MODULE,
00267 Symbol::SL_GLOBAL,
00268 Symbol::SV_UNKNOWN,
00269 obj->code_off(),
00270 NULL,
00271 NULL, 0 );
00272
00273
00274 syms[curFile->GetName()].push_back(sym);
00275 symsToMods[sym] = curFile->GetName();
00276
00277 curFile->DefineSymbols( syms, symsToMods, curFile->GetName() );
00278 }
00279 }
00280 else
00281 {
00282
00283
00284
00285 Symbol *sym = new Symbol(name,
00286 Symbol::ST_MODULE,
00287 Symbol::SL_GLOBAL,
00288 Symbol::SV_UNKNOWN,
00289 obj->code_off(),
00290 NULL,
00291 NULL,
00292 obj->code_len());
00293
00294 syms[name].push_back(sym);
00295 symsToMods[sym] = name;
00296
00297
00298 for( std::vector<Object::File*>::const_iterator iter = files.begin();
00299 iter != files.end();
00300 iter++ )
00301 {
00302 const File* curFile = *iter;
00303 assert( curFile != NULL );
00304
00305 curFile->DefineSymbols( syms, symsToMods, name );
00306 }
00307 }
00308 }
00309
00310 void
00311 Object::Module::PatchSymbolSizes( const Object* obj,
00312 const std::vector<Object::intSymbol*>& allSyms ) const
00313 {
00314 DWORD64 lastFuncAddr = NULL;
00315 unsigned int i;
00316
00317 for( i = 0; i < allSyms.size(); i++ )
00318 {
00319 Object::intSymbol* sym = allSyms[i];
00320 assert( sym != NULL );
00321 if( (sym->GetName() != "") && (sym->GetSize() == 0) &&
00322 ((sym->GetType() == Symbol::ST_FUNCTION) ||
00323 (sym->GetType() == Symbol::ST_OBJECT)))
00324 {
00325
00326
00327
00328
00329 bool isAlias = false;
00330 if( (sym->GetType() == Symbol::ST_FUNCTION) &&
00331 (sym->GetAddr() == lastFuncAddr) &&
00332 (sym->GetSize() == 0) )
00333 {
00334
00335
00336
00337
00338
00339 isAlias = true;
00340 }
00341 if( !isAlias )
00342 {
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 DWORD64 cb;
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 unsigned int j = i + 1;
00367 while((j < allSyms.size()) &&
00368 (((allSyms[j]->GetType() != Symbol::ST_FUNCTION) &&
00369 (allSyms[j]->GetType() != Symbol::ST_OBJECT)) ||
00370 (allSyms[j]->GetAddr() == sym->GetAddr())))
00371 {
00372 j++;
00373 }
00374 if( j < allSyms.size() &&
00375 (allSyms[j]->GetType() == sym->GetType()) )
00376 {
00377
00378
00379
00380 cb = allSyms[j]->GetAddr() - sym->GetAddr();
00381 }
00382 else
00383 {
00384
00385
00386
00387 if( sym->GetType() == Symbol::ST_FUNCTION )
00388 {
00389
00390 cb = (obj->code_off() + obj->code_len()) -
00391 sym->GetAddr();
00392 }
00393 else
00394 {
00395
00396 cb = (obj->data_off() + obj->data_len()) -
00397 sym->GetAddr();
00398 }
00399 }
00400 sym->SetSize( (unsigned int) cb );
00401 }
00402
00403 if( sym->GetType() == Symbol::ST_FUNCTION )
00404 {
00405 lastFuncAddr = sym->GetAddr();
00406 }
00407 }
00408 }
00409 }
00410
00411 void
00412 Object::Module::BuildSymbolMap( const Object* obj ) const
00413 {
00414 std::vector<Object::intSymbol*> allSyms;
00415
00416 std::vector<Object::File*>::const_iterator iter = files.begin();
00417 for(; iter != files.end(); iter++ )
00418 {
00419 assert( *iter != NULL );
00420 const std::vector<Object::intSymbol*>& curSyms = (*iter)->GetSymbols();
00421 for( std::vector<Object::intSymbol*>::const_iterator symIter = curSyms.begin(); symIter != curSyms.end();symIter++ )
00422 {
00423 assert( *symIter != NULL );
00424 allSyms.push_back( *symIter );
00425 }
00426 }
00427
00428 sort( allSyms.begin(), allSyms.end(), CompareSymAddresses());
00429 for( unsigned int i = 1; i < allSyms.size(); i++ )
00430 {
00431 if( allSyms[i-1]->GetAddr() > allSyms[i]->GetAddr() )
00432 {
00433 cout << "WARNING - sort failed" << endl;
00434 assert( false );
00435 }
00436 }
00437
00438 PatchSymbolSizes( obj, allSyms );
00439 }
00440
00441 Object::~Object( void )
00442 {
00443 }
00444
00445 #define SymTagFunction 0x5
00446 #define SymTagData 0x7
00447 #define SymTagPublicSymbol 0xa
00448 #define SymTagMisc 0x3808 // Seen with NB11, VC++6-produced executables
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 static BOOL isGlobalSymbol(PSYMBOL_INFO pSymInfo) {
00460 return ((pSymInfo->Flags & SYMFLAG_EXPORT) ||
00461 (pSymInfo->Flags & SYMFLAG_FUNCTION) ||
00462 ((!pSymInfo->Flags) &&
00463 ((pSymInfo->Tag == SymTagFunction) ||
00464 (pSymInfo->Tag == SymTagData) ||
00465 (pSymInfo->Tag == SymTagPublicSymbol) ||
00466 (pSymInfo->Tag == SymTagMisc))) );
00467 }
00468
00469 void Object::ParseGlobalSymbol(PSYMBOL_INFO pSymInfo)
00470 {
00471 Object::Module* curMod = GetCurrentModule();
00472 assert( curMod != NULL );
00473
00474 IMAGEHLP_LINE64 lineInfo;
00475 DWORD dwDisplacement = 0;
00476 ZeroMemory( &lineInfo, sizeof(lineInfo) );
00477 lineInfo.SizeOfStruct = sizeof(lineInfo);
00478 Object::File* pFile = NULL;
00479 if( SymGetLineFromAddr64( hProc,
00480 pSymInfo->Address,
00481 &dwDisplacement,
00482 &lineInfo ) ) {
00483
00484 pFile = curMod->FindFile( lineInfo.FileName );
00485 if( pFile == NULL ) {
00486 pFile = new Object::File( lineInfo.FileName );
00487 curMod->AddFile( pFile );
00488 }
00489 }
00490 else {
00491 pFile = curMod->GetDefaultFile();
00492 }
00493 assert( pFile != NULL );
00494
00495
00496
00497 DWORD symType = Symbol::ST_UNKNOWN;
00498 DWORD symLinkage = Symbol::SL_UNKNOWN;
00499 DWORD64 codeLen = code_len();
00500 DWORD64 codeBase = code_off();
00501 symType = Symbol::ST_FUNCTION;
00502
00503 if ((pSymInfo->Flags & SYMFLAG_FUNCTION) ||
00504 (pSymInfo->Tag == SymTagFunction && !pSymInfo->Flags))
00505 {
00506 symLinkage = Symbol::SL_UNKNOWN;
00507 }
00508 else if ((pSymInfo->Flags == SYMFLAG_EXPORT &&
00509 isText((Offset) pSymInfo->Address - (Offset)mf->base_addr())) ||
00510 (pSymInfo->Name && (!strcmp(pSymInfo->Name, "loadsnstores") ||
00511 !strcmp(pSymInfo->Name, "_loadsnstores"))
00512 ))
00513 {
00514 symType = Symbol::ST_FUNCTION;
00515 symLinkage = Symbol::SL_UNKNOWN;
00516 }
00517 else
00518 {
00519 symType = Symbol::ST_OBJECT;
00520 symLinkage = Symbol::SL_GLOBAL;
00521 }
00522
00523 Offset baseAddr = 0;
00524
00525
00526
00527 if( !isForwarded( ((Offset) pSymInfo->Address) - baseAddr ) )
00528 {
00529 pFile->AddSymbol( new Object::intSymbol
00530 ( pSymInfo->Name,
00531 pSymInfo->Address - get_base_addr(),
00532 symType,
00533 symLinkage,
00534 pSymInfo->Size,
00535 findEnclosingRegion((Offset)(pSymInfo->Address - get_base_addr())) ));
00536 }
00537 }
00538
00539 BOOL CALLBACK SymEnumSymbolsCallback( PSYMBOL_INFO pSymInfo,
00540 ULONG symSize,
00541 PVOID userContext )
00542 {
00543 assert( pSymInfo != NULL );
00544 Object* obj = (Object*) userContext;
00545 assert( obj != NULL );
00546
00547 #if 0
00548 fprintf(stderr, "symEnumSymsCallback, %s, Flags:0x%x, Tag:0x%x, Type:%d, Addr:0x%x...\n",
00549 pSymInfo->Name,
00550 pSymInfo->Flags,
00551 pSymInfo->Tag,
00552 pSymInfo->TypeIndex,
00553 pSymInfo->Address);
00554 #endif
00555
00556 if (isGlobalSymbol(pSymInfo))
00557 {
00558 obj->ParseGlobalSymbol(pSymInfo);
00559 }
00560 else if ((pSymInfo->Flags & SYMFLAG_LOCAL) ||
00561 (pSymInfo->Flags & SYMFLAG_PARAMETER)) {
00562
00563
00564 }
00565 else {
00566
00567 }
00568
00569 return TRUE;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 void Object::ParseSymbolInfo( bool alloc_syms )
00579 {
00580
00581
00582
00583
00584
00585 string file_ = mf->filename();
00586 static unsigned count = 1;
00587 hProc = (HANDLE) count++;
00588 if(!SymInitialize(hProc, NULL, false)){
00589 DWORD dwErr = GetLastError();
00590 if(dwErr) {
00591 fprintf( stderr, "SymInitialize failed for %s\n",
00592 ((file_.length() > 0) ? file_.c_str()
00593 : "<no name available>"));
00594 goto done;
00595 }
00596 }
00597 assert( hProc != NULL );
00598 assert( hProc != INVALID_HANDLE_VALUE );
00599
00600
00601 if (peHdr) imageBase = peHdr->OptionalHeader.ImageBase;
00602 else imageBase = 0;
00603
00604
00605
00606 HANDLE mapAddr = mf->base_addr();
00607 DWORD64 dw64BaseAddr = (DWORD64)mapAddr;
00608
00609 HANDLE hFile = mf->getFileHandle();
00610 DWORD64 loadRet = SymLoadModule64( hProc,
00611 hFile,
00612 NULL,
00613 NULL,
00614 dw64BaseAddr,
00615 0 );
00616 if(!loadRet) {
00617 DWORD dwErr = GetLastError();
00618 if(dwErr) {
00619 string file_ = mf->filename();
00620 fprintf( stderr, "SymLoadModule64 failed for %s\n",
00621 ((file_.length() > 0) ? file_.c_str()
00622 : "<no name available>"));
00623
00624 goto done;
00625 }
00626 }
00627
00628 if( !SymEnumSymbols(hProc,
00629 dw64BaseAddr,
00630 "",
00631 SymEnumSymbolsCallback,
00632 this ) )
00633 {
00634 int lasterr = GetLastError();
00635 fprintf( stderr, "Failed to enumerate symbols\n");
00636
00637 }
00638
00639
00640
00641
00642 assert( curModule != NULL );
00643 curModule->BuildSymbolMap( this );
00644 if (alloc_syms)
00645 curModule->DefineSymbols( this, symbols_, symsToModules_ );
00646 no_of_symbols_ = symbols_.size();
00647
00648
00649
00650
00651
00652 code_vldS_ = code_off_;
00653 code_vldE_ = code_off_ + code_len_;
00654 data_vldS_ = data_off_;
00655 data_vldE_ = data_off_ + data_len_;
00656
00657 done:
00658 delete curModule;
00659 }
00660
00661
00662
00663
00664
00665 void Object::AddTLSFunctions()
00666 {
00667
00668 if (!peHdr || peHdr->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_TLS) {
00669 return;
00670 }
00671
00672
00673 unsigned long tlsSize = peHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
00674 if (!tlsSize) {
00675 return;
00676 }
00677 Address imgBase = peHdr->OptionalHeader.ImageBase;
00678 Offset tlsMemOff = peHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
00679 Region *secn = findEnclosingRegion(tlsMemOff);
00680 if (!secn || (tlsMemOff - secn->getMemOffset()) > secn->getDiskSize()) {
00681 return;
00682 }
00683 Offset tlsDiskOff = tlsMemOff
00684 + (Offset)secn->getDiskOffset()
00685 - (Offset)secn->getMemOffset();
00686 IMAGE_TLS_DIRECTORY *tlsDir = (IMAGE_TLS_DIRECTORY*)
00687 ( tlsDiskOff + (Offset)mf->base_addr() );
00688
00689
00690 secn = findEnclosingRegion(tlsDir->AddressOfCallBacks - imgBase);
00691 Offset cbOffSec = tlsDir->AddressOfCallBacks
00692 - secn->getMemOffset()
00693 - imgBase;
00694 if (!secn || cbOffSec > secn->getDiskSize()) {
00695 return;
00696 }
00697 Offset cbOffDisk = cbOffSec + secn->getDiskOffset();
00698 PIMAGE_TLS_CALLBACK *tlsCBs = (PIMAGE_TLS_CALLBACK*)
00699 ( cbOffDisk + (Offset)mf->base_addr() );
00700 unsigned maxCBs = (secn->getDiskSize() - cbOffSec) / sizeof(PIMAGE_TLS_CALLBACK);
00701
00702
00703 for (unsigned tidx=0; tidx < maxCBs && tlsCBs[tidx] != NULL ; tidx++) {
00704 Offset funcOff = ((Address) tlsCBs[tidx]) - imgBase;
00705 secn = findEnclosingRegion(funcOff);
00706 if (!secn) {
00707 continue;
00708 }
00709 Offset baseAddr = 0;
00710 Object::File *pFile = curModule->GetDefaultFile();
00711 char funcName [128];
00712 snprintf(funcName, 128, "tls_cb_%d", tidx);
00713 pFile->AddSymbol( new Object::intSymbol
00714 ( funcName,
00715 funcOff,
00716 Symbol::ST_FUNCTION,
00717 Symbol::SL_GLOBAL,
00718 0,
00719 secn ));
00720 }
00721 }
00722
00723 Region::perm_t getRegionPerms(DWORD flags){
00724 if((flags & IMAGE_SCN_MEM_EXECUTE) && (flags & IMAGE_SCN_MEM_WRITE))
00725 return Region::RP_RWX;
00726 else if(flags & IMAGE_SCN_MEM_EXECUTE)
00727 return Region::RP_RX;
00728 else if(flags & IMAGE_SCN_MEM_WRITE)
00729 return Region::RP_RW;
00730 else
00731 return Region::RP_R;
00732 }
00733
00734 Region::RegionType getRegionType(DWORD flags){
00735 if((flags & IMAGE_SCN_CNT_CODE) && (flags & IMAGE_SCN_CNT_INITIALIZED_DATA))
00736 return Region::RT_TEXTDATA;
00737 else if(flags & IMAGE_SCN_CNT_CODE)
00738 return Region::RT_TEXT;
00739 else if((flags & IMAGE_SCN_CNT_INITIALIZED_DATA) || (flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
00740 return Region::RT_DATA;
00741 else
00742 return Region::RT_OTHER;
00743 }
00744
00745 std::vector<std::pair<string, IMAGE_IMPORT_DESCRIPTOR> > & Object::getImportDescriptorTable()
00746 {
00747 if (!idt_.empty()) {
00748 return idt_;
00749 }
00750
00751 if (peHdr->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_IMPORT)
00752 assert(0 && "PE header doesn't specify the IDT address");
00753
00754
00755 DWORD dwITrva = peHdr->OptionalHeader.
00756 DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
00757
00758
00759
00760 DWORD dwIToffset = RVA2Offset(dwITrva);
00761
00762
00763 PIMAGE_IMPORT_DESCRIPTOR import_d = (PIMAGE_IMPORT_DESCRIPTOR)
00764 (((char*)mf->base_addr())+dwIToffset);
00765
00766 while(import_d ->Name != NULL && import_d->FirstThunk !=NULL){
00767 IMAGE_IMPORT_DESCRIPTOR ie;
00768 memcpy(&ie, import_d, sizeof(IMAGE_IMPORT_DESCRIPTOR));
00769 string str((char*)(((char*)mf->base_addr())+RVA2Offset(import_d->Name)));
00770 idt_.push_back(pair<string,IMAGE_IMPORT_DESCRIPTOR>(str,ie));
00771
00772 import_d ++;
00773 }
00774 return idt_;
00775
00776 }
00777
00778 map<string, map<string, WORD> > & Object::getHintNameTable()
00779 {
00780 if (!hnt_.empty()) {
00781 return hnt_;
00782 }
00783
00784 vector<pair<string, IMAGE_IMPORT_DESCRIPTOR> > idt = getImportDescriptorTable();
00785 for (vector<pair<string, IMAGE_IMPORT_DESCRIPTOR> >::iterator dit = idt.begin();
00786 dit != idt.end();
00787 dit++)
00788 {
00789 assert(sizeof(Offset) == getAddressWidth());
00790 Offset * iat = (Offset*)((char*)mf->base_addr() + RVA2Offset(dit->second.FirstThunk));
00791
00792 for (unsigned idx=0; iat[idx] != 0; idx++) {
00793 assert (0 == (0x80000000 & iat[idx]));
00794 IMAGE_IMPORT_BY_NAME *hintName = (IMAGE_IMPORT_BY_NAME *)
00795 ((char*)mf->base_addr() + RVA2Offset(iat[idx]));
00796 hnt_[dit->first][string((char*)hintName->Name)] = hintName->Hint;
00797 }
00798 }
00799
00800 return hnt_;
00801 }
00802
00803 void Object::FindInterestingSections(bool alloc_syms, bool defensive)
00804 {
00805
00806
00807 assert( peHdr == NULL );
00808 HANDLE mapAddr = mf->base_addr();
00809 peHdr = ImageNtHeader( mapAddr );
00810
00811 if (peHdr == NULL) {
00812 code_ptr_ = (char*)mapAddr;
00813 code_off_ = 0;
00814 HANDLE hFile = mf->getFileHandle();
00815 code_len_ = mf->size();
00816 is_aout_ = false;
00817 fprintf(stderr,"Adding Symtab object with no program header, will "
00818 "designate it as code, code_ptr_=%lx code_len_=%lx\n",
00819 code_ptr_,code_len_);
00820 if (alloc_syms) {
00821 Region *bufReg = new Region
00822 (0,
00823 ".text",
00824 code_off_,
00825 code_len_,
00826 code_off_,
00827 code_len_,
00828 code_ptr_,
00829 Region::RP_RWX,
00830 Region::RT_TEXT,
00831 true);
00832 regions_.push_back(bufReg);
00833 }
00834 return;
00835 }
00836
00837 assert( peHdr->FileHeader.SizeOfOptionalHeader > 0 );
00838
00839 string file_ = mf->filename();
00840 curModule = new Object::Module( file_, 0 );
00841 assert( curModule != NULL );
00842
00843 curModule->SetIsDll( (peHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0 );
00844 if(curModule->IsDll())
00845 is_aout_ = false;
00846 else
00847 is_aout_ = true;
00848
00849 getImportDescriptorTable();
00850
00851
00852
00853
00854
00855
00856
00857 if (!is_aout_ && peHdr->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT) {
00858 assert(sizeof(Offset) == getAddressWidth());
00859 unsigned long size;
00860 IMAGE_EXPORT_DIRECTORY *eT2 = (IMAGE_EXPORT_DIRECTORY *)::ImageDirectoryEntryToData(mapAddr, false, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
00861 if (eT2) {
00862 DWORD *funcNamePtrs = (DWORD *) ::ImageRvaToVa(ImageNtHeader(mapAddr), mapAddr, ULONG(eT2->AddressOfNames), NULL);
00863 DWORD *funcAddrs = (DWORD *) ::ImageRvaToVa(ImageNtHeader(mapAddr), mapAddr, ULONG(eT2->AddressOfFunctions), NULL);
00864 WORD *funcAddrNameMap = (WORD *) ::ImageRvaToVa(ImageNtHeader(mapAddr), mapAddr, ULONG(eT2->AddressOfNameOrdinals), NULL);
00865 if (funcNamePtrs && funcAddrs && funcAddrNameMap) {
00866 for (unsigned i = 0; i < eT2->NumberOfNames; ++i) {
00867 char *name = (char *) ::ImageRvaToVa(ImageNtHeader(mapAddr), mapAddr, funcNamePtrs[i], NULL);
00868 int funcIndx = funcAddrNameMap[i];
00869 Address funcAddr = funcAddrs[funcIndx];
00870 if ((funcAddr >= (Address) eT2) &&
00871 (funcAddr < ((Address) eT2 + size))) continue;
00872 Symbol *sym = new Symbol(name,
00873 Symbol::ST_FUNCTION,
00874 Symbol::SL_GLOBAL,
00875 Symbol::SV_DEFAULT,
00876 funcAddr);
00877 sym->setDynamic(true);
00878 symbols_[name].push_back(sym);
00879 symsToModules_[sym] = curModule->GetName();
00880 }
00881 }
00882 }
00883 }
00884
00885 SecAlignment = peHdr ->OptionalHeader.SectionAlignment;
00886 unsigned int nSections = peHdr->FileHeader.NumberOfSections;
00887 no_of_sections_ = nSections;
00888 Address prov_begin = (Address)-1;
00889 Address prov_end = (Address)-1;
00890 code_off_ = (Address)-1;
00891 code_len_ = (Address)-1;
00892
00893 if (defensive) {
00894
00895
00896 unsigned long secSize = ( peHdr->OptionalHeader.SizeOfHeaders
00897 / peHdr->OptionalHeader.SectionAlignment )
00898 * peHdr->OptionalHeader.SectionAlignment;
00899 if ( peHdr->OptionalHeader.SizeOfHeaders
00900 % peHdr->OptionalHeader.SectionAlignment )
00901 {
00902 secSize += peHdr->OptionalHeader.SectionAlignment;
00903 }
00904 prov_begin = 0;
00905 prov_end = prov_begin + secSize;
00906 regions_.push_back(
00907 new Region(
00908 0, "PROGRAM_HEADER", 0, peHdr->OptionalHeader.SizeOfHeaders,
00909 0, secSize, (char*)mapAddr,
00910 getRegionPerms(IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE),
00911 getRegionType(IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA),
00912 true));
00913 }
00914
00915 PIMAGE_SECTION_HEADER pScnHdr = (PIMAGE_SECTION_HEADER)(((char*)peHdr) +
00916 sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) +
00917 peHdr->FileHeader.SizeOfOptionalHeader);
00918 bool foundText = false;
00919 for( unsigned int i = 0; i < nSections; i++ ) {
00920
00921
00922
00923 Offset diskOffset = 0;
00924 if (pScnHdr->SizeOfRawData != 0) {
00925
00926
00927 diskOffset = (Offset)
00928 ((pScnHdr->PointerToRawData / peHdr->OptionalHeader.FileAlignment)
00929 * peHdr->OptionalHeader.FileAlignment);
00930 }
00931 Offset secSize = (pScnHdr->Misc.VirtualSize > pScnHdr->SizeOfRawData) ?
00932 pScnHdr->Misc.VirtualSize : pScnHdr->SizeOfRawData;
00933 if (alloc_syms)
00934 regions_.push_back
00935 (new Region(i+1,
00936 (const char *)pScnHdr->Name,
00937 diskOffset,
00938 pScnHdr->SizeOfRawData,
00939 pScnHdr->VirtualAddress,
00940 secSize,
00941 (char *)(diskOffset + (Offset)mapAddr),
00942 getRegionPerms(pScnHdr->Characteristics),
00943 getRegionType(pScnHdr->Characteristics)));
00944
00945
00946
00947
00948
00949 if( strncmp( (const char*)pScnHdr->Name, ".text", 8 ) == 0 ) {
00950
00951 textSectionId = i + 1;
00952 code_ptr_ = (char*)(((char*)mapAddr) +
00953 pScnHdr->PointerToRawData);
00954 code_off_ = pScnHdr->VirtualAddress;
00955
00956
00957
00958
00959 code_len_ = ((pScnHdr->SizeOfRawData < pScnHdr->Misc.VirtualSize) ?
00960 pScnHdr->SizeOfRawData : pScnHdr->Misc.VirtualSize);
00961
00962 foundText = true;
00963 if (prov_begin == -1) {
00964 prov_begin = code_off_;
00965 prov_end = code_off_ + code_len_;
00966 } else {
00967 if (prov_begin > code_off_) {
00968 prov_begin = code_off_;
00969 }
00970 if ( prov_end < (code_off_ + code_len_) ) {
00971 prov_end = (code_off_ + code_len_);
00972 }
00973 }
00974 }
00975 else if( strncmp( (const char*)pScnHdr->Name, ".data", 8 ) == 0 ) {
00976
00977 dataSectionId = i + 1;
00978 data_ptr_ = (char *)(((char*)mapAddr) +
00979 pScnHdr->PointerToRawData);
00980 data_off_ = pScnHdr->VirtualAddress;
00981 data_len_ = (pScnHdr->SizeOfRawData < pScnHdr->Misc.VirtualSize ?
00982 pScnHdr->SizeOfRawData : pScnHdr->Misc.VirtualSize);
00983 if (defensive) {
00984 if (prov_begin == -1) {
00985 prov_begin = data_off_;
00986 prov_end = data_off_ + data_len_;
00987 } else {
00988 if (prov_begin > data_off_) {
00989 prov_begin = data_off_;
00990 }
00991 if (prov_end < (data_off_ + data_len_)) {
00992 prov_end = (data_off_ + data_len_);
00993 }
00994 }
00995 }
00996 }
00997 else {
00998 Offset sec_len = (pScnHdr->SizeOfRawData < pScnHdr->Misc.VirtualSize) ?
00999 pScnHdr->SizeOfRawData : pScnHdr->Misc.VirtualSize;
01000 if (-1 == prov_begin) {
01001 prov_begin = pScnHdr->VirtualAddress;
01002 prov_end = prov_begin + sec_len;
01003 } else {
01004 if (prov_begin > pScnHdr->VirtualAddress) {
01005 prov_begin = pScnHdr->VirtualAddress;
01006 }
01007 if (prov_end < (pScnHdr->VirtualAddress + sec_len)) {
01008 prov_end = (pScnHdr->VirtualAddress + sec_len);
01009 }
01010 }
01011 }
01012 pScnHdr += 1;
01013 }
01014
01015 if (-1 == code_len_ || defensive) {
01016
01017
01018 if (code_off_ == -1)
01019 code_off_ = prov_begin;
01020 else if (prov_begin != -1 &&
01021 code_off_ > prov_begin)
01022 code_off_ = prov_begin;
01023
01024 if (code_len_ == -1)
01025 code_len_ = prov_end - code_off_;
01026 else if (prov_end != -1 &&
01027 code_len_ < (prov_end - code_off_))
01028 code_len_ = (prov_end - code_off_);
01029
01030 assert(code_off_ != -1 && code_len_ != -1);
01031 }
01032 }
01033
01034
01035 Region *Object::findEnclosingRegion(const Offset where)
01036 {
01037
01038 int first = 0;
01039 int last = regions_.size() - 1;
01040 while (last >= first) {
01041 Region *curreg = regions_[(first + last) / 2];
01042 if (where >= curreg->getMemOffset()
01043 && where < (curreg->getMemOffset()
01044 + curreg->getMemSize())) {
01045 return curreg;
01046 }
01047 else if (where < curreg->getMemOffset()) {
01048 last = ((first + last) / 2) - 1;
01049 }
01050 else {
01051
01052 first = ((first + last) / 2) + 1;
01053 }
01054 }
01055 return NULL;
01056 }
01057
01058 bool Object::isForwarded( Offset addr )
01059 {
01060
01061
01062
01063
01064
01065
01066 if(peHdr && peHdr->FileHeader.Characteristics & IMAGE_FILE_DLL )
01067 {
01068 PIMAGE_DATA_DIRECTORY dataDir = peHdr->OptionalHeader.DataDirectory;
01069 Offset exportStart = dataDir->VirtualAddress;
01070 Offset exportEnd = exportStart + dataDir->Size;
01071 if( addr >= exportStart && addr < exportEnd )
01072 return true;
01073 }
01074 return false;
01075 }
01076
01077 bool Object::getCatchBlock(ExceptionBlock &b, Offset addr,
01078 unsigned size) const
01079 {
01080 return false;
01081 }
01082
01083 bool Object::isText( const Offset addr ) const
01084 {
01085 return( addr >= code_off_ && addr < code_off_ + code_len_ );
01086 }
01087
01088 void fixup_filename(std::string &filename)
01089 {
01090 if (filename.substr(0,22) == "\\Device\\HarddiskVolume") {
01091 TCHAR volumePath[1024];
01092 if (GetVolumePathName(filename.c_str(), volumePath, 1024)) {
01093 std::string::size_type filePathIndex = filename.find_first_of("\\/", 22);
01094 if (filePathIndex != std::string::npos)
01095 filename = volumePath + filename.substr(++filePathIndex);
01096 else
01097 filename = volumePath + filename.substr(23);
01098 } else {
01099 filename = "c:"+filename.substr(23);
01100 }
01101 }
01102 }
01103
01104 Object::Object(MappedFile *mf_,
01105 bool defensive,
01106 void (*err_func)(const char *), bool alloc_syms) :
01107 AObject(mf_, err_func),
01108 curModule( NULL ),
01109 peHdr( NULL ),
01110 trapHeaderPtr_( 0 )
01111 {
01112 FindInterestingSections(alloc_syms, defensive);
01113 if (alloc_syms && defensive) {
01114 AddTLSFunctions();
01115 }
01116 ParseSymbolInfo(alloc_syms);
01117 }
01118
01119 SYMTAB_EXPORT ObjectType Object::objType() const
01120 {
01121 return is_aout() ? obj_Executable : obj_SharedLib;
01122 }
01123
01124
01125 void Object::getModuleLanguageInfo(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
01126 {
01127 return;
01128 }
01129
01130 struct line_info_tmp_t {
01131 line_info_tmp_t(unsigned long a, unsigned int l) {addr = a; line_no = l;}
01132 unsigned long addr;
01133 unsigned int line_no;
01134 };
01135
01136 struct line_info_tmp_lt {
01137 bool operator()(const line_info_tmp_t &a, const line_info_tmp_t &b) {
01138 return a.addr < b.addr;
01139 };
01140 };
01141
01142 typedef std::multiset<line_info_tmp_t, line_info_tmp_lt> info_for_file_t;
01143 typedef std::map<std::string, info_for_file_t*> info_for_all_files_t;
01144
01145 static BOOL CALLBACK add_line_info(SRCCODEINFO *srcinfo, void *param)
01146 {
01147 info_for_all_files_t *all_info = (info_for_all_files_t *) param;
01148 info_for_all_files_t::iterator iter = all_info->find(std::string(srcinfo->FileName));
01149 info_for_file_t *finfo = NULL;
01150 if (iter == all_info->end()) {
01151 finfo = new info_for_file_t();
01152 (*all_info)[std::string(srcinfo->FileName)] = finfo;
01153 }
01154 else {
01155 finfo = (*iter).second;
01156 }
01157 finfo->insert(line_info_tmp_t((unsigned long) srcinfo->Address, srcinfo->LineNumber));
01158 return true;
01159 }
01160
01161 static bool store_line_info(dyn_hash_map<std::string, LineInformation> *lineInfo,
01162 info_for_all_files_t *baseInfo)
01163 {
01164 for (info_for_all_files_t::iterator i = baseInfo->begin(); i != baseInfo->end(); i++)
01165 {
01166 const char *filename = (*i).first.c_str();
01167 for (info_for_file_t::iterator j = (*i).second->begin(); j != (*i).second->end(); j++) {
01168 info_for_file_t::iterator next = j;
01169 next++;
01170 if (next != (*i).second->end())
01171 (*lineInfo)[filename].addLine(filename, j->line_no, 0, j->addr, next->addr);
01172 else
01173 (*lineInfo)[filename].addLine(filename, j->line_no, 0, j->addr, j->addr);
01174 }
01175 delete (*i).second;
01176 }
01177 return true;
01178 }
01179
01180 void Object::parseFileLineInfo(Symtab *, dyn_hash_map<std::string, LineInformation> &li)
01181 {
01182 int result;
01183 static Offset last_file = 0x0;
01184
01185 Offset baseAddr = get_base_addr();
01186 if (last_file == baseAddr)
01187 return;
01188 last_file = baseAddr;
01189 info_for_all_files_t inf;
01190 result = SymEnumLines(hProc,
01191 baseAddr,
01192 NULL,
01193 NULL,
01194 add_line_info,
01195 &inf);
01196 if (!result) {
01197
01198 DWORD dwErr = GetLastError();
01199
01200
01201 return;
01202 }
01203 store_line_info(&li, &inf);
01204 }
01205
01206 typedef struct localsStruct {
01207 Function *func;
01208 Offset base;
01209 HANDLE p;
01210 map<unsigned, unsigned> foundSyms;
01211 localsStruct() : foundSyms() {}
01212 } localsStruct;
01213
01214 Dyninst::MachRegister WinConvert(Register reg) {
01215
01216 switch(reg) {
01217 case CV_REG_EAX:
01218 return x86::eax;
01219 case CV_REG_EBX:
01220 return x86::ebx;
01221 case CV_REG_ECX:
01222 return x86::ecx;
01223 case CV_REG_EDX:
01224 return x86::edx;
01225 case CV_REG_ESP:
01226 return x86::esp;
01227 case CV_REG_EBP:
01228 return x86::ebp;
01229 case CV_REG_ESI:
01230 return x86::esi;
01231 case CV_REG_EDI:
01232 return x86::edi;
01233 default:
01234 return Dyninst::InvalidReg;
01235 }
01236 }
01237
01238 BOOL CALLBACK enumLocalSymbols(PSYMBOL_INFO pSymInfo, unsigned long symSize,
01239 void *userContext)
01240 {
01241 Type *type;
01242 Function *func;
01243 storageClass storage;
01244 localVar *newvar;
01245 MachRegister reg;
01246 signed long frameOffset;
01247 Offset base;
01248 HANDLE p;
01249
01250 char *storageName;
01251 char *paramType;
01252
01253
01254
01255
01256 localsStruct *locals = (localsStruct *) userContext;
01257 if (locals->foundSyms.find(pSymInfo->Index) != locals->foundSyms.end())
01258 return true;
01259 locals->foundSyms[pSymInfo->Index] = 1;
01260 base = locals->base;
01261 func = locals->func;
01262 p = locals->p;
01263
01264
01265 type = getType(p, base, pSymInfo->TypeIndex, func->getModule());
01266
01267
01268 if ((pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE) ||
01269 ((pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE) &&
01270 (pSymInfo->Register = CV_REG_EBP)))
01271 {
01272 reg = x86::ebp;
01273 frameOffset = (signed) pSymInfo->Address;
01274 storage = storageRegOffset;
01275 storageName = "Frame Relative";
01276 }
01277 else if (pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
01278 {
01279 reg = WinConvert(pSymInfo->Register);
01280 frameOffset = (signed) pSymInfo->Address;
01281 storage = storageRegOffset;
01282 storageName = "Register Relative";
01283 }
01284 else if (pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER) {
01285 reg = WinConvert(pSymInfo->Register);
01286 frameOffset = 0;
01287 storage = storageReg;
01288 storageName = "Register";
01289 }
01290 else {
01291 frameOffset = (signed) pSymInfo->Address;
01292 storage = storageAddr;
01293 storageName = "Absolute";
01294 }
01295
01296 VariableLocation loc;
01297 loc.stClass = storage;
01298 loc.refClass = storageNoRef;
01299 loc.frameOffset = frameOffset;
01300 loc.lowPC = 0;
01301 loc.hiPC = (Address) -1;
01302 loc.mr_reg = reg;
01303
01304 std::string vName = convertCharToString(pSymInfo->Name);
01305 std::string fName = convertCharToString(func->getModule()->fileName().c_str());
01306 newvar = new localVar(vName, type, fName, -1, func);
01307 newvar->addLocation(loc);
01308
01309
01310 if (pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER) {
01311 assert(func);
01312 if (!func->addParam(newvar)) {
01313 fprintf(stderr, "%s[%d]: addParam failed\n", FILE__, __LINE__);
01314 return false;
01315 }
01316 paramType = "parameter";
01317 }
01318 else if (pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL) {
01319 assert(func);
01320 if (!func->addLocalVar(newvar)) {
01321 fprintf(stderr, "%s[%d]: addLocalVar failed\n", FILE__, __LINE__);
01322 return false;
01323 }
01324 paramType = "local";
01325 }
01326 else {
01327
01328 fprintf(stderr, "[%s:%u] - Local variable of unknown type. %s in %s\n",
01329 __FILE__, __LINE__, pSymInfo->Name, func->getAllPrettyNames()[0].c_str());
01330 paramType = "unknown";
01331 }
01332
01333
01334 const char *typeName;
01335 if (type) {
01336 typeName = type->getName().c_str();
01337 }
01338 else {
01339 typeName = "unknown";
01340 }
01341
01342 return true;
01343 }
01344
01345
01346 static void enumLocalVars(Function *func,
01347 localsStruct *locals)
01348 {
01349 IMAGEHLP_STACK_FRAME frame;
01350 memset(&frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
01351
01352 frame.InstructionOffset = locals->base + func->getOffset();
01353 int result = SymSetContext(locals->p, &frame, NULL);
01354
01355
01356
01357
01358 result = SymEnumSymbols(locals->p, 0, NULL, enumLocalSymbols, locals);
01359
01360
01361
01362
01363
01364 if(func->getSize())
01365 {
01366 memset(&frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
01367
01368 frame.InstructionOffset = locals->base +
01369 func->getOffset() +
01370 func->getSize();
01371 result = SymSetContext(locals->p, &frame, NULL);
01372 result = SymEnumSymbols(locals->p, 0, NULL, enumLocalSymbols, locals);
01373 }
01374
01375
01376 #if 0
01377 for (unsigned i=0; i<points.size(); i++) {
01378 frame.InstructionOffset = points[i]->addr();
01379 bool result = SymSetContext(locals->p, &frame, NULL);
01380
01381
01382
01383
01384 result = SymEnumSymbols(locals->p, 0, NULL, enumLocalSymbols, locals);
01385
01386
01387
01388
01389 }
01390 #endif
01391
01392 }
01393
01394 static int variantValue(VARIANT *v) {
01395 switch(v->vt) {
01396 case VT_I8:
01397 return (int) v->llVal;
01398 case VT_I4:
01399 return (int) v->lVal;
01400 case VT_UI1:
01401 return (int) v->bVal;
01402 case VT_I2:
01403 return (int) v->iVal;
01404 case VT_I1:
01405 return (int) v->cVal;
01406 case VT_UI2:
01407 return (int) v->uiVal;
01408 case VT_UI4:
01409 return (int) v->ulVal;
01410 case VT_UI8:
01411 return (int) v->ullVal;
01412 case VT_INT:
01413 return (int) v->intVal;
01414 case VT_UINT:
01415 return (int) v->uintVal;
01416 default:
01417 return 0;
01418 }
01419 }
01420
01421
01422 static void addTypeToCollection(Type *type, Module *mod)
01423 {
01424 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01425 assert(tc);
01426 tc->addType(type);
01427
01428
01429
01430
01431
01432
01433
01434
01435 }
01436
01437 static char *getTypeName(HANDLE p, Offset base, int typeIndex) {
01438 int result, length;
01439 WCHAR *wname = NULL;
01440 char *name = NULL;
01441
01442 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_SYMNAME, &wname);
01443 if (!result)
01444 return NULL;
01445 length = wcslen(wname) + 1;
01446 name = (char *) malloc(length + 1);
01447 result = WideCharToMultiByte(CP_ACP, 0, wname, -1, name, length, NULL, NULL);
01448 LocalFree(wname);
01449 if (!result) {
01450 int lasterror = GetLastError();
01451
01452 return NULL;
01453 }
01454 return name;
01455 }
01456
01457 static dataClass getDataClass(HANDLE p, Offset base, int typeIndex) {
01458 enum SymTagEnum wintype;
01459 int result, basetype;
01460
01461 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_SYMTAG, &wintype);
01462 if (!result)
01463 return dataUnknownType;
01464 switch (wintype) {
01465 case SymTagFunction:
01466 case SymTagFunctionType:
01467 return dataFunction;
01468 case SymTagPointerType:
01469 return dataPointer;
01470 case SymTagArrayType:
01471 return dataArray;
01472 case SymTagBaseType:
01473 return dataScalar;
01474 case SymTagEnum:
01475 return dataEnum;
01476 case SymTagTypedef:
01477 return dataTypedef;
01478 case SymTagUDT:
01479 enum UdtKind udtType;
01480 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_UDTKIND, &udtType);
01481 if (!result)
01482 return dataUnknownType;
01483 switch (udtType) {
01484 case UdtUnion:
01485 return dataUnion;
01486 case UdtStruct:
01487 case UdtClass:
01488 return dataStructure;
01489 default:
01490 return dataUnknownType;
01491 }
01492 case SymTagFunctionArgType:
01493 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &basetype);
01494 if (!result)
01495 return dataUnknownType;
01496 return getDataClass(p, base, basetype);
01497 default:
01498 return dataUnknownType;
01499 }
01500 }
01501
01502 static Type *getEnumType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01503 unsigned i;
01504 char *name = NULL;
01505 char *entryName = NULL;
01506 VARIANT entryValue;
01507 typeEnum *type;
01508 int result;
01509 unsigned numEntries, entriesSize;
01510 TI_FINDCHILDREN_PARAMS *entries = NULL;
01511
01512 name = getTypeName(p, base, typeIndex);
01513 std::string tName = convertCharToString(name);
01514 type = new typeEnum(typeIndex, tName);
01515 addTypeToCollection(type, mod);
01516 free(name);
01517 name = NULL;
01518
01519
01520
01521
01522 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_CHILDRENCOUNT, &numEntries);
01523 if (!result)
01524 numEntries = 0;
01525 if (numEntries) {
01526 entriesSize = sizeof(TI_FINDCHILDREN_PARAMS) + (numEntries + 1) * sizeof(ULONG);
01527 entries = (TI_FINDCHILDREN_PARAMS *) malloc(entriesSize);
01528 memset(entries, 0, entriesSize);
01529 entries->Count = numEntries;
01530 result = SymGetTypeInfo(p, base, typeIndex, TI_FINDCHILDREN, entries);
01531 if (!result)
01532 numEntries = 0;
01533 }
01534
01535 for (i=0; i<numEntries; i++) {
01536 entryName = getTypeName(p, base, entries->ChildId[i]);
01537 VariantInit(&entryValue);
01538 result = SymGetTypeInfo(p, base, entries->ChildId[i], TI_GET_VALUE, &entryValue);
01539 if (!result)
01540 continue;
01541 type->addConstant(entryName, variantValue(&entryValue));
01542 }
01543
01544 if (entries)
01545 free(entries);
01546 return type;
01547 }
01548
01549 static Type *getPointerType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01550 int baseTypeIndex, result;
01551 Type *baseType;
01552 typePointer *newType;
01553
01554 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &baseTypeIndex);
01555 if (!result) {
01556 fprintf(stderr, "[%s:%u] - TI_GET_TYPEID failed\n", __FILE__, __LINE__);
01557 return NULL;
01558 }
01559
01560
01561
01562
01563
01564
01565 newType = new typePointer(typeIndex, NULL);
01566 addTypeToCollection(newType, mod);
01567
01568 baseType = getType(p, base, baseTypeIndex, mod);
01569 if (!baseType) {
01570 fprintf(stderr, "[%s:%u] - getType failed\n", __FILE__, __LINE__);
01571 return NULL;
01572 }
01573
01574 newType->setPtr(baseType);
01575 return newType;
01576 }
01577
01578 static Type *getArrayType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01579 int result, baseIndex, index;
01580 Type *indexType, *newType, *baseType;
01581 unsigned size, num_elements;
01582 ULONG64 size64;
01583 std::string bname;
01584 std::string name;
01585
01586
01587 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_ARRAYINDEXTYPEID, &index);
01588 if (!result) {
01589 fprintf(stderr, "[%s:%u] - TI_GET_ARRAYINDEXTYPEID failed\n",
01590 __FILE__, __LINE__);
01591 return NULL;
01592 }
01593 indexType = getType(p, base, index, mod);
01594
01595
01596 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &baseIndex);
01597 if (!result) {
01598 fprintf(stderr, "[%s:%u] - TI_GET_TYPEID failed\n", __FILE__, __LINE__);
01599 return NULL;
01600 }
01601 baseType = getType(p, base, baseIndex, mod);
01602
01603 bname = baseType->getName();
01604 name = bname + "[]";
01605
01606 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_LENGTH, &size64);
01607 if (!result) {
01608 num_elements = 0;
01609 }
01610 else {
01611 size = (unsigned) size64;
01612 num_elements = size / baseType->getSize();
01613 }
01614
01615 newType = new typeArray(typeIndex, baseType, 0, num_elements-1, name);
01616 newType->getSize();
01617 addTypeToCollection(newType, mod);
01618 assert(newType->getID() == typeIndex);
01619
01620 return newType;
01621 }
01622
01623
01624 static Type *getTypedefType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01625 int result, baseTypeIndex;
01626 Type *baseType, *newType;
01627 char *name;
01628
01629 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &baseTypeIndex);
01630 if (!result) {
01631 fprintf(stderr, "[%s:%u] - TI_GET_TYPEID failed\n", __FILE__, __LINE__);
01632 return NULL;
01633 }
01634 baseType = getType(p, base, baseTypeIndex, mod);
01635 if (!baseType) {
01636 return NULL;
01637 }
01638
01639 name = getTypeName(p, base, typeIndex);
01640 std::string tName = convertCharToString(name);
01641 newType = new typeTypedef(typeIndex, baseType, tName);
01642 addTypeToCollection(newType, mod);
01643 return newType;
01644 }
01645
01646 static Type *getUDTType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01647 int result, symtag;
01648 unsigned size, numChildren, childrenSize, child_offset, i, child_size;
01649 fieldListType *newType;
01650 UINT64 size64;
01651 const char *name, *childName;
01652 enum UdtKind udtType;
01653 TI_FINDCHILDREN_PARAMS *children = NULL;
01654
01655
01656
01657
01658 name = getTypeName(p, base, typeIndex);
01659 std::string tName = convertCharToString(name);
01660 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_LENGTH, &size64);
01661 if (!result) {
01662 fprintf(stderr, "[%s:%u] - TI_GET_LENGTH return error\n");
01663 return NULL;
01664 }
01665 size = (unsigned) size64;
01666
01667
01668
01669
01670
01671 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_UDTKIND, &udtType);
01672 if (!result) {
01673 fprintf(stderr, "[%s:%u] - TI_GET_UDTKIND returned error\n");
01674 return NULL;
01675 }
01676 switch (udtType) {
01677 case UdtUnion:
01678 newType = new typeUnion(typeIndex, tName);
01679 break;
01680 case UdtStruct:
01681 case UdtClass:
01682 default:
01683 newType = new typeStruct(typeIndex, tName);
01684 break;
01685 }
01686 addTypeToCollection(newType, mod);
01687 if (name)
01688 free((void *) name);
01689 name = NULL;
01690
01691
01692
01693
01694
01695 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_CHILDRENCOUNT, &numChildren);
01696 if (!result)
01697 numChildren = 0;
01698
01699
01700
01701 if (numChildren) {
01702 childrenSize = sizeof(TI_FINDCHILDREN_PARAMS) + (numChildren + 1) * sizeof(ULONG);
01703 children = (TI_FINDCHILDREN_PARAMS *) malloc(childrenSize);
01704 memset(children, 0, childrenSize);
01705 children->Count = numChildren;
01706 result = SymGetTypeInfo(p, base, typeIndex, TI_FINDCHILDREN, children);
01707 if (!result)
01708 numChildren = 0;
01709 }
01710
01711
01712
01713
01714 for (i=0; i<numChildren; i++) {
01715
01716 Type *child_type = getType(p, base, children->ChildId[i], mod);
01717 if (!child_type)
01718 continue;
01719
01720
01721 childName = NULL;
01722 result = SymGetTypeInfo(p, base, children->ChildId[i], TI_GET_SYMTAG, &symtag);
01723 if (result && symtag == SymTagBaseClass) {
01724 childName = P_strdup("{superclass}");
01725 }
01726 if (!childName)
01727 childName = getTypeName(p, base, children->ChildId[i]);
01728 if (!childName)
01729 childName = P_strdup(child_type->getName().c_str());
01730
01731
01732 result = SymGetTypeInfo(p, base, children->ChildId[i], TI_GET_OFFSET, &child_offset);
01733 if (!result) {
01734 child_offset = 0;
01735 child_size = 0;
01736 }
01737 else {
01738 child_offset *= 8;
01739 child_size = child_type->getSize();
01740 }
01741
01742 std::string fName = convertCharToString(childName);
01743 newType->addField(fName, child_type, child_offset);
01744 if (childName)
01745 free((void *) childName);
01746 childName = NULL;
01747 }
01748
01749 if (children)
01750 free(children);
01751
01752 return newType;
01753 }
01754
01755 static Type *getLayeredType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01756 int result, newTypeIndex;
01757 Type *newType;
01758
01759 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &newTypeIndex);
01760 if (!result) {
01761 fprintf(stderr, "TI_GET_TYPEID failed\n");
01762 return NULL;
01763 }
01764
01765 newType = getType(p, base, newTypeIndex, mod);
01766 return newType;
01767 }
01768
01769 static Type *getFunctionType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01770 int result, retTypeIndex;
01771 typeFunction *newType;
01772 Type *retType;
01773 unsigned num_params, args_size, i;
01774 std::vector<Type *> params;
01775 TI_FINDCHILDREN_PARAMS *args = NULL;
01776 std::string name;
01777
01778
01779 std::string tName = "";
01780 newType = new typeFunction(typeIndex, NULL, tName);
01781 addTypeToCollection(newType, mod);
01782
01783 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_TYPEID, &retTypeIndex);
01784 if (!result) {
01785 fprintf(stderr, "[%s:%u] - Couldn't TI_GET_TYPEID\n", __FILE__, __LINE__);
01786 return NULL;
01787 }
01788
01789 retType = getType(p, base, retTypeIndex, mod);
01790 if (!retType) {
01791 return NULL;
01792 }
01793 newType->setRetType(retType);
01794
01795 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_COUNT, &num_params);
01796 if (!result)
01797 goto done_params;
01798
01799 args_size = sizeof(TI_FINDCHILDREN_PARAMS) + (num_params + 1) * sizeof(ULONG);
01800 args = (TI_FINDCHILDREN_PARAMS *) malloc(args_size);
01801 memset(args, 0, args_size);
01802 args->Count = num_params;
01803 result = SymGetTypeInfo(p, base, typeIndex, TI_FINDCHILDREN, args);
01804 if (!result)
01805 goto done_params;
01806
01807 for (i=0; i<num_params; i++) {
01808 Type *arg_type = getType(p, base, args->ChildId[i], mod);
01809 if (!arg_type) {
01810 continue;
01811 }
01812 params.push_back(arg_type);
01813 }
01814
01815 done_params:
01816
01817
01818
01819
01820 name = "(";
01821 name += retType->getName();
01822 name += ")(";
01823 for (i=0; i<params.size(); i++) {
01824 if (i != 0)
01825 name += ", ";
01826 name += params[i]->getName();
01827 }
01828 name += "()";
01829
01830 std::string newName = name;
01831 newType->setName(newName);
01832
01833 for (i=0; i<params.size(); i++) {
01834
01835 newType->addParam(params[i]);
01836 }
01837
01838 if (args)
01839 free(args);
01840
01841 return newType;
01842 }
01843
01844 static Type *getBaseType(HANDLE p, Offset base, int typeIndex, Module *mod) {
01845 BasicType baseType;
01846 int result;
01847 ULONG64 size64;
01848 unsigned size;
01849 Type *newType;
01850
01851 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_BASETYPE, &baseType);
01852 if (!result) {
01853 fprintf(stderr, "[%s:%u] - TI_GET_BASETYPE return error\n");
01854 return NULL;
01855 }
01856
01857 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_LENGTH, &size64);
01858 if (!result) {
01859 fprintf(stderr, "[%s:%u] - TI_GET_LENGTH return error\n");
01860 return NULL;
01861 }
01862 size = (unsigned) size64;
01863 switch(baseType) {
01864 case btNoType:
01865 newType = NULL;
01866 break;
01867 case btVoid:
01868 newType = new typeScalar(typeIndex, size, "void");
01869 break;
01870 case btChar:
01871 newType = new typeScalar(typeIndex, size, "char");
01872 break;
01873 case btWChar:
01874 newType = new typeScalar(typeIndex, size, "wchar");
01875 break;
01876 case btInt:
01877 if (size == 8)
01878 newType = new typeScalar(typeIndex, size, "long long int");
01879 else if (size == 4)
01880 newType = new typeScalar(typeIndex, size, "int");
01881 else if (size == 2)
01882 newType = new typeScalar(typeIndex, size, "short");
01883 else if (size == 1)
01884 newType = new typeScalar(typeIndex, size, "char");
01885 else
01886 newType = new typeScalar(typeIndex, size, "");
01887 break;
01888 case btUInt:
01889 if (size == 8)
01890 newType = new typeScalar(typeIndex, size, "unsigned long long int");
01891 else if (size == 4)
01892 newType = new typeScalar(typeIndex, size, "unsigned int");
01893 else if (size == 2)
01894 newType = new typeScalar(typeIndex, size, "unsigned short");
01895 else if (size == 1)
01896 newType = new typeScalar(typeIndex, size, "unsigned char");
01897 else
01898 newType = new typeScalar(typeIndex, size, "");
01899 break;
01900 case btFloat:
01901 if (size == 8)
01902 newType = new typeScalar(typeIndex, size, "double");
01903 else
01904 newType = new typeScalar(typeIndex, size, "float");
01905 break;
01906 case btBCD:
01907 newType = new typeScalar(typeIndex, size, "BCD");
01908 break;
01909 case btBool:
01910 newType = new typeScalar(typeIndex, size, "bool");
01911 break;
01912 case btLong:
01913 newType = new typeScalar(typeIndex, size, "long");
01914 break;
01915 case btULong:
01916 newType = new typeScalar(typeIndex, size, "unsigned long");
01917 break;
01918 case btCurrency:
01919 newType = new typeScalar(typeIndex, size, "currency");
01920 break;
01921 case btDate:
01922 newType = new typeScalar(typeIndex, size, "Date");
01923 break;
01924 case btVariant:
01925 newType = new typeScalar(typeIndex, size, "variant");
01926 break;
01927 case btComplex:
01928 newType = new typeScalar(typeIndex, size, "complex");
01929 break;
01930 case btBit:
01931 newType = new typeScalar(typeIndex, size, "bit");
01932 break;
01933 case btBSTR:
01934 newType = new typeScalar(typeIndex, size, "bstr");
01935 break;
01936 case btHresult:
01937 newType = new typeScalar(typeIndex, size, "Hresult");
01938 break;
01939 default:
01940 fprintf(stderr, "Couldn't parse baseType %d for %d\n", baseType, typeIndex);
01941 assert(0);
01942 break;
01943 }
01944 if (newType)
01945 addTypeToCollection(newType, mod);
01946 return newType;
01947 }
01948
01949 static Type *getType(HANDLE p, Offset base, int typeIndex, Module *mod)
01950 {
01951 static unsigned depth = 0;
01952 BOOL result;
01953 Type *foundType = NULL;
01954 typeCollection *collection;
01955 enum SymTagEnum symtag;
01956
01957 if (!typeIndex)
01958 return NULL;
01959
01960
01961
01962
01963
01964
01965 if (mod)
01966 collection = typeCollection::getModTypeCollection(mod);
01967 else
01968 collection = (typeCollection*)Symtab::stdTypes;
01969 assert(collection);
01970
01971
01972
01973
01974
01975 foundType = collection->findType(typeIndex);
01976 if (foundType) {
01977 return foundType;
01978 }
01979
01980
01981
01982
01983
01984 result = SymGetTypeInfo(p, base, typeIndex, TI_GET_SYMTAG, &symtag);
01985 if (!result) {
01986 depth--;
01987 return NULL;
01988 }
01989 switch (symtag) {
01990 case SymTagBaseType:
01991 foundType = getBaseType(p, base, typeIndex, mod);
01992 break;
01993 case SymTagEnum:
01994 foundType = getEnumType(p, base, typeIndex, mod);
01995 break;
01996 case SymTagFunctionType:
01997 foundType = getFunctionType(p, base, typeIndex, mod);
01998 break;
01999 case SymTagPointerType:
02000 foundType = getPointerType(p, base, typeIndex, mod);
02001 break;
02002 case SymTagArrayType:
02003 foundType = getArrayType(p, base, typeIndex, mod);
02004 break;
02005 case SymTagTypedef:
02006 foundType = getTypedefType(p, base, typeIndex, mod);
02007 break;
02008 case SymTagUDT:
02009 foundType = getUDTType(p, base, typeIndex, mod);
02010 break;
02011 case SymTagFunctionArgType:
02012 case SymTagData:
02013 case SymTagFunction:
02014 case SymTagBaseClass:
02015 foundType = getLayeredType(p, base, typeIndex, mod);
02016 if (foundType)
02017 typeIndex = foundType->getID();
02018 break;
02019 case SymTagThunk:
02020 foundType = NULL;
02021 break;
02022 case SymTagVTableShape:
02023 case SymTagVTable:
02024 break;
02025 default:
02026 fprintf(stderr, "Unknown type %d\n", symtag);
02027 assert(0);
02028 foundType = NULL;
02029 break;
02030 }
02031
02032 return foundType;
02033 }
02034
02035 typedef struct proc_mod_pair {
02036 HANDLE handle;
02037 Symtab *obj;
02038 Offset base_addr;
02039 } proc_mod_pair;
02040
02041 static void findLocalVars(Function *func, proc_mod_pair base) {
02042 Module *mod = func->getModule();
02043 localsStruct locals;
02044 HANDLE p = base.handle;
02045
02046 locals.func = func;
02047 locals.base = base.base_addr;
02048 locals.p = p;
02049
02050 enumLocalVars(func, &locals);
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062 }
02063
02064 BOOL CALLBACK add_type_info(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, void *info)
02065 {
02066 HANDLE p;
02067 Offset obj_base;
02068 proc_mod_pair *pair;
02069 Symtab *obj;
02070 Type *type;
02071 char *name;
02072 Address addr;
02073
02074 if (!isGlobalSymbol(pSymInfo)) {
02075
02076 return TRUE;
02077 }
02078
02079 pair = (proc_mod_pair *) info;
02080 p = pair->handle;
02081 obj_base = pair->base_addr;
02082 obj = pair->obj;
02083 name = pSymInfo->Name;
02084 addr = (Address) pSymInfo->Address - obj_base;
02085
02086 std::vector<Module *> mods;
02087 Module *mod;
02088
02089 if(!obj->getAllModules(mods))
02090 {
02091 return true;
02092 }
02093 else
02094 mod = mods[0];
02095
02096 if (obj->isExec()) {
02097
02098
02099
02100
02101
02102 Function *f = NULL;
02103 if(obj->findFuncByEntryOffset(f, (Offset) pSymInfo->Address))
02104 {
02105
02106 if (strcmp(f->getModule()->fileName().c_str(), "DEFAULT_MODULE"))
02107 return true;
02108 }
02109 }
02110
02111 type = getType(p, obj_base, pSymInfo->TypeIndex, mod);
02112
02113
02114
02115
02116
02117 if (type)
02118 {
02119 Variable *var = NULL;
02120 bool result = obj->findVariableByOffset(var, addr);
02121 if (result) {
02122 var->setType(type);
02123 }
02124 if (name) {
02125 std::string vName = name;
02126 typeCollection *tc = typeCollection::getModTypeCollection(mod);
02127 assert(tc);
02128 tc->addGlobalVariable(vName, type);
02129 }
02130 }
02131 return TRUE;
02132 }
02133
02134 void Object::parseTypeInfo(Symtab *obj) {
02135 proc_mod_pair pair;
02136 BOOL result;
02137
02138
02139
02140
02141 pair.handle = hProc;
02142 pair.obj = obj;
02143 pair.base_addr = getBaseAddress();
02144
02145 if (!pair.base_addr) {
02146 pair.base_addr = getLoadAddress();
02147 }
02148
02149 HANDLE mapAddr = mf->base_addr();
02150 result = SymEnumSymbols(hProc, (DWORD64)mapAddr, NULL,
02151 add_type_info, &pair);
02152 if (!result){
02153 printSysError(GetLastError());
02154
02155 }
02156
02157
02158
02159
02160 std::vector<Function *> funcs;
02161 obj->getAllFunctions(funcs);
02162 for (unsigned i=0; i < funcs.size(); i++) {
02163 findLocalVars(funcs[i], pair);
02164 }
02165 }
02166
02167 bool AObject::getSegments(vector<Segment> &segs) const
02168 {
02169 for(unsigned int i=0; i<regions_.size(); i++){
02170 Segment seg;
02171 seg.data = regions_[i]->getPtrToRawData();
02172
02173 seg.loadaddr = regions_[i] -> getMemOffset();
02174 seg.size = regions_[i] -> getDiskSize();
02175 seg.name = regions_[i] -> getRegionName();
02176
02177 segs.push_back(seg);
02178 }
02179 return true;
02180 }
02181
02182 bool Object::emitDriver(Symtab *obj, string fName, std::vector<Symbol *>&allSymbols,
02183 unsigned flag)
02184 {
02185 emitWin *em = new emitWin((PCHAR)GetMapAddr(), this, err_func_);
02186 return em -> driver(obj, fName);
02187 }
02188
02189
02190 void Object::addReference(Offset off, std::string lib, std::string fun){
02191 ref[lib][off] = fun;
02192 }
02193
02194
02195
02196
02197 DWORD Object::ImageOffset2SectionNum(DWORD dwRO)
02198 {
02199 PIMAGE_SECTION_HEADER sectionHeader =
02200 (PIMAGE_SECTION_HEADER)((DWORD)peHdr
02201 + sizeof(DWORD)
02202 + sizeof(IMAGE_FILE_HEADER)
02203 + peHdr->FileHeader.SizeOfOptionalHeader);
02204 unsigned int SecCount = peHdr ->FileHeader.NumberOfSections;
02205 for(unsigned int i=0;i < SecCount; i++)
02206 {
02207 if((dwRO>=sectionHeader->PointerToRawData) && (dwRO<(sectionHeader->PointerToRawData+sectionHeader->SizeOfRawData)))
02208 {
02209 return (i);
02210 }
02211 sectionHeader++;
02212 }
02213 return(-1);
02214 }
02215
02216 PIMAGE_SECTION_HEADER Object::ImageOffset2Section(DWORD dwRO)
02217 {
02218 PIMAGE_SECTION_HEADER sectionHeader =
02219 (PIMAGE_SECTION_HEADER)((DWORD)peHdr
02220 + sizeof(DWORD)
02221 + sizeof(IMAGE_FILE_HEADER)
02222 + peHdr->FileHeader.SizeOfOptionalHeader);
02223 unsigned int SecCount = peHdr ->FileHeader.NumberOfSections;
02224
02225 for(unsigned int i=0;i<SecCount;i++)
02226 {
02227 if((dwRO >= sectionHeader->PointerToRawData) &&
02228 (dwRO < (sectionHeader->PointerToRawData + sectionHeader->SizeOfRawData)))
02229 {
02230 return sectionHeader;
02231 }
02232 sectionHeader++;
02233 }
02234 return(NULL);
02235 }
02236
02237 PIMAGE_SECTION_HEADER Object::ImageRVA2Section(DWORD dwRVA)
02238 {
02239 PIMAGE_SECTION_HEADER sectionHeader =
02240 (PIMAGE_SECTION_HEADER)((DWORD)peHdr
02241 + sizeof(DWORD)
02242 + sizeof(IMAGE_FILE_HEADER)
02243 + peHdr->FileHeader.SizeOfOptionalHeader);
02244 unsigned int SecCount = peHdr ->FileHeader.NumberOfSections;
02245
02246 for(unsigned int i=0;i<SecCount;i++)
02247 {
02248 if((dwRVA>=sectionHeader->VirtualAddress) && (dwRVA<=(sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)))
02249 {
02250 return sectionHeader;
02251 }
02252 sectionHeader++;
02253 }
02254 return(NULL);
02255 }
02256
02257 DWORD Object::RVA2Offset(DWORD dwRVA)
02258 {
02259 DWORD offset;
02260 PIMAGE_SECTION_HEADER section = ImageRVA2Section(dwRVA);
02261 if(section==NULL)
02262 {
02263 return(0);
02264 }
02265 offset=dwRVA+section->PointerToRawData-section->VirtualAddress;
02266 return offset;
02267 }
02268
02269 DWORD Object::Offset2RVA(DWORD dwRO)
02270 {
02271 PIMAGE_SECTION_HEADER section = ImageOffset2Section(dwRO);
02272 if(section==NULL)
02273 {
02274 return(0);
02275 }
02276 return(dwRO+section->VirtualAddress-section->PointerToRawData);
02277 }
02278
02279 void Object::setTrapHeader(Offset addr)
02280 {
02281 trapHeaderPtr_ = addr;
02282 }
02283 Offset Object::trapHeader()
02284 {
02285 return trapHeaderPtr_;
02286 }
02287
02288 void Object::insertPrereqLibrary(std::string lib)
02289 {
02290
02291 ref[lib] = std::map<Offset, std::string>();
02292 }
02293
02294 bool Region::isStandardCode()
02295 {
02296 return (getRegionPermissions() == RP_RX ||
02297 getRegionPermissions() == RP_RWX);
02298 }
02299
02300 Dyninst::Architecture Object::getArch()
02301 {
02302 return Dyninst::Arch_x86;
02303 }
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356