SZ Bsc1::formatDname(SZ szDecor) { #define BUFLEN 250 static char decorBuf[BUFLEN]; if (szDecor[0] != '?') return szDecor; __unDName(decorBuf, szDecor, BUFLEN-32, malloc, free, UNDNAME_NO_FUNCTION_RETURNS| UNDNAME_NO_ALLOCATION_MODEL| UNDNAME_NO_ALLOCATION_LANGUAGE| UNDNAME_NO_MS_KEYWORDS| UNDNAME_NO_MS_THISTYPE| UNDNAME_NO_CV_THISTYPE| UNDNAME_NO_ACCESS_SPECIFIERS| UNDNAME_NO_THROW_SIGNATURES| UNDNAME_NO_MEMBER_TYPE| UNDNAME_NO_RETURN_UDT_MODEL); szDecor = decorBuf; if (szDecor[0] == ' ') szDecor++; if (szDecor[0] == '?' && szDecor[1] == '?' && szDecor[2] == ' ') szDecor += 3; return szDecor; }
const char * __thiscall MSVCRT_type_info_name(type_info * _this) { if (!_this->name) { /* Create and set the demangled name */ /* Note: mangled name in type_info struct always starts with a '.', while * it isn't valid for mangled name. * Is this '.' really part of the mangled name, or has it some other meaning ? */ char* name = __unDName(0, _this->mangled + 1, 0, MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); if (name) { unsigned int len = strlen(name); /* It seems _unDName may leave blanks at the end of the demangled name */ while (len && name[--len] == ' ') name[len] = '\0'; if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL)) { /* Another thread set this member since we checked above - use it */ MSVCRT_free(name); } } } TRACE("(%p) returning %s\n", _this, _this->name); return _this->name; }
QString MsvcDemangler::demangle(const QString &symbol) const { QString result; if (char *output = __unDName(NULL, symbol.toLatin1().constData(), 0, 0)) { result = QLatin1String(output); free(output); } return result; }
QString DefaultDemangler::demangle(const QString &symbol) const { int status; auto byteArray = symbol.toLatin1(); if (auto output = std::unique_ptr<char[], FreeDeleter>(__cxa_demangle(byteArray.constData(), nullptr, nullptr, &status))) { return QLatin1String(output.get()); } else if (auto output = std::unique_ptr<char[], FreeDeleter>(__unDName(nullptr, byteArray.constData(), 0, 0))) { return QLatin1String(output.get()); } else { return QString(); } }
char* undname(const char* decorated) { dummy_parent = talloc(sizeof(int), NULL); char* undecorated = calloc(BUFFER_SIZE, sizeof(char)); __unDName(undecorated, decorated, BUFFER_SIZE, malloc, free, UNDNAME_COMPLETE); // __unDName's behavior in case of failure is to return the mangled string // (despite what the documentation says). if (0 == strcmp(decorated, undecorated)) return NULL; return undecorated; }
const char * __stdcall MSVCRT_type_info_name(type_info * _this) { if (!_this->name) { /* Create and set the demangled name */ /* Nota: mangled name in type_info struct always start with a '.', while * it isn't valid for mangled name. * Is this '.' really part of the mangled name, or has it some other meaning ? */ char* name = __unDName(0, _this->mangled + 1, 0, MSVCRT_malloc, MSVCRT_free, 0x2800); if (name) { unsigned int len = strlen(name); /* It seems _unDName may leave blanks at the end of the demangled name */ while (len && name[--len] == ' ') name[len] = '\0'; _mlock(_EXIT_LOCK2); if (_this->name) { /* Another thread set this member since we checked above - use it */ MSVCRT_free(name); } else _this->name = name; _munlock(_EXIT_LOCK2); } } TRACE("(%p) returning %s\n", _this, _this->name); return _this->name; }
bool LoadDIASymbols(const wxString &strPDBFile, wxInt32 modulenum, std::list<CFunctionDescription> & llFuncs, stdext::hash_map<BasedAddress,int> & addressmap ) { // Create DIA80 Data Source Object IDiaDataSource *pDataSource; HRESULT hr = NoRegCoCreate( L"msdia80.dll", _uuidof( DiaSource ), _uuidof( IDiaDataSource ), (void **) &(pDataSource)); if(!SUCCEEDED(hr)) { return false; } /* HMODULE mod=LoadLibrary(L"msdia80.dll"); if(!mod) { return false; } TYPEOF_DllGetClassObject *pGetClassObject=(TYPEOF_DllGetClassObject *)GetProcAddress(mod,"DllGetClassObject"); if(!pGetClassObject) { FreeLibrary(mod); return false; } IClassFactory *pcf; HRESULT hr=(*pGetClassObject)(CLSID_DiaSource,IID_IClassFactory,(void **)&pcf); if(!SUCCEEDED(hr)) { FreeLibrary(mod); return false; } IDiaDataSource *pDataSource; hr=pcf->CreateInstance(NULL,_uuidof(IDiaDataSource),(void **)&pDataSource); if(!SUCCEEDED(hr)) { pcf->Release(); FreeLibrary(mod); return false; } pcf->Release(); */ // Load the executable's debug symbols hr=pDataSource->loadDataFromPdb(strPDBFile); if(!SUCCEEDED(hr)) { pDataSource->Release(); return false; } // Open a symbol session IDiaSession *pDIASession; hr=pDataSource->openSession(&pDIASession); if(!SUCCEEDED(hr)) { pDataSource->Release(); return false; } // Set the UNBASED address on the session, for resolving BasedAddress addrs hr=pDIASession->put_loadAddress(0); if(!SUCCEEDED(hr)) { pDIASession->Release(); pDataSource->Release(); return false; } // Get addresses for this module std::list<BasedAddress> addresses; for(stdext::hash_map<BasedAddress,int>::iterator iter=addressmap.begin();iter!=addressmap.end();iter++) { if(iter->first.nModule==modulenum) { addresses.push_back(iter->first); } } stdext::hash_map<DWORD,wxInt32> functions; int curidx=(int)llFuncs.size(); for(std::list<BasedAddress>::iterator itera=addresses.begin();itera!=addresses.end();itera++) { // Get the symbol for this thing IDiaSymbol* pFunc; if(FAILED(pDIASession->findSymbolByVA(itera->nAddr, SymTagFunction, &pFunc)) || pFunc==NULL) { continue; } // Get the unique symbol index id DWORD indexId; if(FAILED(pFunc->get_symIndexId(&indexId))) { pFunc->Release(); continue; } // See if we have this function already stdext::hash_map<DWORD,int>::iterator iterf=functions.find(indexId); if(iterf!=functions.end()) { addressmap[*itera]=iterf->second; } else { CFunctionDescription func; ////// ULONGLONG addr; if(FAILED(pFunc->get_virtualAddress(&addr))) { pFunc->Release(); continue; } ////// ULONGLONG length; if(FAILED(pFunc->get_length(&length))) { pFunc->Release(); continue; } ///////// BSTR pName; if(FAILED(pFunc->get_name(&pName))) { pFunc->Release(); continue; } func.strMangledName=(const LPWSTR)pName; LocalFree(pName); char mangled[512]; WideCharToMultiByte(CP_UTF8,0,func.strMangledName,-1,mangled,512,NULL,NULL); ///////// char outbase[512]; __unDName(outbase,mangled,512,&malloc,&free,0x1000); wchar_t outbasew[512]; MultiByteToWideChar(CP_UTF8,0,outbase,-1,outbasew,512); func.strBaseName=(const wchar_t *)(outbasew); ///////// char outfull[512]; __unDName(outfull,mangled,512,&malloc,&free,0); wchar_t outfullw[512]; MultiByteToWideChar(CP_UTF8,0,outfull,-1,outfullw,512); func.strFullName=(const wchar_t *)(outfullw); ////////// func.nAddress=BasedAddress(addr,modulenum); func.nByteLength=length; ///////// IDiaEnumLineNumbers *pdeln; func.strSourceFile=wxT("<unknown>"); func.nFirstSourceLine=0; func.nLastSourceLine=0; bool bGotFile=false; if(SUCCEEDED(pDIASession->findLinesByVA(addr,length,&pdeln))) { IDiaLineNumber *pdln; int nLineItem=0; while(SUCCEEDED(pdeln->Item(nLineItem,&pdln))) { DWORD dwLineNumber; IDiaSourceFile *pdsf; if(SUCCEEDED(pdln->get_lineNumber(&dwLineNumber)) && SUCCEEDED(pdln->get_sourceFile(&pdsf))) { BSTR filename; if(SUCCEEDED(pdsf->get_fileName(&filename))) { if(bGotFile) { if(filename==func.strSourceFile) { if(dwLineNumber<func.nFirstSourceLine) { func.nFirstSourceLine=dwLineNumber; } if(dwLineNumber>func.nLastSourceLine) { func.nLastSourceLine=dwLineNumber; } } } else { bGotFile=true; func.strSourceFile=filename; func.nFirstSourceLine=dwLineNumber; func.nLastSourceLine=dwLineNumber; } LocalFree(filename); } pdsf->Release(); } pdln->Release(); nLineItem++; } pdeln->Release(); } llFuncs.push_back(func); functions[indexId]=curidx; addressmap[*itera]=curidx; curidx++; } } pDIASession->Release(); pDataSource->Release(); // FreeLibrary(mod); return true; }