diff --git a/pykd/context.cpp b/pykd/context.cpp index 2c2cfab..c39550a 100644 --- a/pykd/context.cpp +++ b/pykd/context.cpp @@ -7,9 +7,9 @@ ///////////////////////////////////////////////////////////////////////////////// -namespace Ctx { - -///////////////////////////////////////////////////////////////////////////////// +namespace pykd { + +//////////////////////////////////////////////////////////////////////////////// namespace I386 { #include "defctxi386.h" @@ -17,15 +17,13 @@ namespace I386 { ///////////////////////////////////////////////////////////////////////////////// -void Registers::getI386Context( - IDebugAdvanced2 *advanced -) +void ThreadContext::getI386Context() { I386::CONTEXT Context = {0}; - HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context)); + HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context)); if (S_OK != hres) - throw Exception( "IDebugAdvanced2::GetThreadContext", hres ); + throw DbgException( "IDebugAdvanced2::GetThreadContext", hres ); m_regValues[CV_REG_DR0] = Context.Dr0; m_regValues[CV_REG_DR1] = Context.Dr1; @@ -65,15 +63,13 @@ namespace AMD64 { ///////////////////////////////////////////////////////////////////////////////// -void Registers::getAmd64Context( - IDebugAdvanced2 *advanced -) +void ThreadContext::getAmd64Context() { AMD64::CONTEXT Context = {0}; - HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context)); + HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context)); if (S_OK != hres) - throw Exception( "IDebugAdvanced2::GetThreadContext", hres); + throw DbgException( "IDebugAdvanced2::GetThreadContext", hres); m_regValues[CV_AMD64_MXCSR] = Context.MxCsr; @@ -115,66 +111,48 @@ void Registers::getAmd64Context( ///////////////////////////////////////////////////////////////////////////////// -Registers::Registers( - IDebugControl4 *control, - IDebugAdvanced2 *advanced -) +ThreadContext::ThreadContext( IDebugClient4 *client ) : + pykd::DbgObject( client ) { - HRESULT hres = control->GetExecutingProcessorType(&m_processorType); + HRESULT hres = m_control->GetExecutingProcessorType(&m_processorType); if (S_OK != hres) - throw Exception( "IDebugControl::GetExecutingProcessorType", hres ); + throw DbgException( "IDebugControl::GetExecutingProcessorType", hres ); switch (m_processorType) { case IMAGE_FILE_MACHINE_I386: - getI386Context(advanced); + getI386Context(); return; case IMAGE_FILE_MACHINE_AMD64: - getAmd64Context(advanced); + getAmd64Context(); return; } std::stringstream sstream; sstream << __FUNCTION__ << ":\n"; sstream << "Unsupported processor type: 0x" << std::hex << m_processorType; - throw Exception( sstream.str() ); + throw DbgException( sstream.str() ); } ///////////////////////////////////////////////////////////////////////////////// -ULONG64 Registers::getValue(ULONG cvRegId) const +ULONG64 ThreadContext::getValue(ULONG cvRegId) const { - try - { - return getSubValue(cvRegId); - } - catch (const IsNotSubRegister &) - { - } + ULONG64 val; - RegValues::const_iterator it = m_regValues.find(cvRegId); - if (it == m_regValues.end()) - throw Exception(__FUNCTION__ ": Register missing"); - return it->second; + if ( getValueNoThrow( cvRegId, val ) ) + return val; + + throw DbgException(__FUNCTION__ ": Register missing"); } -///////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// -bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const +bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const { - try - { - val = getSubValue(cvRegId); + if ( getSubValue(cvRegId, val ) ) return true; - } - catch (const IsNotSubRegister &) - { - } - catch (const Exception &) - { - return false; - } RegValues::const_iterator it = m_regValues.find(cvRegId); if (it == m_regValues.end()) @@ -184,9 +162,9 @@ bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const return true; } -///////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// -ULONG64 Registers::getIp() const +ULONG64 ThreadContext::getIp() const { return getValue( IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EIP : CV_AMD64_RIP @@ -195,7 +173,7 @@ ULONG64 Registers::getIp() const ///////////////////////////////////////////////////////////////////////////////// -ULONG64 Registers::getRetReg() const +ULONG64 ThreadContext::getRetReg() const { return getValue( IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EAX : CV_AMD64_RAX @@ -204,7 +182,7 @@ ULONG64 Registers::getRetReg() const ///////////////////////////////////////////////////////////////////////////////// -ULONG64 Registers::getSp() const +ULONG64 ThreadContext::getSp() const { return getValue( IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_ESP : CV_AMD64_RSP @@ -213,7 +191,7 @@ ULONG64 Registers::getSp() const ///////////////////////////////////////////////////////////////////////////////// -python::object Registers::getByIndex(ULONG ind) const +python::object ThreadContext::getByIndex(ULONG ind) const { RegValues::const_iterator it = m_regValues.begin(); for (ULONG i = 0; it != m_regValues.end(); ++i, ++it ) @@ -222,10 +200,7 @@ python::object Registers::getByIndex(ULONG ind) const return python::make_tuple(it->first, it->second); } - PyErr_SetString(PyExc_IndexError, "Index out of range"); - python::throw_error_already_set(); - - return python::object(); + throw PyException( PyExc_IndexError, "Index out of range"); } ///////////////////////////////////////////////////////////////////////////////// @@ -243,109 +218,110 @@ struct SubRegister { ///////////////////////////////////////////////////////////////////////////////// -static const class SubRegisterMapI386 : public std::map { -public: - SubRegisterMapI386(); -} g_SubRegistersI386; + +struct SubRegisterMapI386 { + + std::map subRegs; + + SubRegisterMapI386() + { + subRegs[CV_REG_AL].set(CV_REG_EAX, 0x00, 0xff); + subRegs[CV_REG_CL].set(CV_REG_ECX, 0x00, 0xff); + subRegs[CV_REG_DL].set(CV_REG_EDX, 0x00, 0xff); + subRegs[CV_REG_BL].set(CV_REG_EBX, 0x00, 0xff); + + subRegs[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff); + subRegs[CV_REG_CH].set(CV_REG_ECX, 0x08, 0xff); + subRegs[CV_REG_DH].set(CV_REG_EDX, 0x08, 0xff); + subRegs[CV_REG_BH].set(CV_REG_EBX, 0x08, 0xff); + + subRegs[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff); + subRegs[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff); + subRegs[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff); + subRegs[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff); + + subRegs[CV_REG_SP].set(CV_REG_ESP, 0x00, 0xffff); + subRegs[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff); + subRegs[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff); + subRegs[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff); + } + +}; + +static const std::map g_SubRegistersI386 = SubRegisterMapI386().subRegs; ///////////////////////////////////////////////////////////////////////////////// -SubRegisterMapI386::SubRegisterMapI386() -{ - (*this)[CV_REG_AL].set(CV_REG_EAX, 0x00, 0xff); - (*this)[CV_REG_CL].set(CV_REG_ECX, 0x00, 0xff); - (*this)[CV_REG_DL].set(CV_REG_EDX, 0x00, 0xff); - (*this)[CV_REG_BL].set(CV_REG_EBX, 0x00, 0xff); +struct SubRegisterMapAmd64 { - (*this)[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff); - (*this)[CV_REG_CH].set(CV_REG_ECX, 0x08, 0xff); - (*this)[CV_REG_DH].set(CV_REG_EDX, 0x08, 0xff); - (*this)[CV_REG_BH].set(CV_REG_EBX, 0x08, 0xff); + std::map subRegs; - (*this)[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff); - (*this)[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff); - (*this)[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff); - (*this)[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff); + SubRegisterMapAmd64() + { + subRegs[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff); + subRegs[CV_AMD64_CL].set(CV_AMD64_RCX, 0x00, 0xff); + subRegs[CV_AMD64_DL].set(CV_AMD64_RDX, 0x00, 0xff); + subRegs[CV_AMD64_BL].set(CV_AMD64_RBX, 0x00, 0xff); - (*this)[CV_REG_SP].set(CV_REG_ESP, 0x00, 0xffff); - (*this)[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff); - (*this)[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff); - (*this)[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff); + subRegs[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff); + subRegs[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff); + subRegs[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff); + subRegs[CV_AMD64_BH].set(CV_AMD64_RBX, 0x08, 0xff); -} + subRegs[CV_AMD64_AX].set(CV_AMD64_RAX, 0x00, 0xffff); + subRegs[CV_AMD64_CX].set(CV_AMD64_RCX, 0x00, 0xffff); + subRegs[CV_AMD64_DX].set(CV_AMD64_RDX, 0x00, 0xffff); + subRegs[CV_AMD64_BX].set(CV_AMD64_RBX, 0x00, 0xffff); + + subRegs[CV_AMD64_SP].set(CV_AMD64_RSP, 0x00, 0xffff); + subRegs[CV_AMD64_BP].set(CV_AMD64_RBP, 0x00, 0xffff); + subRegs[CV_AMD64_SI].set(CV_AMD64_RSI, 0x00, 0xffff); + subRegs[CV_AMD64_DI].set(CV_AMD64_RDI, 0x00, 0xffff); + + subRegs[CV_AMD64_EAX].set(CV_AMD64_RAX, 0x00, 0xffffffff); + subRegs[CV_AMD64_ECX].set(CV_AMD64_RCX, 0x00, 0xffffffff); + subRegs[CV_AMD64_EDX].set(CV_AMD64_RDX, 0x00, 0xffffffff); + subRegs[CV_AMD64_EBX].set(CV_AMD64_RBX, 0x00, 0xffffffff); + + subRegs[CV_AMD64_ESP].set(CV_AMD64_RSP, 0x00, 0xffffffff); + subRegs[CV_AMD64_EBP].set(CV_AMD64_RBP, 0x00, 0xffffffff); + subRegs[CV_AMD64_ESI].set(CV_AMD64_RSI, 0x00, 0xffffffff); + subRegs[CV_AMD64_EDI].set(CV_AMD64_RDI, 0x00, 0xffffffff); + + subRegs[CV_AMD64_R8B].set(CV_AMD64_R8, 0x00, 0xff); + subRegs[CV_AMD64_R9B].set(CV_AMD64_R9, 0x00, 0xff); + subRegs[CV_AMD64_R10B].set(CV_AMD64_R10, 0x00, 0xff); + subRegs[CV_AMD64_R11B].set(CV_AMD64_R11, 0x00, 0xff); + subRegs[CV_AMD64_R12B].set(CV_AMD64_R12, 0x00, 0xff); + subRegs[CV_AMD64_R13B].set(CV_AMD64_R13, 0x00, 0xff); + subRegs[CV_AMD64_R14B].set(CV_AMD64_R14, 0x00, 0xff); + subRegs[CV_AMD64_R15B].set(CV_AMD64_R15, 0x00, 0xff); + + subRegs[CV_AMD64_R8W].set(CV_AMD64_R8, 0x00, 0xffff); + subRegs[CV_AMD64_R9W].set(CV_AMD64_R9, 0x00, 0xffff); + subRegs[CV_AMD64_R10W].set(CV_AMD64_R10, 0x00, 0xffff); + subRegs[CV_AMD64_R11W].set(CV_AMD64_R11, 0x00, 0xffff); + subRegs[CV_AMD64_R12W].set(CV_AMD64_R12, 0x00, 0xffff); + subRegs[CV_AMD64_R13W].set(CV_AMD64_R13, 0x00, 0xffff); + subRegs[CV_AMD64_R14W].set(CV_AMD64_R14, 0x00, 0xffff); + subRegs[CV_AMD64_R15W].set(CV_AMD64_R15, 0x00, 0xffff); + + subRegs[CV_AMD64_R8D].set(CV_AMD64_R8, 0x00, 0xffffffff); + subRegs[CV_AMD64_R9D].set(CV_AMD64_R9, 0x00, 0xffffffff); + subRegs[CV_AMD64_R10D].set(CV_AMD64_R10, 0x00, 0xffffffff); + subRegs[CV_AMD64_R11D].set(CV_AMD64_R11, 0x00, 0xffffffff); + subRegs[CV_AMD64_R12D].set(CV_AMD64_R12, 0x00, 0xffffffff); + subRegs[CV_AMD64_R13D].set(CV_AMD64_R13, 0x00, 0xffffffff); + subRegs[CV_AMD64_R14D].set(CV_AMD64_R14, 0x00, 0xffffffff); + subRegs[CV_AMD64_R15D].set(CV_AMD64_R15, 0x00, 0xffffffff); + } +}; + +static const std::map g_SubRegistersAmd64 = SubRegisterMapAmd64().subRegs; ///////////////////////////////////////////////////////////////////////////////// -static const class SubRegisterMapAmd64 : public std::map { -public: - SubRegisterMapAmd64(); -} g_SubRegistersAmd64; - -///////////////////////////////////////////////////////////////////////////////// - -SubRegisterMapAmd64::SubRegisterMapAmd64() -{ - (*this)[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff); - (*this)[CV_AMD64_CL].set(CV_AMD64_RCX, 0x00, 0xff); - (*this)[CV_AMD64_DL].set(CV_AMD64_RDX, 0x00, 0xff); - (*this)[CV_AMD64_BL].set(CV_AMD64_RBX, 0x00, 0xff); - - (*this)[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff); - (*this)[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff); - (*this)[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff); - (*this)[CV_AMD64_BH].set(CV_AMD64_RBX, 0x08, 0xff); - - (*this)[CV_AMD64_AX].set(CV_AMD64_RAX, 0x00, 0xffff); - (*this)[CV_AMD64_CX].set(CV_AMD64_RCX, 0x00, 0xffff); - (*this)[CV_AMD64_DX].set(CV_AMD64_RDX, 0x00, 0xffff); - (*this)[CV_AMD64_BX].set(CV_AMD64_RBX, 0x00, 0xffff); - - (*this)[CV_AMD64_SP].set(CV_AMD64_RSP, 0x00, 0xffff); - (*this)[CV_AMD64_BP].set(CV_AMD64_RBP, 0x00, 0xffff); - (*this)[CV_AMD64_SI].set(CV_AMD64_RSI, 0x00, 0xffff); - (*this)[CV_AMD64_DI].set(CV_AMD64_RDI, 0x00, 0xffff); - - (*this)[CV_AMD64_EAX].set(CV_AMD64_RAX, 0x00, 0xffffffff); - (*this)[CV_AMD64_ECX].set(CV_AMD64_RCX, 0x00, 0xffffffff); - (*this)[CV_AMD64_EDX].set(CV_AMD64_RDX, 0x00, 0xffffffff); - (*this)[CV_AMD64_EBX].set(CV_AMD64_RBX, 0x00, 0xffffffff); - - (*this)[CV_AMD64_ESP].set(CV_AMD64_RSP, 0x00, 0xffffffff); - (*this)[CV_AMD64_EBP].set(CV_AMD64_RBP, 0x00, 0xffffffff); - (*this)[CV_AMD64_ESI].set(CV_AMD64_RSI, 0x00, 0xffffffff); - (*this)[CV_AMD64_EDI].set(CV_AMD64_RDI, 0x00, 0xffffffff); - - (*this)[CV_AMD64_R8B].set(CV_AMD64_R8, 0x00, 0xff); - (*this)[CV_AMD64_R9B].set(CV_AMD64_R9, 0x00, 0xff); - (*this)[CV_AMD64_R10B].set(CV_AMD64_R10, 0x00, 0xff); - (*this)[CV_AMD64_R11B].set(CV_AMD64_R11, 0x00, 0xff); - (*this)[CV_AMD64_R12B].set(CV_AMD64_R12, 0x00, 0xff); - (*this)[CV_AMD64_R13B].set(CV_AMD64_R13, 0x00, 0xff); - (*this)[CV_AMD64_R14B].set(CV_AMD64_R14, 0x00, 0xff); - (*this)[CV_AMD64_R15B].set(CV_AMD64_R15, 0x00, 0xff); - - (*this)[CV_AMD64_R8W].set(CV_AMD64_R8, 0x00, 0xffff); - (*this)[CV_AMD64_R9W].set(CV_AMD64_R9, 0x00, 0xffff); - (*this)[CV_AMD64_R10W].set(CV_AMD64_R10, 0x00, 0xffff); - (*this)[CV_AMD64_R11W].set(CV_AMD64_R11, 0x00, 0xffff); - (*this)[CV_AMD64_R12W].set(CV_AMD64_R12, 0x00, 0xffff); - (*this)[CV_AMD64_R13W].set(CV_AMD64_R13, 0x00, 0xffff); - (*this)[CV_AMD64_R14W].set(CV_AMD64_R14, 0x00, 0xffff); - (*this)[CV_AMD64_R15W].set(CV_AMD64_R15, 0x00, 0xffff); - - (*this)[CV_AMD64_R8D].set(CV_AMD64_R8, 0x00, 0xffffffff); - (*this)[CV_AMD64_R9D].set(CV_AMD64_R9, 0x00, 0xffffffff); - (*this)[CV_AMD64_R10D].set(CV_AMD64_R10, 0x00, 0xffffffff); - (*this)[CV_AMD64_R11D].set(CV_AMD64_R11, 0x00, 0xffffffff); - (*this)[CV_AMD64_R12D].set(CV_AMD64_R12, 0x00, 0xffffffff); - (*this)[CV_AMD64_R13D].set(CV_AMD64_R13, 0x00, 0xffffffff); - (*this)[CV_AMD64_R14D].set(CV_AMD64_R14, 0x00, 0xffffffff); - (*this)[CV_AMD64_R15D].set(CV_AMD64_R15, 0x00, 0xffffffff); -} - -///////////////////////////////////////////////////////////////////////////////// - -ULONG64 Registers::getSubValue(ULONG cvRegId) const +bool ThreadContext::getSubValue(ULONG cvRegId, ULONG64 &val) const { const std::map *subRegs = NULL; if (IMAGE_FILE_MACHINE_I386 == m_processorType) @@ -356,18 +332,17 @@ ULONG64 Registers::getSubValue(ULONG cvRegId) const std::map::const_iterator itSubReg = subRegs->find(cvRegId); if (itSubReg == subRegs->end()) - throw IsNotSubRegister(); + return false; RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg); if (itFullReg == m_regValues.end()) - throw Exception(__FUNCTION__ ": Register missing"); + return false; - return - (itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask; -} - -// ---------------------------------------------------------------------------- + val = (itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask; + return true; } ///////////////////////////////////////////////////////////////////////////////// + +} diff --git a/pykd/context.h b/pykd/context.h index 7753fd2..32e7c32 100644 --- a/pykd/context.h +++ b/pykd/context.h @@ -1,31 +1,24 @@ +#pragma once #include #include #include +#include "context.h" +#include "dbgobj.h" #include "dbgexcept.h" -#pragma once +namespace pykd { -namespace pykd{ - std::string processorToStr(ULONG processorMode); -} - -namespace Ctx { +std::string processorToStr(ULONG processorMode); //////////////////////////////////////////////////////////////////////////////// -typedef pykd::DbgException Exception; - -//////////////////////////////////////////////////////////////////////////////// - -class Registers +class ThreadContext : private DbgObject { public: - Registers( - IDebugControl4 *control, - IDebugAdvanced2 *advanced - ); + + ThreadContext( IDebugClient4 *client ); // get register value by ID ULONG64 getValue(ULONG cvRegId) const; @@ -44,6 +37,7 @@ public: ULONG getCount() const { return static_cast( m_regValues.size() ); } + python::object getByIndex(ULONG ind) const; // get processor type @@ -53,22 +47,14 @@ public: private: - struct IsNotSubRegister : public std::exception { - IsNotSubRegister() : std::exception("is not sub-register") { } - }; - // query i386 registers - void getI386Context( - IDebugAdvanced2 *advanced - ); + void getI386Context(); // query AMD64 registers - void getAmd64Context( - IDebugAdvanced2 *advanced - ); + void getAmd64Context(); // try query as "sub-register" - ULONG64 getSubValue(ULONG cvRegId) const; + bool getSubValue(ULONG cvRegId, ULONG64 &val) const; private: typedef std::map RegValues; @@ -79,7 +65,7 @@ private: //////////////////////////////////////////////////////////////////////////////// -typedef boost::shared_ptr< Registers > ContextPtr; +typedef boost::shared_ptr< ThreadContext > ContextPtr; //////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/cpureg.cpp b/pykd/cpureg.cpp index ee61890..0e22591 100644 --- a/pykd/cpureg.cpp +++ b/pykd/cpureg.cpp @@ -7,60 +7,114 @@ namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -python::object DebugClient::getRegByIndex( ULONG index ) +CpuReg::CpuReg( IDebugClient4 *client, const std::string ®Name ) : + DbgObject( client ) { - HRESULT hres; + HRESULT hres; - DEBUG_VALUE debugValue; - hres = m_registers->GetValue( index, &debugValue ); + m_name = regName; + + hres = m_registers->GetIndexByName( m_name.c_str(), &m_index ); if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetValue failed" ); - - switch( debugValue.Type ) - { - case DEBUG_VALUE_INT8: - return boost::python::long_( debugValue.I8 ); - break; - - case DEBUG_VALUE_INT16: - return boost::python::long_( debugValue.I16 ); - break; - - case DEBUG_VALUE_INT32: - return boost::python::long_( debugValue.I32 ); - break; - - case DEBUG_VALUE_INT64: - return boost::python::long_(debugValue.I64 ); - break; - } - - throw DbgException( "Invalid register value" ); -} - -python::object getRegByIndex( ULONG index ) -{ - return g_dbgClient->getRegByIndex( index ); + throw DbgException( "IDebugRegister::GetIndexByName", hres ); } /////////////////////////////////////////////////////////////////////////////////// - -python::object DebugClient::getRegByName( const std::wstring ®Name ) +CpuReg::CpuReg( IDebugClient4 *client, ULONG index ) : + DbgObject( client ) { - ULONG registerIndex = 0; - HRESULT hres; + HRESULT hres; + + m_index = index; + + ULONG nameSize = 0; + + hres = + m_registers->GetDescription( + m_index, + NULL, + 0, + &nameSize, + NULL ); - hres = m_registers->GetIndexByNameWide( regName.c_str(), ®isterIndex ); if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister2::GetIndexByNameWide failed" ); + throw DbgException( "IDebugRegister::GetDescription", hres ); - return getRegByIndex( registerIndex ); -} + std::vector nameBuffer(nameSize); -python::object getRegByName( const std::wstring ®Name ) + hres = + m_registers->GetDescription( + m_index, + &nameBuffer[0], + nameSize, + NULL, + NULL ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetDescription", hres ); + + m_name = std::string( &nameBuffer[0] ); + +} + +/////////////////////////////////////////////////////////////////////////////////// + +BaseTypeVariant CpuReg::getValue() { - return g_dbgClient->getRegByName( regName ); + HRESULT hres; + + DEBUG_VALUE debugValue; + hres = m_registers->GetValue( m_index, &debugValue ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetValue", hres ); + + switch( debugValue.Type ) + { + case DEBUG_VALUE_INT8: + return BaseTypeVariant( (LONG)debugValue.I8 ); + break; + + case DEBUG_VALUE_INT16: + return BaseTypeVariant( (LONG)debugValue.I16 ); + break; + + case DEBUG_VALUE_INT32: + return BaseTypeVariant( debugValue.I32 ); + break; + + case DEBUG_VALUE_INT64: + return BaseTypeVariant( debugValue.I64 ); + break; + } + + throw DbgException( "Failed to convert register value" ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +CpuReg DebugClient::getRegByName( const std::string ®Name ) +{ + return CpuReg( m_client, regName ); +} + + +CpuReg getRegByName( const std::string ®Name ) +{ + return g_dbgClient->getRegByName( regName ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +CpuReg DebugClient::getRegByIndex( ULONG index ) +{ + return CpuReg( m_client, index ); +} + + +CpuReg getRegByIndex( ULONG index ) +{ + return g_dbgClient->getRegByIndex( index ); } /////////////////////////////////////////////////////////////////////////////////// @@ -72,7 +126,7 @@ ULONG64 DebugClient::loadMSR( ULONG msr ) hres = m_dataSpaces->ReadMsr( msr, &value ); if ( FAILED( hres ) ) - throw DbgException( "IDebugDataSpaces::ReadMsr failed" ); + throw DbgException( "IDebugDataSpaces::ReadMsr", hres ); return value; } @@ -90,7 +144,7 @@ void DebugClient::setMSR( ULONG msr, ULONG64 value) hres = m_dataSpaces->WriteMsr(msr, value); if ( FAILED( hres ) ) - throw DbgException( "IDebugDataSpaces::WriteMsr failed" ); + throw DbgException( "IDebugDataSpaces::WriteMsr", hres ); } void setMSR( ULONG msr, ULONG64 value) diff --git a/pykd/cpureg.h b/pykd/cpureg.h index 05b445d..d8bd3d4 100644 --- a/pykd/cpureg.h +++ b/pykd/cpureg.h @@ -7,9 +7,37 @@ namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -python::object getRegByName( const std::wstring ®Name ); +class CpuReg : public intBase, protected DbgObject { -python::object getRegByIndex( ULONG index ); +public: + + CpuReg( IDebugClient4 *client, const std::string ®Name ); + + CpuReg( IDebugClient4 *client, ULONG index ); + + std::string + name() const { + return m_name; + } + + ULONG index() const { + return m_index; + } + + virtual BaseTypeVariant getValue(); + +private: + + std::string m_name; + + ULONG m_index; +}; + +/////////////////////////////////////////////////////////////////////////////////// + +CpuReg getRegByName( const std::string ®Name ); + +CpuReg getRegByIndex( ULONG index ); ULONG64 loadMSR( ULONG msr ); diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 1661cbc..9282556 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -210,9 +210,9 @@ public: void setMSR( ULONG msr, ULONG64 value); - python::object getRegByName( const std::wstring ®Name ); + CpuReg getRegByName( const std::string ®Name ); - python::object getRegByIndex( ULONG index ); + CpuReg getRegByIndex( ULONG index ); void setCurrentProcess( ULONG64 addr ); @@ -234,14 +234,12 @@ public: return getDbgControl(GetPageSize); } - Ctx::ContextPtr getThreadContext() { - return Ctx::ContextPtr( - new Ctx::Registers(m_control, m_advanced) - ); + ContextPtr getThreadContext() { + return ContextPtr( new ThreadContext(m_client) ); } python::dict getLocals( - Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast(0) ) + ContextPtr ctx = ContextPtr( reinterpret_cast(0) ) ); public: @@ -397,12 +395,12 @@ inline ULONG getPageSize() { return g_dbgClient->getPageSize(); } -inline Ctx::ContextPtr getThreadContext() { +inline ContextPtr getThreadContext() { return g_dbgClient->getThreadContext(); } inline python::dict getLocals( - Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast(0) ) + ContextPtr ctx = ContextPtr() ) { return g_dbgClient->getLocals(ctx); diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 41213dd..d47a17b 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -143,7 +143,8 @@ BOOST_PYTHON_MODULE( pykd ) .def( "__long__", &intBase::long_ ) .def( "__int__", &intBase::int_ ) .def( "__index__", &intBase::long_ ) - .def( "__hash__", &intBase::long_ ); + .def( "__hash__", &intBase::long_ ) + .def( "__coerce__", &intBase::coerce ); python::class_("dbgClient", "Class representing a debugging session", python::no_init ) .def( "addr64", &DebugClient::addr64, @@ -442,11 +443,11 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "ptrSize", &ptrSize, "Return effective pointer size" ); python::def ( "rdmsr", &DebugClient::loadMSR, - "Return MSR value" ); + "Return MSR value" ); python::def( "reg", &getRegByName, "Return a CPU regsiter value by the register's name" ); python::def( "reg", &getRegByIndex, - "Return a CPU regsiter value by the register's value" ); + "Return a CPU regsiter value by the register's value" ); python::def( "setExecutionStatus", &setExecutionStatus, "Requests that the debugger engine enter an executable state" ); python::def( "setCurrentProcess", &setCurrentProcess, @@ -599,7 +600,7 @@ BOOST_PYTHON_MODULE( pykd ) .def( "ea", &Disasm::ea, "Return effective address for last disassembled instruction or 0" ) .def( "reset", &Disasm::reset, "Reset current offset to begin" ); - python::class_( "stackFrame", + python::class_( "stackFrame", "Class representing a frame of the call satck", python::no_init ) .def_readonly( "instructionOffset", &DEBUG_STACK_FRAME::InstructionOffset, "Return a frame's instruction offset" ) @@ -612,23 +613,28 @@ BOOST_PYTHON_MODULE( pykd ) .def_readonly( "frameNumber", &DEBUG_STACK_FRAME::FrameNumber, "Return a frame's number" ); - python::class_( + python::class_( "Context", "Context of thread (register values)", python::no_init ) - .def( "ip", &Ctx::Registers::getIp, + .def( "ip", &ThreadContext::getIp, "Get instruction pointer register" ) - .def( "retreg", &Ctx::Registers::getIp, + .def( "retreg", &ThreadContext::getIp, "Get primary return value register" ) - .def( "csp", &Ctx::Registers::getSp, + .def( "csp", &ThreadContext::getSp, "Get current stack pointer" ) - .def( "get", &Ctx::Registers::getValue, + .def( "get", &ThreadContext::getValue, "Get register value by ID (CV_REG_XXX)" ) - .def( "processorType", &Ctx::Registers::getProcessorType, - "Get processor type as string") - .def("__len__", &Ctx::Registers::getCount, + .def( "processorType", &ThreadContext::getProcessorType, + "Get processor ThreadContext as string") + .def("__len__", &ThreadContext::getCount, "Return count of registers") - .def("__getitem__", &Ctx::Registers::getByIndex, + .def("__getitem__", &ThreadContext::getByIndex, "Return tuple by index"); + python::class_ >( + "cpuReg", "CPU regsiter class", boost::python::no_init ) + .def( "name", &CpuReg::name, "The name of the regsiter" ) + .def( "index", &CpuReg::index, "The index of thr register" ); + python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, "Open pdb file for querying debug symbols. Return DiaSymbol of global scope"); diff --git a/pykd/intbase.h b/pykd/intbase.h index 4fb81ea..302880e 100644 --- a/pykd/intbase.h +++ b/pykd/intbase.h @@ -185,6 +185,11 @@ public: return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0; } + python::object coerce() { + __debugbreak(); + return python::object(); + } + private: virtual BaseTypeVariant getValue() { diff --git a/pykd/livevar.cpp b/pykd/livevar.cpp index 3996b80..3b44d3d 100644 --- a/pykd/livevar.cpp +++ b/pykd/livevar.cpp @@ -19,7 +19,7 @@ struct addLocals { python::dict &m_locals; const Module &m_module; ULONG m_rva; - Ctx::ContextPtr m_ctx; + ContextPtr m_ctx; IDebugClient4 *m_client; ULONG m_formalNameCounter; @@ -181,7 +181,7 @@ static bool isOutOfDebugRange( //////////////////////////////////////////////////////////////////////////////// -python::dict DebugClient::getLocals(Ctx::ContextPtr ctx OPTIONAL) +python::dict DebugClient::getLocals(ContextPtr ctx OPTIONAL) { if (!ctx) ctx = getThreadContext(); diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 47fef54..595c7d0 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -1,11 +1,14 @@ +#define PYKD_VERSION_MAJOR 0 +#define PYKD_VERSION_MINOR 1 +#define PYKD_VERSION_SUBVERSION 0 +#define PYKD_VERSION_BUILDNO 6 + + #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) -#define PYKD_VERSION_MAJOR 1 -#define PYKD_VERSION_MINOR 6 - -#define PYKD_VERSION_BUILD 0,PYKD_VERSION_MAJOR,0,PYKD_VERSION_MINOR +#define PYKD_VERSION_BUILD PYKD_VERSION_MAJOR, PYKD_VERSION_MINOR, PYKD_VERSION_SUBVERSION, PYKD_VERSION_BUILDNO #define PYKD_VERSION_BUILD_STR __VER_STR1__(PYKD_VERSION_BUILD)