From 82559bc810126befac784c0f1cc833cabbdd7384 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 25 Dec 2013 17:03:06 +0000 Subject: [PATCH] [0.3.x] added : getParam and getParams routines git-svn-id: https://pykd.svn.codeplex.com/svn@86949 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/pycpucontext.cpp | 68 ++++++++++++++++++++++++++++++++++++--- pykd/pycpucontext.h | 35 ++++++++++++++------ pykd/pymod.cpp | 42 +++++++++++++++--------- test/scripts/stacktest.py | 10 +++++- 4 files changed, 124 insertions(+), 31 deletions(-) diff --git a/pykd/pycpucontext.cpp b/pykd/pycpucontext.cpp index e1256f3..15141a0 100644 --- a/pykd/pycpucontext.cpp +++ b/pykd/pycpucontext.cpp @@ -59,20 +59,78 @@ python::list CPUContextAdapter::getStack( kdlib::CPUContextPtr& cpu ) /////////////////////////////////////////////////////////////////////////////// -std::wstring StackFrameAdapter::print( kdlib::StackFrame& frame ) +std::wstring StackFrameAdapter::print( kdlib::StackFramePtr& frame ) { AutoRestorePyState pystate; std::wstringstream sstr; sstr << L"Frame: "; - sstr << L"IP=" << std::hex << frame.getIP() << L" "; - sstr << L"Return=" << std::hex << frame.getRET() << L" "; - sstr << L"Frame Offset=" << std::hex << frame.getFP() << L" "; - sstr << L"Stack Offset=" << std::hex << frame.getSP(); + sstr << L"IP=" << std::hex << frame->getIP() << L" "; + sstr << L"Return=" << std::hex << frame->getRET() << L" "; + sstr << L"Frame Offset=" << std::hex << frame->getFP() << L" "; + sstr << L"Stack Offset=" << std::hex << frame->getSP(); return sstr.str(); } /////////////////////////////////////////////////////////////////////////////// +python::list StackFrameAdapter::getParamsList( kdlib::StackFramePtr& frame) +{ + typedef std::vector< std::pair< std::wstring, kdlib::TypedVarPtr> > FuncParamList; + + FuncParamList paramLst; + unsigned long paramCount; + + do { + AutoRestorePyState pystate; + paramCount = frame->getTypedParamCount(); + for ( unsigned long i = 0; i < paramCount; ++i ) + { + kdlib::TypedVarPtr param = frame->getTypedParam(i); + std::wstring paramName = frame->getTypedParamName(i); + + paramLst.push_back( std::make_pair( paramName, param) ); + } + } while(false); + + python::list pyLst; + + for ( unsigned long i = 0; i < paramCount; ++i ) + pyLst.append( python::make_tuple( paramLst[i].first, paramLst[i].second ) ); + + return pyLst; +} + +/////////////////////////////////////////////////////////////////////////////// + +python::dict StackFrameAdapter::getParamsDict( kdlib::StackFramePtr& frame) +{ + typedef std::vector< std::pair< std::wstring, kdlib::TypedVarPtr> > FuncParamList; + + FuncParamList paramLst; + unsigned long paramCount; + + do { + AutoRestorePyState pystate; + paramCount = frame->getTypedParamCount(); + for ( unsigned long i = 0; i < paramCount; ++i ) + { + kdlib::TypedVarPtr param = frame->getTypedParam(i); + std::wstring paramName = frame->getTypedParamName(i); + + paramLst.push_back( std::make_pair( paramName, param) ); + } + } while(false); + + python::dict pyLst; + + for ( unsigned long i = 0; i < paramCount; ++i ) + pyLst[paramLst[i].first] = paramLst[i].second; + + return pyLst; +} + +/////////////////////////////////////////////////////////////////////////////// + } // end namespace pykd diff --git a/pykd/pycpucontext.h b/pykd/pycpucontext.h index ca16084..60711b7 100644 --- a/pykd/pycpucontext.h +++ b/pykd/pycpucontext.h @@ -17,31 +17,41 @@ class StackFrameAdapter { public: - static kdlib::MEMOFFSET_64 getIP( kdlib::StackFrame& frame ) + static kdlib::MEMOFFSET_64 getIP( kdlib::StackFramePtr& frame ) { AutoRestorePyState pystate; - return frame.getIP(); + return frame->getIP(); } - static kdlib::MEMOFFSET_64 getRET( kdlib::StackFrame& frame ) + static kdlib::MEMOFFSET_64 getRET( kdlib::StackFramePtr& frame ) { AutoRestorePyState pystate; - return frame.getRET(); + return frame->getRET(); } - static kdlib::MEMOFFSET_64 getFP( kdlib::StackFrame& frame ) + static kdlib::MEMOFFSET_64 getFP( kdlib::StackFramePtr& frame ) { AutoRestorePyState pystate; - return frame.getFP(); + return frame->getFP(); } - static kdlib::MEMOFFSET_64 getSP( kdlib::StackFrame& frame ) + static kdlib::MEMOFFSET_64 getSP( kdlib::StackFramePtr& frame ) { AutoRestorePyState pystate; - return frame.getSP(); + return frame->getSP(); } - static std::wstring print( kdlib::StackFrame& frame ); + static std::wstring print( kdlib::StackFramePtr& frame ); + + static python::list getParamsList( kdlib::StackFramePtr& frame); + + static python::dict getParamsDict( kdlib::StackFramePtr& frame); + + static kdlib::TypedVarPtr getParam( kdlib::StackFramePtr& frame, const std::wstring ¶mName ) + { + AutoRestorePyState pystate; + return frame->getTypedParam(paramName); + } }; /////////////////////////////////////////////////////////////////////////////// @@ -94,6 +104,13 @@ inline kdlib::StackFramePtr getCurrentFrame() { return kdlib::getStack()->getFrame(0); } +inline python::list getParams() { + return StackFrameAdapter::getParamsList( getCurrentFrame() ); +} + +inline kdlib::TypedVarPtr getParam( const std::wstring &name ) { + return StackFrameAdapter::getParam( getCurrentFrame(), name ); +} class CPUContextAdapter { diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 4155bcc..9e9c548 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -289,8 +289,6 @@ BOOST_PYTHON_MODULE( pykd ) python::def("containingRecord", pykd::containingRecordByType, "Return instance of the typedVar class. It's value are loaded from the target memory." "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" ); - //python::def("createStruct", &kdlib::defineStruct, - // "Return custom defined struct" ); python::def( "createStruct", &pykd::defineStruct, createStruct_( python::args( "name", "align" ), "Create custom struct" ) ); python::def( "createUnion", &pykd::defineUnion, createUnion_( python::args( "name", "align" ), @@ -317,16 +315,14 @@ BOOST_PYTHON_MODULE( pykd ) "Return a current stack as a list of stackFrame objects" ); python::def( "getFrame", pykd::getCurrentFrame, "Return a current stack frame" ); - - // python::def( "getStackWow64", &getCurrentStackWow64, // "Return a stack for wow64 context as a list of stackFrame objects" ); - // python::def( "getFrame", &getCurrentStackFrame, - // "Return a current stack frame" ); // python::def( "getLocals", &getLocals, // "Get list of local variables" ); - // python::def( "getParams", &getParams, - // "Get list of function arguments" ); + python::def( "getParams", pykd::getParams, + "Get list of function arguments as list of tuple (name, value ) " ); + python::def( "getParam", pykd::getParam, + "Get the function argument by name" ); // breakpoints python::def( "setBp", pykd::softwareBreakPointSet, @@ -599,14 +595,28 @@ BOOST_PYTHON_MODULE( pykd ) python::class_( "stackFrame", "class for stack's frame representation", python::no_init ) - .add_property( "ip", StackFrameAdapter::getIP, "instruction pointer" ) - .add_property( "instructionOffset", StackFrameAdapter::getIP, "Return a frame's instruction offset" ) - .add_property( "ret",StackFrameAdapter::getRET, "return pointer" ) - .add_property( "returnOffset",StackFrameAdapter::getRET, "Return a frame's return offset" ) - .add_property( "fp", StackFrameAdapter::getFP, "frame pointer" ) - .add_property( "frameOffset",StackFrameAdapter::getFP, "Return a frame's offset" ) - .add_property( "sp", StackFrameAdapter::getSP, "stack pointer" ) - .add_property( "stackOffset", StackFrameAdapter::getSP, "Return a frame's stack offset" ) + .add_property( "ip", StackFrameAdapter::getIP, + "instruction pointer" ) + .add_property( "instructionOffset", StackFrameAdapter::getIP, + "Return a frame's instruction offset" ) + .add_property( "ret",StackFrameAdapter::getRET, + "return pointer" ) + .add_property( "returnOffset",StackFrameAdapter::getRET, + "Return a frame's return offset" ) + .add_property( "fp", StackFrameAdapter::getFP, + "frame pointer" ) + .add_property( "frameOffset",StackFrameAdapter::getFP, + "Return a frame's offset" ) + .add_property( "sp", StackFrameAdapter::getSP, + "stack pointer" ) + .add_property( "stackOffset", StackFrameAdapter::getSP, + "Return a frame's stack offset" ) + .def( "getParams", StackFrameAdapter::getParamsList, + "return set of function's parameters as a list of tuple (name, value ) ") + .add_property( "params", StackFrameAdapter::getParamsDict, + "return set of function's parameters as a dict (name : value)") + .def( "getParam", StackFrameAdapter::getParam, + "return function param by it's name") .def( "__str__", StackFrameAdapter::print ); python::class_( "cpu", diff --git a/test/scripts/stacktest.py b/test/scripts/stacktest.py index 7e37169..7ef15bc 100644 --- a/test/scripts/stacktest.py +++ b/test/scripts/stacktest.py @@ -29,4 +29,12 @@ class StackTest(unittest.TestCase): self.assertEqual( expectedStack, realStack ) - + def testGetParams(self): + expectedParams = ["a", "b", "c"] + self.assertEqual( expectedParams, [ name for name, param in pykd.getParams()] ) + self.assertEqual( 10, dict(pykd.getParams())["a"].deref() ) + self.assertEqual( 10, pykd.getParam("a").deref() ) + + self.assertEqual( 10, pykd.getStack()[1].params["a"] ) + self.assertEqual( 10, pykd.getStack()[1].getParam("a") ) + self.assertEqual( 10, dict( pykd.getStack()[1].getParams() )["a"] )