From 4adda326f589320c599213af3a64ede1a480ed60 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 25 Sep 2012 06:15:50 +0000 Subject: [PATCH] [0.2.x] fixed : DiaSymbol::getName git-svn-id: https://pykd.svn.codeplex.com/svn@79835 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dia/diawrapper.cpp | 102 +++++++++++++++++++++++++++-------- test/scripts/moduletest.py | 7 ++- test/scripts/pykdtest.py | 9 +++- test/targetapp/targetapp.cpp | 7 +++ 4 files changed, 99 insertions(+), 26 deletions(-) diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp index f260c44..b1c7f63 100644 --- a/pykd/dia/diawrapper.cpp +++ b/pykd/dia/diawrapper.cpp @@ -306,6 +306,7 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index ) SymbolPtr DiaSymbol::getChildByName(const std::string &name ) { + // ищем прямое совпадение DiaEnumSymbolsPtr symbols; HRESULT hres = m_symbol->findChildren( @@ -329,9 +330,37 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name ) return SymbolPtr( new DiaSymbol(child, m_machineType) ); } - std::string pattern = "*"; + // _имя + std::string underscoreName; + underscoreName += '_'; + underscoreName += name; + symbols = 0; + + hres = + m_symbol->findChildren( + ::SymTagNull, + toWStr(underscoreName), + nsfCaseSensitive | nsfUndecoratedName, + &symbols); + + hres = symbols->get_Count(&count); + if (S_OK != hres) + throw DiaException("Call IDiaEnumSymbols::get_Count", hres); + + if (count >0 ) + { + DiaSymbolPtr child; + hres = symbols->Item(0, &child); + if (S_OK != hres) + throw DiaException("Call IDiaEnumSymbols::Item", hres); + + return SymbolPtr( new DiaSymbol(child, m_machineType) ); + } + + // _имя@парам + std::string pattern = "_"; pattern += name; - pattern += "*"; + pattern += "@*"; symbols = 0; hres = @@ -350,20 +379,17 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name ) if (count == 0) throw DiaException( name + " not found"); - - for ( LONG i = 0; i < count; ++i ) + + if (count >0 ) { DiaSymbolPtr child; - hres = symbols->Item(i, &child); + hres = symbols->Item(0, &child); if (S_OK != hres) throw DiaException("Call IDiaEnumSymbols::Item", hres); - SymbolPtr symPtr = SymbolPtr( new DiaSymbol(child, m_machineType) ); - - if ( name == symPtr->getName() ) - return symPtr; + return SymbolPtr( new DiaSymbol(child, m_machineType) ); } - + throw DiaException(name + " is not found"); } @@ -432,30 +458,60 @@ ULONG DiaSymbol::getLocType() ////////////////////////////////////////////////////////////////////////////// -static const boost::regex stdcallMatch("^(\\w+)(@\\d+)?$"); +static const boost::regex stdcallMatch("^_(\\w+)(@\\d+)?$"); +static const boost::regex fastcallMatch("^@(\\w+)(@\\d+)?$"); std::string DiaSymbol::getName() { + HRESULT hres; BSTR bstrName = NULL; - HRESULT hres = m_symbol->get_undecoratedName(&bstrName); - if (S_OK != hres) - bstrName = callSymbol(get_name); - - std::string retStr = autoBstr( bstrName ).asStr(); ULONG symTag; hres = m_symbol->get_symTag( &symTag ); - if ( S_OK == hres && symTag == SymTagPublicSymbol && retStr[0] == '_' ) + + if ( FAILED( hres ) ) + throw DiaException("Call IDiaSymbol::get_symTag", hres); + + if ( symTag == SymTagPublicSymbol ) { - retStr.erase( 0, 1 ); + std::string retStr = autoBstr( callSymbol(get_name) ).asStr(); + + boost::cmatch matchResult; + + if ( boost::regex_match( retStr.c_str(), matchResult, stdcallMatch ) ) + return std::string( matchResult[1].first, matchResult[1].second ); + + if ( boost::regex_match( retStr.c_str(), matchResult, fastcallMatch ) ) + return std::string( matchResult[1].first, matchResult[1].second ); + + return retStr; + } + + if( symTag == SymTagData || symTag == SymTagFunction ) + { + hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName); + if ( FAILED( hres ) ) + throw DiaException("Call IDiaSymbol::get_undecoratedNameEx", hres); + + std::string retStr = autoBstr( bstrName ).asStr(); + + if ( !retStr.empty() ) + { + boost::cmatch matchResult; + + if ( boost::regex_match( retStr.c_str(), matchResult, stdcallMatch ) ) + return std::string( matchResult[1].first, matchResult[1].second ); + + if ( boost::regex_match( retStr.c_str(), matchResult, fastcallMatch ) ) + return std::string( matchResult[1].first, matchResult[1].second ); + + return retStr; + } } - boost::cmatch matchResult; + bstrName = callSymbol(get_name); - if ( boost::regex_match( retStr.c_str(), matchResult, stdcallMatch ) ) - retStr= std::string( matchResult[1].first, matchResult[1].second ); - - return retStr; + return autoBstr( bstrName ).asStr(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index e77b060..701d578 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -49,6 +49,11 @@ class ModuleTest( unittest.TestCase ): self.assertEqual( target.module.rva("FuncWithName0"), target.module.FuncWithName0 - target.module.begin() ) self.assertEqual( target.module.rva("FuncWithName0"), pykd.getOffset( target.module.name() + "!FuncWithName0") - target.module.begin() ) + def testFindSymbol( self ): + self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) ) + self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) ) + + def testType( self ): self.assertEqual( "structTest", target.module.type("structTest").name() ); self.assertEqual( "structTest", target.module.type("g_structTest").name() ); @@ -61,6 +66,6 @@ class ModuleTest( unittest.TestCase ): self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) self.assertEqual( 2, displacement ) fileName, lineNo, displacement = pykd.getSourceLine() - self.assertEqual( 616, lineNo ) + self.assertEqual( 622, lineNo ) diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index d2cd68c..deb1db0 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -53,8 +53,13 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ), ] ) else: - return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) - + return unittest.TestSuite( + [ + unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ), + unittest.TestLoader().loadTestsFromName( singleName ), + unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ) + ] ) + if __name__ == "__main__": print "\nTesting PyKd ver. " + pykd.version diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index 167d144..7c38a9c 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -459,6 +459,12 @@ void FuncWithName1(int a) std::cout << g_arrOfPtrToFunc[1]; } +static +void _FuncWithName2(int a) +{ + std::cout << a; +} + //////////////////////////////////////////////////////////////////////////////// #pragma optimize("g", off) VOID functionCalledFromEnumWindowsProc1(DWORD dwProcessId) @@ -637,6 +643,7 @@ int _tmain(int argc, _TCHAR* argv[]) __debugbreak(); FuncWithName0(); FuncWithName1(2); + _FuncWithName2(3); } catch(std::exception & ex) {