From 3a47a6574d36f0d174ac62cc7f22da9311cb44a2 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 7 Aug 2012 11:15:23 +0000 Subject: [PATCH] [0.2.x] added : cpuReg class git-svn-id: https://pykd.svn.codeplex.com/svn@78577 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/cpureg.cpp | 167 ++-------------------------------- pykd/cpureg.h | 9 +- pykd/dbgengine.h | 7 ++ pykd/dia/diawrapper.cpp | 57 +++++++++++- pykd/dia/diawrapper.h | 2 +- pykd/module.h | 2 +- pykd/pykd_2008.vcproj | 16 +++- pykd/pymod.cpp | 29 +++++- pykd/symengine.h | 4 +- pykd/typedvar.h | 2 +- pykd/typeinfo.cpp | 51 +++-------- pykd/typeinfo.h | 10 +- pykd/vardata.cpp | 128 +++++++++++++------------- pykd/vardata.h | 19 ++-- pykd/{intbase.h => variant.h} | 0 pykd/win/dbgeng.cpp | 140 +++++++++++++++++++++++++++- pykd/win/dbgeng.h | 2 + test/scripts/pykdtest.py | 2 + 18 files changed, 354 insertions(+), 293 deletions(-) rename pykd/{intbase.h => variant.h} (100%) diff --git a/pykd/cpureg.cpp b/pykd/cpureg.cpp index ccacd56..29b43d1 100644 --- a/pykd/cpureg.cpp +++ b/pykd/cpureg.cpp @@ -1,195 +1,48 @@ #include "stdafx.h" -#include +//#include +#include "dbgengine.h" #include "cpureg.h" -#include "dbgclient.h" +#include "dbgexcept.h" namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -CpuReg::CpuReg( IDebugClient4 *client, const std::string ®Name ) : - DbgObject( client ) +CpuReg::CpuReg( const std::string ®Name ) { - HRESULT hres; - m_name = regName; - - hres = m_registers->GetIndexByName( boost::to_lower_copy(m_name).c_str(), &m_index ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetIndexByName", hres ); - - DEBUG_REGISTER_DESCRIPTION desc = {}; - - hres = - m_registers->GetDescription( - m_index, - NULL, - 0, - NULL, - &desc ); - - if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetDescription", hres ); - - switch ( desc.Type ) - { - case DEBUG_VALUE_INT8: - case DEBUG_VALUE_INT16: - case DEBUG_VALUE_INT32: - case DEBUG_VALUE_INT64: - break; - - default: - throw DbgException( "Unsupported register type ( not integer )" ); - } + m_index = getRegIndexByName( m_name ); } /////////////////////////////////////////////////////////////////////////////////// -CpuReg::CpuReg( IDebugClient4 *client, ULONG index ) : - DbgObject( client ) +CpuReg::CpuReg( ULONG index ) { - HRESULT hres; - m_index = index; - - ULONG nameSize = 0; - - hres = - m_registers->GetDescription( - m_index, - NULL, - 0, - &nameSize, - NULL ); - - if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetDescription", hres ); - - std::vector nameBuffer(nameSize); - DEBUG_REGISTER_DESCRIPTION desc = {}; - - hres = - m_registers->GetDescription( - m_index, - &nameBuffer[0], - nameSize, - NULL, - &desc ); - - if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetDescription", hres ); - - switch ( desc.Type ) - { - case DEBUG_VALUE_INT8: - case DEBUG_VALUE_INT16: - case DEBUG_VALUE_INT32: - case DEBUG_VALUE_INT64: - break; - - default: - throw DbgException( "Unsupported register type ( not integer )" ); - } - - m_name = std::string( &nameBuffer[0] ); - + m_name = getRegNameByIndex( m_index ); } /////////////////////////////////////////////////////////////////////////////////// BaseTypeVariant CpuReg::getValue() { - 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" ); + return getRegVariantValue( m_index ); } /////////////////////////////////////////////////////////////////////////////////// -CpuReg DebugClient::getRegByName( const std::string ®Name ) -{ - return CpuReg( m_client, regName ); -} - - CpuReg getRegByName( const std::string ®Name ) { - return g_dbgClient->getRegByName( regName ); + return CpuReg( regName ); } /////////////////////////////////////////////////////////////////////////////////// -CpuReg DebugClient::getRegByIndex( ULONG index ) -{ - return CpuReg( m_client, index ); -} - - CpuReg getRegByIndex( ULONG index ) { - return g_dbgClient->getRegByIndex( index ); -} - -/////////////////////////////////////////////////////////////////////////////////// - -ULONG64 DebugClient::loadMSR( ULONG msr ) -{ - HRESULT hres; - ULONG64 value; - - hres = m_dataSpaces->ReadMsr( msr, &value ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugDataSpaces::ReadMsr", hres ); - - return value; -} - -ULONG64 loadMSR( ULONG msr ) -{ - return g_dbgClient->loadMSR( msr ); -} - -/////////////////////////////////////////////////////////////////////////////////// - -void DebugClient::setMSR( ULONG msr, ULONG64 value) -{ - HRESULT hres; - - hres = m_dataSpaces->WriteMsr(msr, value); - if ( FAILED( hres ) ) - throw DbgException( "IDebugDataSpaces::WriteMsr", hres ); -} - -void setMSR( ULONG msr, ULONG64 value) -{ - g_dbgClient->setMSR( msr, value ); + return CpuReg( index ); } /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/cpureg.h b/pykd/cpureg.h index d8bd3d4..f0f9c33 100644 --- a/pykd/cpureg.h +++ b/pykd/cpureg.h @@ -1,19 +1,18 @@ #pragma once -#include "intbase.h" -#include "dbgobj.h" +#include "variant.h" namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -class CpuReg : public intBase, protected DbgObject { +class CpuReg : public intBase { public: - CpuReg( IDebugClient4 *client, const std::string ®Name ); + CpuReg( const std::string ®Name ); - CpuReg( IDebugClient4 *client, ULONG index ); + CpuReg( ULONG index ); std::string name() const { diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 038c79d..99c9db3 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -1,6 +1,7 @@ #pragma once #include "dbgmem.h" +#include "variant.h" namespace pykd { @@ -13,6 +14,7 @@ void debugGo(); // system properties ULONG ptrSize(); +bool is64bitSystem(); //manage debug module ULONG64 findModuleBase( const std::string &moduleName ); @@ -24,6 +26,11 @@ std::string getModuleSymbolFileName( ULONG64 baseOffset ); ULONG getModuleTimeStamp( ULONG64 baseOffset ); ULONG getModuleCheckSum( ULONG64 baseOffset ); +// CPU registers +ULONG getRegIndexByName( const std::string ®Name ); +std::string getRegNameByIndex( ULONG index ); +BaseTypeVariant getRegVariantValue( ULONG index ); + // это нужно сделать по-другому! std::string getSymbolByOffset( ULONG64 offset ); diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp index 80e6052..6c11f5c 100644 --- a/pykd/dia/diawrapper.cpp +++ b/pykd/dia/diawrapper.cpp @@ -328,11 +328,66 @@ ULONGLONG DiaSymbol::getVa() //////////////////////////////////////////////////////////////////////////////// -void DiaSymbol::getValue( VARIANT &vtValue) +void DiaSymbol::getValue( BaseTypeVariant &btv ) { + CComVariant vtValue; HRESULT hres = m_symbol->get_value(&vtValue); if (S_OK != hres) throw DiaException("Call IDiaSymbol::get_value", hres); + + switch (vtValue.vt) + { + case VT_I1: + btv = (LONG)vtValue.bVal; + break; + + case VT_UI1: + btv = (ULONG)vtValue.bVal; + break; + + case VT_BOOL: + btv = !!vtValue.iVal; + break; + + case VT_I2: + btv = (LONG)vtValue.iVal; + break; + + case VT_UI2: + btv = (ULONG)vtValue.iVal; + break; + + case VT_I4: + case VT_INT: + btv = (LONG)vtValue.lVal; + break; + + case VT_UI4: + case VT_UINT: + case VT_ERROR: + case VT_HRESULT: + btv = (ULONG)vtValue.lVal; + break; + + case VT_I8: + btv = (ULONG64)vtValue.llVal; + break; + + case VT_UI8: + btv = (LONG64)vtValue.llVal; + break; + + //case VT_R4: + // btv = vtValue.fltVal; + // break; + + //case VT_R8: + // fillDataBuff(vtValue.dblVal); + // break; + + default: + throw DbgException( "Unsupported const value" ); + } } ////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h index 210e7f9..98318c3 100644 --- a/pykd/dia/diawrapper.h +++ b/pykd/dia/diawrapper.h @@ -102,7 +102,7 @@ public: //static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue); //python::object getValue(); - void getValue( VARIANT &vtValue); + void getValue( BaseTypeVariant &vtValue ); //bool isBasicType(); diff --git a/pykd/module.h b/pykd/module.h index 8cf5167..f5a657b 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -1,6 +1,6 @@ #pragma once -#include "intbase.h" +#include "variant.h" #include "symengine.h" #include "typeinfo.h" #include "typedvar.h" diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 275d415..8417e57 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -349,6 +349,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -431,6 +435,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -443,10 +451,6 @@ RelativePath=".\dbgmem.h" > - - @@ -483,6 +487,10 @@ RelativePath=".\vardata.h" > + + ( "intBase", "intBase", python::no_init ) .def( python::init() ) .def( "__eq__", &intBase::eq ) @@ -275,6 +288,12 @@ BOOST_PYTHON_MODULE( pykd ) .def("__getitem__", &TypedVar::getElementByIndex ) .def("__getitem__", &TypedVar::getElementByIndexPtr ); + + 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" ); + // wrapper for standart python exceptions python::register_exception_translator( &PyException::exceptionTranslate ); @@ -301,6 +320,14 @@ BOOST_PYTHON_MODULE( pykd ) + + + + + + + + //#include diff --git a/pykd/symengine.h b/pykd/symengine.h index 544ae1f..749de4e 100644 --- a/pykd/symengine.h +++ b/pykd/symengine.h @@ -1,5 +1,7 @@ #pragma once +#include "variant.h" + namespace pykd { //////////////////////////////////////////////////////////////////////////////// @@ -128,7 +130,7 @@ public: virtual ULONG getSymTag() = 0; virtual SymbolPtr getType() = 0; virtual ULONGLONG getVa() = 0; - virtual void getValue( VARIANT &vtValue) = 0; + virtual void getValue( BaseTypeVariant &vtValue) = 0; virtual ULONG getVirtualBaseDispIndex() = 0; virtual int getVirtualBasePointerOffset() = 0; virtual bool isVirtualBaseClass() = 0; diff --git a/pykd/typedvar.h b/pykd/typedvar.h index 79dd8a4..64230d8 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -1,7 +1,7 @@ #pragma once #include "typeinfo.h" -#include "intbase.h" +#include "variant.h" #include "dbgexcept.h" #include "vardata.h" diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index e1633fa..0c6f102 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -114,34 +114,7 @@ BaseTypeVariant TypeInfo::getValue() if ( !m_constant ) throw TypeException( getName(), "this type is not a constant and has not a value" ); - switch( m_constantValue.vt ) - { - case VT_UI1: - return (ULONG)m_constantValue.bVal;; - - case VT_I1: - return (LONG)m_constantValue.cVal; - - case VT_UI2: - return (ULONG)m_constantValue.uiVal; - - case VT_I2: - return (LONG)m_constantValue.iVal; - - case VT_UI4: - return (ULONG)m_constantValue.lVal; - - case VT_I4: - return (LONG)m_constantValue.ulVal; - - case VT_UI8: - return (ULONG64)m_constantValue.ullVal; - - case VT_I8: - return (LONG64)m_constantValue.llVal; - } - - throw TypeException( getName(), "Failed to convert constant type to any integer type" ); + return m_constantValue; } ///////////////////////////////////////////////////////////////////////////////////// @@ -166,9 +139,8 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, const std::string &symN TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, SymbolPtr &symChild ) { - CComVariant constVal; - SymbolPtr symType = symChild; + if ( symType->getSymTag() == SymTagData ) { if ( symType->getLocType() == LocIsBitField ) @@ -178,18 +150,17 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, SymbolPtr &symChild ) if ( symType->getDataKind() == DataIsConstant ) { + BaseTypeVariant constVal; symType->getValue( constVal ); + TypeInfoPtr ptr = getTypeInfo( symType->getType() ); + ptr->setConstant( constVal ); + return ptr; } symType = symType->getType(); } - TypeInfoPtr ptr = getTypeInfo( symType ); - - if ( constVal.vt != VT_EMPTY ) - ptr->setConstant( constVal ); - - return ptr; + return getTypeInfo( symType ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -766,11 +737,11 @@ python::dict EnumTypeInfo::asMap() for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ ) { - CComVariant val; + BaseTypeVariant val; (*it)->getValue( val ); - dct[val.ulVal] = (*it)->getName(); + dct[ boost::apply_visitor( VariantToULong(), val ) ] = (*it)->getName(); } return dct; @@ -788,11 +759,11 @@ std::string EnumTypeInfo::print() for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ ) { - CComVariant val; + BaseTypeVariant val; (*it)->getValue( val ); sstr << " " << (*it)->getName(); - sstr << " = " << std::hex << val.ulVal << " (" << std::dec << val.ulVal << ')'; + sstr << " = " << boost::apply_visitor( VariantToHex(), val ) << " (" << boost::apply_visitor( VariantToStr(), val )<< ')'; sstr << std::endl; } diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index e485a0f..4fa7e48 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -5,7 +5,7 @@ #include #include "udtutils.h" -#include "intbase.h" +#include "variant.h" #include "symengine.h" #include "dbgexcept.h" @@ -56,9 +56,7 @@ public: m_virtualBasePtr( 0 ), m_virtualDispIndex( 0 ), m_virtualDispSize( 0 ) - { - m_constantValue.vt = VT_EMPTY; - } + {} virtual std::string print() { std::stringstream sstr; @@ -156,7 +154,7 @@ public: throw PyException( PyExc_TypeError, "object is unsubscriptable"); } - void setConstant( const VARIANT& var ) + void setConstant( const BaseTypeVariant& var ) { m_constant = true; m_constantValue = var; @@ -220,7 +218,7 @@ protected: bool m_virtualMember; - VARIANT m_constantValue; + BaseTypeVariant m_constantValue; LONG m_virtualBasePtr; diff --git a/pykd/vardata.cpp b/pykd/vardata.cpp index a9d8503..455b274 100644 --- a/pykd/vardata.cpp +++ b/pykd/vardata.cpp @@ -60,107 +60,103 @@ ULONG64 VarDataMemory::readPtr() const VarDataConst::VarDataConst( SymbolPtr &symData) : m_fieldOffset(0) - , m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) ) { - VARIANT vtValue = {0}; - symData->getValue(vtValue); - - switch (vtValue.vt) - { - case VT_I1: - case VT_UI1: - fillDataBuff(vtValue.bVal); - break; - - case VT_BOOL: - fillDataBuff(!!vtValue.iVal); - break; - - case VT_I2: - case VT_UI2: - fillDataBuff(vtValue.iVal); - break; - - case VT_I4: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_ERROR: - case VT_HRESULT: - fillDataBuff(vtValue.lVal); - break; - - case VT_I8: - case VT_UI8: - fillDataBuff(vtValue.llVal); - break; - - case VT_R4: - fillDataBuff(vtValue.fltVal); - break; - - case VT_R8: - fillDataBuff(vtValue.dblVal); - break; - - default: - throw DbgException( "Unsupported const value" ); - } + symData->getValue(m_value); } -//////////////////////////////////////////////////////////////////////////////// +// VARIANT vtValue = {0}; +// symData->getValue(vtValue); +// +// switch (vtValue.vt) +// { +// case VT_I1: +// case VT_UI1: +// fillDataBuff(vtValue.bVal); +// break; +// +// case VT_BOOL: +// fillDataBuff(!!vtValue.iVal); +// break; +// +// case VT_I2: +// case VT_UI2: +// fillDataBuff(vtValue.iVal); +// break; +// +// case VT_I4: +// case VT_UI4: +// case VT_INT: +// case VT_UINT: +// case VT_ERROR: +// case VT_HRESULT: +// fillDataBuff(vtValue.lVal); +// break; +// +// case VT_I8: +// case VT_UI8: +// fillDataBuff(vtValue.llVal); +// break; +// +// case VT_R4: +// fillDataBuff(vtValue.fltVal); +// break; +// +// case VT_R8: +// fillDataBuff(vtValue.dblVal); +// break; +// +// default: +// throw DbgException( "Unsupported const value" ); +// } +//} + +////////////////////////////////////////////////////////////////////////////////// std::string VarDataConst::asString() const { return ""; } -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// ULONG64 VarDataConst::getAddr() const { throw DbgException("Constant does not have address"); } -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// VarDataPtr VarDataConst::fork(ULONG offset) const { return VarDataPtr(new VarDataConst(*this, offset)); } -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const { - if (offset + length > m_dataBuff->size()) + ULONG64 val = boost::apply_visitor( VariantToULong64(), m_value ); + if (offset + length > sizeof(val) ) throw DbgException("Internal error in " __FUNCTION__); - RtlCopyMemory(buffer, &m_dataBuff->at(offset), length); + + RtlCopyMemory(buffer, (char*)&val + offset, length); } -////////////////////////////////////////////////////////////////////////////////' +//////////////////////////////////////////////////////////////////////////////////' ULONG64 VarDataConst::readPtr() const { - ULONG64 val = 0; - const ULONG length = ptrSize(); - if (length > m_dataBuff->size()) - throw DbgException("Internal error in " __FUNCTION__); - RtlCopyMemory(&val, &m_dataBuff->at(0), length); - return val; + return boost::apply_visitor( VariantToULong64(), m_value ); } -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) : - m_fieldOffset(from.m_fieldOffset + fieldOffset) - , m_dataBuff(from.m_dataBuff) + m_fieldOffset(from.m_fieldOffset + fieldOffset), + m_value(from.m_value) { } -//////////////////////////////////////////////////////////////////////////////// - -} - -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +} // end pykd namespace diff --git a/pykd/vardata.h b/pykd/vardata.h index b7548a0..d170945 100644 --- a/pykd/vardata.h +++ b/pykd/vardata.h @@ -75,16 +75,21 @@ protected: VarDataConst(SymbolPtr &symData); VarDataConst(const VarDataConst &from, ULONG fieldOffset); - template - void fillDataBuff(const T &data) - { - RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) ); - } + //template + //void fillDataBuff(const T &data) + //{ + // RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) ); + //} private: - ULONG m_fieldOffset; - boost::shared_ptr< std::vector > m_dataBuff; + BaseTypeVariant m_value; + ULONG m_fieldOffset; + + //ULONG m_fieldOffset; + //boost::shared_ptr< std::vector > m_dataBuff; + + }; } diff --git a/pykd/intbase.h b/pykd/variant.h similarity index 100% rename from pykd/intbase.h rename to pykd/variant.h diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index e97901a..29640d2 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" +#include + #include "win/dbgeng.h" #include "dbgexcept.h" @@ -318,6 +320,21 @@ ULONG ptrSize() /////////////////////////////////////////////////////////////////////////////////// +bool is64bitSystem() +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + hres = g_dbgEng->control->IsPointer64Bit(); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::IsPointer64Bit failed" ); + + return hres == S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + std::string getSymbolByOffset( ULONG64 offset ) { PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); @@ -344,8 +361,127 @@ std::string getSymbolByOffset( ULONG64 offset ) return symbolName; } -/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -}; +ULONG64 loadMSR( ULONG msr ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + ULONG64 value; + + hres = g_dbgEng->dataspace->ReadMsr( msr, &value ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugDataSpaces::ReadMsr", hres ); + + return value; +} + +/////////////////////////////////////////////////////////////////////////////// + +void setMSR( ULONG msr, ULONG64 value) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + hres = g_dbgEng->dataspace->WriteMsr(msr, value); + if ( FAILED( hres ) ) + throw DbgException( "IDebugDataSpaces::WriteMsr", hres ); +} + +/////////////////////////////////////////////////////////////////////////////// + +ULONG getRegIndexByName( const std::string ®Name ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + ULONG index; + + hres = g_dbgEng->registers->GetIndexByName( boost::to_lower_copy(regName).c_str(), &index ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetIndexByName", hres ); + + return index; +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string getRegNameByIndex( ULONG index ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + ULONG nameSize = 0; + + hres = + g_dbgEng->registers->GetDescription( + index, + NULL, + 0, + &nameSize, + NULL ); + + if ( nameSize == 0 ) + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetDescription", hres ); + + std::vector nameBuffer(nameSize); + DEBUG_REGISTER_DESCRIPTION desc = {}; + + hres = + g_dbgEng->registers->GetDescription( + index, + &nameBuffer[0], + nameSize, + NULL, + &desc ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetDescription", hres ); + + return std::string( &nameBuffer[0] ); +} + +/////////////////////////////////////////////////////////////////////////////// + +BaseTypeVariant getRegVariantValue( ULONG index ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + DEBUG_VALUE debugValue; + hres = g_dbgEng->registers->GetValue( 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" ); +} + +/////////////////////////////////////////////////////////////////////////////// + +} // end pykd namespace diff --git a/pykd/win/dbgeng.h b/pykd/win/dbgeng.h index dca1692..3550431 100644 --- a/pykd/win/dbgeng.h +++ b/pykd/win/dbgeng.h @@ -23,6 +23,7 @@ public: CComQIPtr symbols; CComQIPtr dataspace; CComQIPtr advanced; + CComQIPtr registers; DbgEngBind( PDEBUG_CLIENT4 c ) { @@ -32,6 +33,7 @@ public: symbols = c; dataspace = c; advanced = c; + registers = c; } PyThreadStateSaver pystate; diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 9bd99dd..4248fe3 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -18,6 +18,7 @@ import memtest import moduletest import typeinfo import typedvar +import regtest def getTestSuite( singleName = "" ): if singleName == "": @@ -29,6 +30,7 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), + unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), ] ) else: return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )