From a7e9463dc4e2547d8fca0ae6d7eba238ba865ccd Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Fri, 1 Jun 2012 15:26:51 +0000 Subject: [PATCH] [0.1.x] changed: method __getitem__ (index) of the Context class returns tuple [0.1.x] added: method __getitem__ (regName) of the Context class [0.1.x] added: method __getattr__ (regName) of the Context class [0.1.x] added: method __str__() of the Context class git-svn-id: https://pykd.svn.codeplex.com/svn@76867 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/context.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++- pykd/context.h | 5 ++- pykd/pymod.cpp | 13 ++++++-- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/pykd/context.cpp b/pykd/context.cpp index b90b75f..bcfba71 100644 --- a/pykd/context.cpp +++ b/pykd/context.cpp @@ -2,6 +2,7 @@ #include "stdafx.h" #include +#include #include "context.h" #include "stkframe.h" @@ -145,6 +146,32 @@ ULONG64 ThreadContext::getValue(ULONG cvRegId) const throw DbgException(__FUNCTION__ ": Register missing"); } +///////////////////////////////////////////////////////////////////////////////// + +ULONG64 ThreadContext::getValueByName( const std::string ®Name ) const +{ + std::string upcaseName = boost::to_upper_copy( regName ); + + if ( IMAGE_FILE_MACHINE_I386 == m_processorType ) + { + for ( ULONG i = 0; i < pyDia::Symbol::cntI386RegName; ++i ) + { + if ( upcaseName == pyDia::Symbol::i386RegName[i].second ) + return getValue( pyDia::Symbol::i386RegName[i].first ); + } + } + else + { + for ( ULONG i = 0; i < pyDia::Symbol::cntAmd64RegName; ++i ) + { + if ( upcaseName == pyDia::Symbol::amd64RegName[i].second ) + return getValue( pyDia::Symbol::amd64RegName[i].first ); + } + } + + throwUnsupportedProcessor(__FUNCTION__); +} + /////////////////////////////////////////////////////////////////////////////////// bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const @@ -218,7 +245,27 @@ python::object ThreadContext::getByIndex(ULONG ind) const for (ULONG i = 0; it != m_regValues.end(); ++i, ++it ) { if (i == ind) - return python::make_tuple(it->first, it->second); + { + switch (m_processorType) + { + case IMAGE_FILE_MACHINE_I386: + + for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j ) + if ( pyDia::Symbol::i386RegName[j].first == it->first ) + return python::make_tuple( it->first, pyDia::Symbol::i386RegName[j].second, it->second); + + break; + + + case IMAGE_FILE_MACHINE_AMD64: + + for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j ) + if ( pyDia::Symbol::amd64RegName[j].first == it->first ) + return python::make_tuple( it->first, pyDia::Symbol::amd64RegName[j].second, it->second); + + break; + } + } } throw PyException( PyExc_IndexError, "Index out of range"); @@ -376,4 +423,38 @@ void ThreadContext::throwUnsupportedProcessor(PCSTR szFunction) const ///////////////////////////////////////////////////////////////////////////////// +std::string ThreadContext::print() const +{ + std::stringstream sstr; + + RegValues::const_iterator it = m_regValues.begin(); + for (; it != m_regValues.end(); ++it ) + { + switch (m_processorType) + { + case IMAGE_FILE_MACHINE_I386: + + for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j ) + if ( pyDia::Symbol::i386RegName[j].first == it->first ) + sstr << pyDia::Symbol::i386RegName[j].second << '=' << std::hex << it->second << std::endl; + + break; + + + case IMAGE_FILE_MACHINE_AMD64: + + for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j ) + if ( pyDia::Symbol::amd64RegName[j].first == it->first ) + sstr << pyDia::Symbol::amd64RegName[j].second << '=' << std::hex << it->second << std::endl; + + break; + } + + } + + return sstr.str(); +} + +///////////////////////////////////////////////////////////////////////////////// + } diff --git a/pykd/context.h b/pykd/context.h index 53db942..40d9b41 100644 --- a/pykd/context.h +++ b/pykd/context.h @@ -30,6 +30,7 @@ public: // get register value by ID ULONG64 getValue(ULONG cvRegId) const; + ULONG64 getValueByName( const std::string ®Name ) const; bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const; // get @$ip pseudo register @@ -46,7 +47,7 @@ public: return static_cast( m_regValues.size() ); } - python::object getByIndex(ULONG ind) const; + python::object getByIndex(ULONG ind) const; // get processor type std::string getProcessorType() const { @@ -55,6 +56,8 @@ public: ContextPtr forkByStackFrame(const StackFrame &stkFrmae) const; + std::string print() const; + private: // query i386 registers diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index f4d9081..029d0a3 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -680,7 +680,7 @@ BOOST_PYTHON_MODULE( pykd ) .def( "getLocals", &StackFrame::getLocals, StackFrame_getLocals( python::args( "ctx" ), "Get list of local variables for this stack frame" ) ) .def( "__str__", &StackFrame::print, - "Return stacks frame as string"); + "Return stacks frame as a string"); python::class_( "Context", "Context of thread (register values)", python::no_init ) @@ -692,6 +692,8 @@ BOOST_PYTHON_MODULE( pykd ) "Get current stack pointer" ) .def( "get", &ThreadContext::getValue, "Get register value by ID (CV_REG_XXX)" ) + .def( "get", &ThreadContext::getValueByName, + "Get register value by name" ) .def( "processorType", &ThreadContext::getProcessorType, "Get processor ThreadContext as string") .def( "fork", &ThreadContext::forkByStackFrame, @@ -699,7 +701,14 @@ BOOST_PYTHON_MODULE( pykd ) .def("__len__", &ThreadContext::getCount, "Return count of registers") .def("__getitem__", &ThreadContext::getByIndex, - "Return tuple by index"); + "Return tuple by index") + .def("__getitem__", &ThreadContext::getValueByName, + "Return register value by name" ) + .def("__getattr__", &ThreadContext::getValueByName, + "Return register value as a attribute of the Context" ) + .def("__str__", &ThreadContext::print, + "Return context as a string" ); + python::class_ >( "cpuReg", "CPU regsiter class", boost::python::no_init )