From b44d560685a5684cdbaffd442ae67084565d2a26 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Thu, 16 Aug 2012 15:21:46 +0000 Subject: [PATCH] [0.2.x] added : findSymbol routine git-svn-id: https://pykd.svn.codeplex.com/svn@78885 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dia/diawrapper.cpp | 89 ++++++++++++++++++++++++++++++++--------- pykd/dia/diawrapper.h | 22 +++++----- pykd/module.cpp | 33 +++++++++++++-- pykd/module.h | 5 ++- pykd/pymod.cpp | 12 ++++-- pykd/symengine.h | 5 ++- pykd/typeinfo.cpp | 9 +++++ pykd/typeinfo.h | 3 ++ samples/km/drvobj.py | 2 +- samples/km/ssdt.py | 2 +- snippets/wfp.py | 11 ++++- 11 files changed, 150 insertions(+), 43 deletions(-) diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp index 2a6b719..bc05b58 100644 --- a/pykd/dia/diawrapper.cpp +++ b/pykd/dia/diawrapper.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" +#include "dbghelp.h" #include "dia/diawrapper.h" #include "win/utils.h" @@ -125,7 +126,7 @@ SymbolPtrList DiaSymbol::findChildren( hres = m_symbol->findChildren( static_cast(symTag), NULL, - caseSensitive ? nsCaseSensitive : nsCaseInsensitive, + (caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName, &symbols); } @@ -134,7 +135,7 @@ SymbolPtrList DiaSymbol::findChildren( hres = m_symbol->findChildren( static_cast(symTag), toWStr(name), - caseSensitive ? nsCaseSensitive : nsCaseInsensitive, + (caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName, &symbols); } @@ -177,7 +178,7 @@ ULONG DiaSymbol::getChildCount(ULONG symTag) m_symbol->findChildren( static_cast(symTag), NULL, - nsCaseSensitive, + nsfCaseSensitive | nsfUndecoratedName, &symbols); if (S_OK != hres) throw DiaException("Call IDiaSymbol::findChildren", hres); @@ -199,7 +200,7 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index ) m_symbol->findChildren( static_cast(symTag), NULL, - nsCaseSensitive, + nsfCaseSensitive | nsfUndecoratedName, &symbols); if (S_OK != hres) throw DiaException("Call IDiaSymbol::findChildren", hres); @@ -224,36 +225,67 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index ) //////////////////////////////////////////////////////////////////////////////// -SymbolPtr DiaSymbol::getChildByName(const std::string &_name) +SymbolPtr DiaSymbol::getChildByName(const std::string &name ) { DiaEnumSymbolsPtr symbols; HRESULT hres = m_symbol->findChildren( ::SymTagNull, - toWStr(_name), - nsCaseSensitive, + toWStr(name), + nsfCaseSensitive | nsfUndecoratedName, &symbols); - if (S_OK != hres) - throw DiaException("Call IDiaSymbol::findChildren", hres); - LONG count; hres = symbols->get_Count(&count); if (S_OK != hres) throw DiaException("Call IDiaEnumSymbols::get_Count", hres); - if (!count) - throw DiaException(_name + " not found"); + if (count >0 ) + { + DiaSymbolPtr child; + hres = symbols->Item(0, &child); + if (S_OK != hres) + throw DiaException("Call IDiaEnumSymbols::Item", hres); - if (count != 1) - throw DiaException(_name + " is not unique"); + return SymbolPtr( new DiaSymbol(child) ); + } + + std::string pattern = "*"; + pattern += name; + pattern += "*"; + symbols = 0; + + hres = + m_symbol->findChildren( + ::SymTagNull, + toWStr(pattern), + nsfRegularExpression | nsfCaseSensitive | nsfUndecoratedName, + &symbols); - DiaSymbolPtr child; - hres = symbols->Item(0, &child); if (S_OK != hres) - throw DiaException("Call IDiaEnumSymbols::Item", hres); + throw DiaException("Call IDiaSymbol::findChildren", hres); - return SymbolPtr( new DiaSymbol(child) ); + hres = symbols->get_Count(&count); + if (S_OK != hres) + throw DiaException("Call IDiaEnumSymbols::get_Count", hres); + + if (count == 0) + throw DiaException( name + " not found"); + + for ( LONG i = 0; i < count; ++i ) + { + DiaSymbolPtr child; + hres = symbols->Item(i, &child); + if (S_OK != hres) + throw DiaException("Call IDiaEnumSymbols::Item", hres); + + SymbolPtr symPtr = SymbolPtr( new DiaSymbol(child) ); + + if ( name == symPtr->getName() ) + return symPtr; + } + + throw DiaException(name + " is not found"); } ////////////////////////////////////////////////////////////////////////////// @@ -279,12 +311,31 @@ ULONG DiaSymbol::getLocType() ////////////////////////////////////////////////////////////////////////////// +static const boost::regex stdcallMatch("^_(\\w+)@.+$"); + std::string DiaSymbol::getName() { autoBstr retValue( callSymbol(get_name) ); + + boost::cmatch matchResult; + + std::string retStr = retValue.asStr(); + + if ( boost::regex_match( retStr.c_str(), matchResult, stdcallMatch ) ) + retStr= std::string( matchResult[1].first, matchResult[1].second ); + + return retStr; +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string DiaSymbol::getUndecoratedName() +{ + autoBstr retValue( callSymbol(get_undecoratedName) ); return retValue.asStr(); } -//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// LONG DiaSymbol::getOffset() { diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h index 2ab2697..541aeba 100644 --- a/pykd/dia/diawrapper.h +++ b/pykd/dia/diawrapper.h @@ -14,6 +14,7 @@ typedef CComPtr< IDiaSymbol > DiaSymbolPtr; typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr; typedef CComPtr< IDiaDataSource > DiaDataSourcePtr; typedef CComPtr< IDiaSession > DiaSessionPtr; +typedef CComPtr< IDiaEnumSymbolsByAddr > DiaEnumSymbolsByAddrPtr; ////////////////////////////////////////////////////////////////////////////// @@ -52,7 +53,7 @@ public: DiaSymbol( IDiaSymbol *_symbol ); - SymbolPtr getChildByName(const std::string &_name); + SymbolPtr getChildByName(const std::string &_name ); ULONG getRva(); @@ -82,7 +83,7 @@ public: std::string getName(); - //std::string getUndecoratedName(); + std::string getUndecoratedName(); SymbolPtr getType(); @@ -90,7 +91,6 @@ public: ULONG getSymTag(); - //ULONG getRva(); ULONGLONG getVa(); ULONG getLocType(); @@ -237,20 +237,24 @@ class DiaSession : public SymbolSession public: DiaSession( IDiaSession* session, IDiaSymbol *globalScope ) : - m_globalScope( new DiaSymbol( globalScope ) ), - m_session( session ) + m_globalScope( globalScope ), + m_session( session ), + m_globalSymbol( new DiaSymbol( globalScope ) ) {} SymbolPtr& getSymbolScope() { - return m_globalScope; + return m_globalSymbol; } - SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagData, LONG* displacement = NULL ); + SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL ); + + ULONG findRvaByName( const std::string &name ); private: - SymbolPtr m_globalScope; - DiaSessionPtr m_session; + DiaSymbolPtr m_globalScope; + SymbolPtr m_globalSymbol; + DiaSessionPtr m_session; }; diff --git a/pykd/module.cpp b/pykd/module.cpp index c882b29..3533c17 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -26,6 +26,7 @@ Module::Module(const std::string &moduleName ) m_imageName = getModuleImageName( m_base ); m_timeDataStamp = getModuleTimeStamp( m_base ); m_checkSum = getModuleCheckSum( m_base ); + m_size = getModuleSize( m_base ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -38,6 +39,7 @@ Module::Module(ULONG64 offset ) m_imageName = getModuleImageName( m_base ); m_timeDataStamp = getModuleTimeStamp( m_base ); m_checkSum = getModuleCheckSum( m_base ); + m_size = getModuleSize( m_base ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -81,9 +83,8 @@ void Module::reloadSymbols() ULONG Module::getRvaByName(const std::string &symName) { - SymbolPtr &symScope = getSymScope(); - SymbolPtr child = symScope->getChildByName( symName ); - return child->getRva(); + SymbolPtr sym = getSymScope()->getChildByName( symName ); + return sym->getRva(); } ///////////////////////////////////////////////////////////////////////////////////// @@ -151,7 +152,7 @@ Module::getTypedVarByName( const std::string &symName ) if ( LocIsConstant != symVar->getLocType() ) { - ULONG64 offset = getSymbol( symName ); + ULONG64 offset = getSymbolOffset( symName ); return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) ); } @@ -202,6 +203,30 @@ SymbolPtr Module::getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacment return getSymSession()->findByRva( (ULONG)(offset - m_base ), symTag, displacment ); } +/////////////////////////////////////////////////////////////////////////////////// + +std::string Module::getSymbolNameByVa( ULONG64 offset ) +{ + offset = addr64(offset); + + if ( offset < m_base || offset > getEnd() ) + throw DbgException( "address is out of the module space" ); + + LONG displacement = 0; + + SymbolPtr sym = getSymSession()->findByRva( (ULONG)(offset - m_base ), SymTagNull, &displacement ); + + std::stringstream sstr; + + sstr << sym->getName(); + + if ( displacement > 0 ) + sstr << '+' << std::hex << displacement; + else if ( displacement < 0 ) + sstr << '-' << std::hex << -displacement; + + return sstr.str(); +} /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/module.h b/pykd/module.h index d317dc3..d07d64b 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -58,10 +58,11 @@ public: reloadSymbols(); ULONG64 - getSymbol( const std::string &symbolname ) { + getSymbolOffset( const std::string &symbolname ) { return m_base + getRvaByName(symbolname); } + ULONG getSymbolRva( const std::string &symbolname ) { return getRvaByName(symbolname); @@ -95,6 +96,8 @@ public: SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt ); + std::string getSymbolNameByVa( ULONG64 offset ); + std::string print(); private: diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 65c85ea..841dc13 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -156,7 +156,9 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "loadPtrs", &loadPtrArray, "Read the block of the target's memory and return it as a list of pointers" ); - // typed and vaiables + // types and vaiables + python::def( "findSymbol", &TypeInfo::findSymbol, + "Find symbol by the target virtual memory offset" ); python::def( "sizeof", &TypeInfo::getSymbolSize, "Return a size of the type or variable" ); python::def("typedVarList", &getTypedVarListByTypeName, @@ -250,11 +252,13 @@ BOOST_PYTHON_MODULE( pykd ) "Return name of the image of the module" ) .def("symfile", &Module::getSymFile, "Return the full path to the module's symbol information" ) - .def("offset", &Module::getSymbol, + .def("offset", &Module::getSymbolOffset, "Return offset of the symbol" ) + .def("findSymbol", &Module::getSymbolNameByVa, + "Return symbol name by offset" ) .def("rva", &Module::getSymbolRva, "Return rva of the symbol" ) - .def( "sizeof", &Module::getSymbolSize, + .def("sizeof", &Module::getSymbolSize, "Return a size of the type or variable" ) .def("type", &Module::getTypeByName, "Return typeInfo class by type name" ) @@ -275,7 +279,7 @@ BOOST_PYTHON_MODULE( pykd ) "Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" ) .def("timestamp",&Module::getTimeDataStamp, "Return a low 32 bits of the time stamp of the image: IMAGE_FILE_HEADER.TimeDateStamp" ) - .def("__getattr__", &Module::getSymbol, + .def("__getattr__", &Module::getSymbolOffset, "Return address of the symbol" ) .def( "__str__", &Module::print ); diff --git a/pykd/symengine.h b/pykd/symengine.h index 659a76a..518e2c4 100644 --- a/pykd/symengine.h +++ b/pykd/symengine.h @@ -119,7 +119,7 @@ public: virtual ULONG getBaseType() = 0; virtual ULONG getBitPosition() = 0; virtual SymbolPtr getChildByIndex(ULONG _index ) = 0; - virtual SymbolPtr getChildByName(const std::string &_name) = 0; + virtual SymbolPtr getChildByName(const std::string &_name ) = 0; virtual ULONG getChildCount() = 0; virtual ULONG getChildCount(ULONG symTag ) = 0; virtual ULONG getCount() = 0; @@ -132,6 +132,7 @@ public: virtual ULONGLONG getSize() = 0; virtual ULONG getSymTag() = 0; virtual SymbolPtr getType() = 0; + virtual std::string getUndecoratedName() = 0; virtual ULONGLONG getVa() = 0; virtual void getValue( BaseTypeVariant &vtValue) = 0; virtual ULONG getVirtualBaseDispIndex() = 0; @@ -148,7 +149,7 @@ public: virtual SymbolPtr& getSymbolScope() = 0; - virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagData, LONG* displacement = NULL ) = 0; + virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL ) = 0; }; diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index 977ac41..6c9c334 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -74,6 +74,15 @@ ULONG64 TypeInfo::getSymbolSize( const std::string &fullName ) ///////////////////////////////////////////////////////////////////////////////////// +std::string TypeInfo::findSymbol( ULONG64 offset ) +{ + ModulePtr module = Module::loadModuleByOffset( offset ); + + return module->getName() + '!' + module->getSymbolNameByVa( offset ); +} + +///////////////////////////////////////////////////////////////////////////////////// + TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym ) { ULONG symTag = typeSym->getSymTag(); diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index b59318b..83551e4 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -28,6 +28,9 @@ public: static ULONG64 getSymbolSize( const std::string &symName ); + static + std::string findSymbol( ULONG64 offset ); + static TypeInfoPtr getTypeInfo( SymbolPtr &symScope, const std::string &symName ); diff --git a/samples/km/drvobj.py b/samples/km/drvobj.py index bb5f4a1..6048acf 100644 --- a/samples/km/drvobj.py +++ b/samples/km/drvobj.py @@ -4,7 +4,7 @@ import sys def loadSymbols(): global nt - nt = loadModule( "nt" ) + nt = module( "nt" ) def getObjNameFromObjHeader( objHeader ): diff --git a/samples/km/ssdt.py b/samples/km/ssdt.py index b4c9d56..7ac0b40 100644 --- a/samples/km/ssdt.py +++ b/samples/km/ssdt.py @@ -3,7 +3,7 @@ import sys def checkSSDT(): - nt = loadModule( "nt" ) + nt = module( "nt" ) if is64bitSystem(): diff --git a/snippets/wfp.py b/snippets/wfp.py index 10fc463..d1b4d3a 100644 --- a/snippets/wfp.py +++ b/snippets/wfp.py @@ -19,8 +19,14 @@ def printBlob( blob ): if i == 0: str += "\n" str += "\n" + str += "As string: " + loadWStr(blob.data ) + str += "\n" + return str +def printArray16( array16 ): + return " ".join( [ "%02x"%v for v in array16.byteArray16 ] ) + def printFwpsValue( value ): return { "FWP_UINT8" : lambda : "%#x" % value.uint8, @@ -32,8 +38,9 @@ def printFwpsValue( value ): "FWP_INT32" : lambda : "%#x" % value.int32, "FWP_INT64" : lambda : "%#x" % value.int64.deref(), "FWP_BYTE_BLOB_TYPE" : lambda : printBlob( value.byteBlob.deref() ), + "FWP_BYTE_ARRAY16_TYPE" : lambda : printArray16( value.byteArray16.deref() ) - }.get( fwpsDataType[ value.type ], lambda : "---" )() + }.get( fwpsDataType[ value.field("type") ], lambda : "---" )() def wfpFixedValues( addr ): @@ -56,7 +63,7 @@ def wfpFixedValues( addr ): for i in range( 0, len(values) ): dprintln( " " + fwpsFields[ i ] ) - dprintln( " Type: " + fwpsDataType[ values[i].type ] ) + dprintln( " Type: " + fwpsDataType[ values[i].field("type") ] ) dprintln( " Value: " + printFwpsValue( values[i] ) ) def printDiscardReason( discardReason ):