diff --git a/pykd/module.cpp b/pykd/module.cpp index ae6bc89..9ab5072 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -287,7 +287,7 @@ SymbolPtr Module::getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacment } /////////////////////////////////////////////////////////////////////////////////// -std::string Module::getSymbolNameByVa( ULONG64 offset ) +std::string Module::getSymbolNameByVa( ULONG64 offset, bool showDisplacement ) { offset = addr64(offset); @@ -302,10 +302,13 @@ std::string Module::getSymbolNameByVa( ULONG64 offset ) sstr << sym->getName(); - if ( displacement > 0 && displacement ) - sstr << '+' << std::hex << displacement; - else if ( displacement < 0 ) - sstr << '-' << std::hex << -displacement; + if ( showDisplacement ) + { + if ( displacement > 0 && displacement ) + 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 946774a..39a8747 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -125,7 +125,7 @@ public: SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt = NULL ); - std::string getSymbolNameByVa( ULONG64 offset ); + std::string getSymbolNameByVa( ULONG64 offset, bool showDisplacement = true ); void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ); diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 1a5f4c7..fb14efc 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -66,6 +66,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfo::findSymbol, 1, 2 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumTypes, Module::enumTypes, 0, 1 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 ); BOOST_PYTHON_MODULE( pykd ) @@ -208,7 +209,7 @@ BOOST_PYTHON_MODULE( pykd ) "Return source file name, line and displacement by the specified offset" ) ); python::def( "getOffset", &TypeInfo::getOffset, "Return traget virtual address for specified symbol" ); - python::def( "findSymbol", &TypeInfo::findSymbol, findSymbol_( python::args( "offset", "safe"), + python::def( "findSymbol", &TypeInfo::findSymbol, findSymbol_( python::args( "offset", "safe", "showDisplacement"), "Find symbol by the target virtual memory offset" ) ); python::def( "sizeof", &TypeInfo::getSymbolSize, "Return a size of the type or variable" ); @@ -350,8 +351,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return the full path to the module's symbol information" ) .def("offset", &Module::getSymbolOffset, "Return offset of the symbol" ) - .def("findSymbol", &Module::getSymbolNameByVa, - "Return symbol name by virtual address" ) + .def("findSymbol", &Module::getSymbolNameByVa, Module_findSymbol( python::args("offset", "showDisplacement"), + "Return symbol name by virtual address" ) ) .def("rva", &Module::getSymbolRva, "Return rva of the symbol" ) .def("sizeof", &Module::getSymbolSize, diff --git a/snippets/stkdelta.py b/snippets/stkdelta.py index be63d66..499d60c 100644 --- a/snippets/stkdelta.py +++ b/snippets/stkdelta.py @@ -30,19 +30,21 @@ def printDeltaStat(): for i in range( 0, len(stk) -1 ): try: - mname = module( stk[i].returnOffset ).name() + mod = module( stk[i].returnOffset ) except BaseException: continue delta = stk[i+1].frameOffset - stk[i].frameOffset if delta > 0: - if mname in moduleLst: - moduleLst[mname] = moduleLst[mname] + delta + moduleName = mod.name() + + if moduleName in moduleLst: + moduleLst[moduleName] = moduleLst[moduleName] + delta else: - moduleLst[mname] = delta + moduleLst[moduleName] = delta - func = findSymbol( stk[i].returnOffset ) + func = moduleName + "!" + mod.findSymbol( stk[i].returnOffset, showDisplacement = False ) if func in funcLst: funcLst[func] = funcLst[func] + delta @@ -79,7 +81,11 @@ def printDeltaStack(): for i in range( 0, len(stk) -1 ): dprint( "%12s\t" % long( stk[i+1].frameOffset - stk[i].frameOffset) ) - dprintln( findSymbol( stk[i].returnOffset ) ) + try: + mod = module( stk[i].returnOffset ) + dprintln( "%s!%s"% ( mod.name(), mod.findSymbol( stk[i].returnOffset, showDisplacement = False ) ) ) + except BaseException: + dprintln( findSymbol( stk[i].returnOffset ) ) def main(): diff --git a/snippets/stkwalk.py b/snippets/stkwalk.py index 5176e8e..c28abf2 100644 --- a/snippets/stkwalk.py +++ b/snippets/stkwalk.py @@ -2,6 +2,8 @@ from pykd import * from optparse import OptionParser from fnmatch import fnmatch +import traceback +import sys nt = None @@ -9,27 +11,30 @@ class PrintOptions: def __init__(self): self.ignoreNotActiveThread = True self.ignoreNotActiveProcess = True + self.showWow64stack = True -def applayThreadFilter( thread,moduleFilter): +def applayThreadFilter(thread,moduleFilter,funcFilter,printopt): + + if not moduleFilter and not funcFilter: + return True try: setImplicitThread(thread) - + stk = getStack() - moduleLst = set() for frame in stk: m = module( frame.instructionOffset ) - if moduleFilter( m, m.name() ): - moduleLst.add(m) - - if len(moduleLst)==0: - return False + if moduleFilter and moduleFilter( m, m.name() ): + return True + sym = m.findSymbol( frame.instructionOffset, showDisplacement = False ) + if funcFilter and funcFilter( sym ): + return True except BaseException: - return False + pass - return True + return False def printThread(process,thread,printopt): @@ -53,11 +58,11 @@ def printThread(process,thread,printopt): -def printProcess(process,processFilter,moduleFilter,printopt): +def printProcess(process,processFilter,moduleFilter,funcFilter,printopt): processName = loadCStr( process.ImageFileName ) - if not processFilter(process, process.UniqueProcessId, processName ): + if processFilter and not processFilter(process, process.UniqueProcessId, processName ): return try: @@ -68,7 +73,7 @@ def printProcess(process,processFilter,moduleFilter,printopt): threadLst = nt.typedVarList(process.ThreadListHead, "_ETHREAD", "ThreadListEntry") filteredThreadLst = [] for thread in threadLst: - if applayThreadFilter( thread, moduleFilter ): + if applayThreadFilter( thread, moduleFilter, funcFilter, printopt ): filteredThreadLst.append( thread ) if filteredThreadLst == []: @@ -104,18 +109,25 @@ def main(): help="process filter: boolean expression with python syntax" ) parser.add_option("-m", "--module", dest="modulefilter", help="module filter: boolean expression with python syntax" ) + parser.add_option("-f", "--function", dest="funcfilter", + help="function filter: boolean expression with python syntax" ) + (options, args) = parser.parse_args() - processFilter = lambda process, pid, name: True - moduleFilter = lambda module, name: True - + processFilter = None + moduleFilter = None + funcFilter = None + if options.processfilter: processFilter = lambda process, pid, name: eval( options.processfilter ) if options.modulefilter: moduleFilter = lambda module, name: eval(options.modulefilter) + if options.funcfilter: + funcFilter = lambda name: eval( options.funcfilter) + printopt = PrintOptions() currentProcess = getCurrentProcess() @@ -123,7 +135,7 @@ def main(): processLst = nt.typedVarList( nt.PsActiveProcessHead, "_EPROCESS", "ActiveProcessLinks") for process in processLst: - printProcess( process, processFilter, moduleFilter, printopt ) + printProcess( process, processFilter, moduleFilter, funcFilter, printopt ) setCurrentProcess(currentProcess) setImplicitThread(currentThread) diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index 729999e..83c2f05 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -52,7 +52,9 @@ class ModuleTest( unittest.TestCase ): def testFindSymbol( self ): self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) ) self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) ) - # self.assertEqual( "", typed) + + self.assertEqual( "_FuncWithName2+10", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) + self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) def testType( self ):