[0.2.x] added : findSymbol routine

git-svn-id: https://pykd.svn.codeplex.com/svn@78885 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-08-16 15:21:46 +00:00 committed by Mikhail I. Izmestev
parent deedfd94e0
commit b44d560685
11 changed files with 150 additions and 43 deletions

View File

@ -1,5 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "dbghelp.h"
#include "dia/diawrapper.h" #include "dia/diawrapper.h"
#include "win/utils.h" #include "win/utils.h"
@ -125,7 +126,7 @@ SymbolPtrList DiaSymbol::findChildren(
hres = m_symbol->findChildren( hres = m_symbol->findChildren(
static_cast<enum ::SymTagEnum>(symTag), static_cast<enum ::SymTagEnum>(symTag),
NULL, NULL,
caseSensitive ? nsCaseSensitive : nsCaseInsensitive, (caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName,
&symbols); &symbols);
} }
@ -134,7 +135,7 @@ SymbolPtrList DiaSymbol::findChildren(
hres = m_symbol->findChildren( hres = m_symbol->findChildren(
static_cast<enum ::SymTagEnum>(symTag), static_cast<enum ::SymTagEnum>(symTag),
toWStr(name), toWStr(name),
caseSensitive ? nsCaseSensitive : nsCaseInsensitive, (caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName,
&symbols); &symbols);
} }
@ -177,7 +178,7 @@ ULONG DiaSymbol::getChildCount(ULONG symTag)
m_symbol->findChildren( m_symbol->findChildren(
static_cast<enum ::SymTagEnum>(symTag), static_cast<enum ::SymTagEnum>(symTag),
NULL, NULL,
nsCaseSensitive, nsfCaseSensitive | nsfUndecoratedName,
&symbols); &symbols);
if (S_OK != hres) if (S_OK != hres)
throw DiaException("Call IDiaSymbol::findChildren", hres); throw DiaException("Call IDiaSymbol::findChildren", hres);
@ -199,7 +200,7 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
m_symbol->findChildren( m_symbol->findChildren(
static_cast<enum ::SymTagEnum>(symTag), static_cast<enum ::SymTagEnum>(symTag),
NULL, NULL,
nsCaseSensitive, nsfCaseSensitive | nsfUndecoratedName,
&symbols); &symbols);
if (S_OK != hres) if (S_OK != hres)
throw DiaException("Call IDiaSymbol::findChildren", 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; DiaEnumSymbolsPtr symbols;
HRESULT hres = HRESULT hres =
m_symbol->findChildren( m_symbol->findChildren(
::SymTagNull, ::SymTagNull,
toWStr(_name), toWStr(name),
nsCaseSensitive, nsfCaseSensitive | nsfUndecoratedName,
&symbols); &symbols);
if (S_OK != hres)
throw DiaException("Call IDiaSymbol::findChildren", hres);
LONG count; LONG count;
hres = symbols->get_Count(&count); hres = symbols->get_Count(&count);
if (S_OK != hres) if (S_OK != hres)
throw DiaException("Call IDiaEnumSymbols::get_Count", hres); throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
if (!count) if (count >0 )
throw DiaException(_name + " not found"); {
DiaSymbolPtr child;
hres = symbols->Item(0, &child);
if (S_OK != hres)
throw DiaException("Call IDiaEnumSymbols::Item", hres);
if (count != 1) return SymbolPtr( new DiaSymbol(child) );
throw DiaException(_name + " is not unique"); }
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) 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() std::string DiaSymbol::getName()
{ {
autoBstr retValue( callSymbol(get_name) ); 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(); return retValue.asStr();
} }
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
LONG DiaSymbol::getOffset() LONG DiaSymbol::getOffset()
{ {

View File

@ -14,6 +14,7 @@ typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr; typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr; typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
typedef CComPtr< IDiaSession > DiaSessionPtr; typedef CComPtr< IDiaSession > DiaSessionPtr;
typedef CComPtr< IDiaEnumSymbolsByAddr > DiaEnumSymbolsByAddrPtr;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -52,7 +53,7 @@ public:
DiaSymbol( IDiaSymbol *_symbol ); DiaSymbol( IDiaSymbol *_symbol );
SymbolPtr getChildByName(const std::string &_name); SymbolPtr getChildByName(const std::string &_name );
ULONG getRva(); ULONG getRva();
@ -82,7 +83,7 @@ public:
std::string getName(); std::string getName();
//std::string getUndecoratedName(); std::string getUndecoratedName();
SymbolPtr getType(); SymbolPtr getType();
@ -90,7 +91,6 @@ public:
ULONG getSymTag(); ULONG getSymTag();
//ULONG getRva();
ULONGLONG getVa(); ULONGLONG getVa();
ULONG getLocType(); ULONG getLocType();
@ -237,20 +237,24 @@ class DiaSession : public SymbolSession
public: public:
DiaSession( IDiaSession* session, IDiaSymbol *globalScope ) : DiaSession( IDiaSession* session, IDiaSymbol *globalScope ) :
m_globalScope( new DiaSymbol( globalScope ) ), m_globalScope( globalScope ),
m_session( session ) m_session( session ),
m_globalSymbol( new DiaSymbol( globalScope ) )
{} {}
SymbolPtr& getSymbolScope() { 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: private:
SymbolPtr m_globalScope; DiaSymbolPtr m_globalScope;
DiaSessionPtr m_session; SymbolPtr m_globalSymbol;
DiaSessionPtr m_session;
}; };

View File

@ -26,6 +26,7 @@ Module::Module(const std::string &moduleName )
m_imageName = getModuleImageName( m_base ); m_imageName = getModuleImageName( m_base );
m_timeDataStamp = getModuleTimeStamp( m_base ); m_timeDataStamp = getModuleTimeStamp( m_base );
m_checkSum = getModuleCheckSum( 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_imageName = getModuleImageName( m_base );
m_timeDataStamp = getModuleTimeStamp( m_base ); m_timeDataStamp = getModuleTimeStamp( m_base );
m_checkSum = getModuleCheckSum( 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) ULONG Module::getRvaByName(const std::string &symName)
{ {
SymbolPtr &symScope = getSymScope(); SymbolPtr sym = getSymScope()->getChildByName( symName );
SymbolPtr child = symScope->getChildByName( symName ); return sym->getRva();
return child->getRva();
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -151,7 +152,7 @@ Module::getTypedVarByName( const std::string &symName )
if ( LocIsConstant != symVar->getLocType() ) if ( LocIsConstant != symVar->getLocType() )
{ {
ULONG64 offset = getSymbol( symName ); ULONG64 offset = getSymbolOffset( symName );
return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) ); 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 ); 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();
}
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -58,10 +58,11 @@ public:
reloadSymbols(); reloadSymbols();
ULONG64 ULONG64
getSymbol( const std::string &symbolname ) { getSymbolOffset( const std::string &symbolname ) {
return m_base + getRvaByName(symbolname); return m_base + getRvaByName(symbolname);
} }
ULONG ULONG
getSymbolRva( const std::string &symbolname ) { getSymbolRva( const std::string &symbolname ) {
return getRvaByName(symbolname); return getRvaByName(symbolname);
@ -95,6 +96,8 @@ public:
SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt ); SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt );
std::string getSymbolNameByVa( ULONG64 offset );
std::string print(); std::string print();
private: private:

View File

@ -156,7 +156,9 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "loadPtrs", &loadPtrArray, python::def( "loadPtrs", &loadPtrArray,
"Read the block of the target's memory and return it as a list of pointers" ); "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, python::def( "sizeof", &TypeInfo::getSymbolSize,
"Return a size of the type or variable" ); "Return a size of the type or variable" );
python::def("typedVarList", &getTypedVarListByTypeName, python::def("typedVarList", &getTypedVarListByTypeName,
@ -250,11 +252,13 @@ BOOST_PYTHON_MODULE( pykd )
"Return name of the image of the module" ) "Return name of the image of the module" )
.def("symfile", &Module::getSymFile, .def("symfile", &Module::getSymFile,
"Return the full path to the module's symbol information" ) "Return the full path to the module's symbol information" )
.def("offset", &Module::getSymbol, .def("offset", &Module::getSymbolOffset,
"Return offset of the symbol" ) "Return offset of the symbol" )
.def("findSymbol", &Module::getSymbolNameByVa,
"Return symbol name by offset" )
.def("rva", &Module::getSymbolRva, .def("rva", &Module::getSymbolRva,
"Return rva of the symbol" ) "Return rva of the symbol" )
.def( "sizeof", &Module::getSymbolSize, .def("sizeof", &Module::getSymbolSize,
"Return a size of the type or variable" ) "Return a size of the type or variable" )
.def("type", &Module::getTypeByName, .def("type", &Module::getTypeByName,
"Return typeInfo class by type name" ) "Return typeInfo class by type name" )
@ -275,7 +279,7 @@ BOOST_PYTHON_MODULE( pykd )
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" ) "Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
.def("timestamp",&Module::getTimeDataStamp, .def("timestamp",&Module::getTimeDataStamp,
"Return a low 32 bits of the time stamp of the image: IMAGE_FILE_HEADER.TimeDateStamp" ) "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" ) "Return address of the symbol" )
.def( "__str__", &Module::print ); .def( "__str__", &Module::print );

View File

@ -119,7 +119,7 @@ public:
virtual ULONG getBaseType() = 0; virtual ULONG getBaseType() = 0;
virtual ULONG getBitPosition() = 0; virtual ULONG getBitPosition() = 0;
virtual SymbolPtr getChildByIndex(ULONG _index ) = 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() = 0;
virtual ULONG getChildCount(ULONG symTag ) = 0; virtual ULONG getChildCount(ULONG symTag ) = 0;
virtual ULONG getCount() = 0; virtual ULONG getCount() = 0;
@ -132,6 +132,7 @@ public:
virtual ULONGLONG getSize() = 0; virtual ULONGLONG getSize() = 0;
virtual ULONG getSymTag() = 0; virtual ULONG getSymTag() = 0;
virtual SymbolPtr getType() = 0; virtual SymbolPtr getType() = 0;
virtual std::string getUndecoratedName() = 0;
virtual ULONGLONG getVa() = 0; virtual ULONGLONG getVa() = 0;
virtual void getValue( BaseTypeVariant &vtValue) = 0; virtual void getValue( BaseTypeVariant &vtValue) = 0;
virtual ULONG getVirtualBaseDispIndex() = 0; virtual ULONG getVirtualBaseDispIndex() = 0;
@ -148,7 +149,7 @@ public:
virtual SymbolPtr& getSymbolScope() = 0; 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;
}; };

View File

@ -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 ) TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
{ {
ULONG symTag = typeSym->getSymTag(); ULONG symTag = typeSym->getSymTag();

View File

@ -28,6 +28,9 @@ public:
static static
ULONG64 getSymbolSize( const std::string &symName ); ULONG64 getSymbolSize( const std::string &symName );
static
std::string findSymbol( ULONG64 offset );
static static
TypeInfoPtr getTypeInfo( SymbolPtr &symScope, const std::string &symName ); TypeInfoPtr getTypeInfo( SymbolPtr &symScope, const std::string &symName );

View File

@ -4,7 +4,7 @@ import sys
def loadSymbols(): def loadSymbols():
global nt global nt
nt = loadModule( "nt" ) nt = module( "nt" )
def getObjNameFromObjHeader( objHeader ): def getObjNameFromObjHeader( objHeader ):

View File

@ -3,7 +3,7 @@ import sys
def checkSSDT(): def checkSSDT():
nt = loadModule( "nt" ) nt = module( "nt" )
if is64bitSystem(): if is64bitSystem():

View File

@ -19,8 +19,14 @@ def printBlob( blob ):
if i == 0: str += "\n" if i == 0: str += "\n"
str += "\n" str += "\n"
str += "As string: " + loadWStr(blob.data )
str += "\n"
return str return str
def printArray16( array16 ):
return " ".join( [ "%02x"%v for v in array16.byteArray16 ] )
def printFwpsValue( value ): def printFwpsValue( value ):
return { return {
"FWP_UINT8" : lambda : "%#x" % value.uint8, "FWP_UINT8" : lambda : "%#x" % value.uint8,
@ -32,8 +38,9 @@ def printFwpsValue( value ):
"FWP_INT32" : lambda : "%#x" % value.int32, "FWP_INT32" : lambda : "%#x" % value.int32,
"FWP_INT64" : lambda : "%#x" % value.int64.deref(), "FWP_INT64" : lambda : "%#x" % value.int64.deref(),
"FWP_BYTE_BLOB_TYPE" : lambda : printBlob( value.byteBlob.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 ): def wfpFixedValues( addr ):
@ -56,7 +63,7 @@ def wfpFixedValues( addr ):
for i in range( 0, len(values) ): for i in range( 0, len(values) ):
dprintln( " " + fwpsFields[ i ] ) dprintln( " " + fwpsFields[ i ] )
dprintln( " Type: " + fwpsDataType[ values[i].type ] ) dprintln( " Type: " + fwpsDataType[ values[i].field("type") ] )
dprintln( " Value: " + printFwpsValue( values[i] ) ) dprintln( " Value: " + printFwpsValue( values[i] ) )
def printDiscardReason( discardReason ): def printDiscardReason( discardReason ):