[0.2.x] added : cpuReg class

git-svn-id: https://pykd.svn.codeplex.com/svn@78577 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-08-07 11:15:23 +00:00 committed by Mikhail I. Izmestev
parent c8d99b5565
commit 3a47a6574d
18 changed files with 354 additions and 293 deletions

View File

@ -1,195 +1,48 @@
#include "stdafx.h" #include "stdafx.h"
#include <boost\algorithm\string\case_conv.hpp> //#include <boost\algorithm\string\case_conv.hpp>
#include "dbgengine.h"
#include "cpureg.h" #include "cpureg.h"
#include "dbgclient.h" #include "dbgexcept.h"
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
CpuReg::CpuReg( IDebugClient4 *client, const std::string &regName ) : CpuReg::CpuReg( const std::string &regName )
DbgObject( client )
{ {
HRESULT hres;
m_name = regName; m_name = regName;
m_index = getRegIndexByName( m_name );
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 )" );
}
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
CpuReg::CpuReg( IDebugClient4 *client, ULONG index ) : CpuReg::CpuReg( ULONG index )
DbgObject( client )
{ {
HRESULT hres;
m_index = index; m_index = index;
m_name = getRegNameByIndex( m_index );
ULONG nameSize = 0;
hres =
m_registers->GetDescription(
m_index,
NULL,
0,
&nameSize,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetDescription", hres );
std::vector<char> 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] );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
BaseTypeVariant CpuReg::getValue() BaseTypeVariant CpuReg::getValue()
{ {
HRESULT hres; return getRegVariantValue( m_index );
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 &regName )
{
return CpuReg( m_client, regName );
}
CpuReg getRegByName( const std::string &regName ) CpuReg getRegByName( const std::string &regName )
{ {
return g_dbgClient->getRegByName( regName ); return CpuReg( regName );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
CpuReg DebugClient::getRegByIndex( ULONG index )
{
return CpuReg( m_client, index );
}
CpuReg getRegByIndex( ULONG index ) CpuReg getRegByIndex( ULONG index )
{ {
return g_dbgClient->getRegByIndex( index ); return CpuReg( 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 );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -1,19 +1,18 @@
#pragma once #pragma once
#include "intbase.h" #include "variant.h"
#include "dbgobj.h"
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class CpuReg : public intBase, protected DbgObject { class CpuReg : public intBase {
public: public:
CpuReg( IDebugClient4 *client, const std::string &regName ); CpuReg( const std::string &regName );
CpuReg( IDebugClient4 *client, ULONG index ); CpuReg( ULONG index );
std::string std::string
name() const { name() const {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "dbgmem.h" #include "dbgmem.h"
#include "variant.h"
namespace pykd { namespace pykd {
@ -13,6 +14,7 @@ void debugGo();
// system properties // system properties
ULONG ptrSize(); ULONG ptrSize();
bool is64bitSystem();
//manage debug module //manage debug module
ULONG64 findModuleBase( const std::string &moduleName ); ULONG64 findModuleBase( const std::string &moduleName );
@ -24,6 +26,11 @@ std::string getModuleSymbolFileName( ULONG64 baseOffset );
ULONG getModuleTimeStamp( ULONG64 baseOffset ); ULONG getModuleTimeStamp( ULONG64 baseOffset );
ULONG getModuleCheckSum( ULONG64 baseOffset ); ULONG getModuleCheckSum( ULONG64 baseOffset );
// CPU registers
ULONG getRegIndexByName( const std::string &regName );
std::string getRegNameByIndex( ULONG index );
BaseTypeVariant getRegVariantValue( ULONG index );
// ýòî íóæíî ñäåëàòü ïî-äðóãîìó! // ýòî íóæíî ñäåëàòü ïî-äðóãîìó!
std::string getSymbolByOffset( ULONG64 offset ); std::string getSymbolByOffset( ULONG64 offset );

View File

@ -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); HRESULT hres = m_symbol->get_value(&vtValue);
if (S_OK != hres) if (S_OK != hres)
throw DiaException("Call IDiaSymbol::get_value", 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" );
}
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -102,7 +102,7 @@ public:
//static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue); //static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue);
//python::object getValue(); //python::object getValue();
void getValue( VARIANT &vtValue); void getValue( BaseTypeVariant &vtValue );
//bool isBasicType(); //bool isBasicType();

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "intbase.h" #include "variant.h"
#include "symengine.h" #include "symengine.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h" #include "typedvar.h"

View File

@ -349,6 +349,10 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
> >
<File
RelativePath=".\cpureg.cpp"
>
</File>
<File <File
RelativePath=".\dbgexcept.cpp" RelativePath=".\dbgexcept.cpp"
> >
@ -431,6 +435,10 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd" Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
> >
<File
RelativePath=".\cpureg.h"
>
</File>
<File <File
RelativePath=".\dbgengine.h" RelativePath=".\dbgengine.h"
> >
@ -443,10 +451,6 @@
RelativePath=".\dbgmem.h" RelativePath=".\dbgmem.h"
> >
</File> </File>
<File
RelativePath=".\intbase.h"
>
</File>
<File <File
RelativePath=".\module.h" RelativePath=".\module.h"
> >
@ -483,6 +487,10 @@
RelativePath=".\vardata.h" RelativePath=".\vardata.h"
> >
</File> </File>
<File
RelativePath=".\variant.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

View File

@ -10,11 +10,12 @@
#include "symengine.h" #include "symengine.h"
#include "module.h" #include "module.h"
#include "intbase.h" #include "variant.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "dbgmem.h" #include "dbgmem.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h" #include "typedvar.h"
#include "cpureg.h"
using namespace pykd; using namespace pykd;
@ -61,6 +62,8 @@ BOOST_PYTHON_MODULE( pykd )
// system properties // system properties
python::def( "ptrSize", &ptrSize, python::def( "ptrSize", &ptrSize,
"Return effective pointer size" ); "Return effective pointer size" );
python::def( "is64bitSystem", &is64bitSystem,
"Check if target system has 64 address space" );
// Manage target memory access // Manage target memory access
@ -143,6 +146,16 @@ BOOST_PYTHON_MODULE( pykd )
"Return instance of the typedVar class. It's value are loaded from the target memory." "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" ); "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
// CPU registers
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" );
python::def ( "rdmsr", &loadMSR,
"Return MSR value" );
python::def( "wrmsr", &setMSR,
"Set MSR value" );
python::class_<intBase>( "intBase", "intBase", python::no_init ) python::class_<intBase>( "intBase", "intBase", python::no_init )
.def( python::init<python::object&>() ) .def( python::init<python::object&>() )
.def( "__eq__", &intBase::eq ) .def( "__eq__", &intBase::eq )
@ -275,6 +288,12 @@ BOOST_PYTHON_MODULE( pykd )
.def("__getitem__", &TypedVar::getElementByIndex ) .def("__getitem__", &TypedVar::getElementByIndex )
.def("__getitem__", &TypedVar::getElementByIndexPtr ); .def("__getitem__", &TypedVar::getElementByIndexPtr );
python::class_<CpuReg, python::bases<intBase> >(
"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 // wrapper for standart python exceptions
python::register_exception_translator<PyException>( &PyException::exceptionTranslate ); python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
@ -301,6 +320,14 @@ BOOST_PYTHON_MODULE( pykd )
//#include <dia2.h> //#include <dia2.h>

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "variant.h"
namespace pykd { namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -128,7 +130,7 @@ public:
virtual ULONG getSymTag() = 0; virtual ULONG getSymTag() = 0;
virtual SymbolPtr getType() = 0; virtual SymbolPtr getType() = 0;
virtual ULONGLONG getVa() = 0; virtual ULONGLONG getVa() = 0;
virtual void getValue( VARIANT &vtValue) = 0; virtual void getValue( BaseTypeVariant &vtValue) = 0;
virtual ULONG getVirtualBaseDispIndex() = 0; virtual ULONG getVirtualBaseDispIndex() = 0;
virtual int getVirtualBasePointerOffset() = 0; virtual int getVirtualBasePointerOffset() = 0;
virtual bool isVirtualBaseClass() = 0; virtual bool isVirtualBaseClass() = 0;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "typeinfo.h" #include "typeinfo.h"
#include "intbase.h" #include "variant.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "vardata.h" #include "vardata.h"

View File

@ -114,34 +114,7 @@ BaseTypeVariant TypeInfo::getValue()
if ( !m_constant ) if ( !m_constant )
throw TypeException( getName(), "this type is not a constant and has not a value" ); throw TypeException( getName(), "this type is not a constant and has not a value" );
switch( m_constantValue.vt ) return m_constantValue;
{
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" );
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -166,9 +139,8 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, const std::string &symN
TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, SymbolPtr &symChild ) TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, SymbolPtr &symChild )
{ {
CComVariant constVal;
SymbolPtr symType = symChild; SymbolPtr symType = symChild;
if ( symType->getSymTag() == SymTagData ) if ( symType->getSymTag() == SymTagData )
{ {
if ( symType->getLocType() == LocIsBitField ) if ( symType->getLocType() == LocIsBitField )
@ -178,18 +150,17 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &symScope, SymbolPtr &symChild )
if ( symType->getDataKind() == DataIsConstant ) if ( symType->getDataKind() == DataIsConstant )
{ {
BaseTypeVariant constVal;
symType->getValue( constVal ); symType->getValue( constVal );
TypeInfoPtr ptr = getTypeInfo( symType->getType() );
ptr->setConstant( constVal );
return ptr;
} }
symType = symType->getType(); symType = symType->getType();
} }
TypeInfoPtr ptr = getTypeInfo( symType ); return getTypeInfo( symType );
if ( constVal.vt != VT_EMPTY )
ptr->setConstant( constVal );
return ptr;
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -766,11 +737,11 @@ python::dict EnumTypeInfo::asMap()
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ ) for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
{ {
CComVariant val; BaseTypeVariant val;
(*it)->getValue( val ); (*it)->getValue( val );
dct[val.ulVal] = (*it)->getName(); dct[ boost::apply_visitor( VariantToULong(), val ) ] = (*it)->getName();
} }
return dct; return dct;
@ -788,11 +759,11 @@ std::string EnumTypeInfo::print()
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ ) for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
{ {
CComVariant val; BaseTypeVariant val;
(*it)->getValue( val ); (*it)->getValue( val );
sstr << " " << (*it)->getName(); 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; sstr << std::endl;
} }

View File

@ -5,7 +5,7 @@
#include <boost\enable_shared_from_this.hpp> #include <boost\enable_shared_from_this.hpp>
#include "udtutils.h" #include "udtutils.h"
#include "intbase.h" #include "variant.h"
#include "symengine.h" #include "symengine.h"
#include "dbgexcept.h" #include "dbgexcept.h"
@ -56,9 +56,7 @@ public:
m_virtualBasePtr( 0 ), m_virtualBasePtr( 0 ),
m_virtualDispIndex( 0 ), m_virtualDispIndex( 0 ),
m_virtualDispSize( 0 ) m_virtualDispSize( 0 )
{ {}
m_constantValue.vt = VT_EMPTY;
}
virtual std::string print() { virtual std::string print() {
std::stringstream sstr; std::stringstream sstr;
@ -156,7 +154,7 @@ public:
throw PyException( PyExc_TypeError, "object is unsubscriptable"); throw PyException( PyExc_TypeError, "object is unsubscriptable");
} }
void setConstant( const VARIANT& var ) void setConstant( const BaseTypeVariant& var )
{ {
m_constant = true; m_constant = true;
m_constantValue = var; m_constantValue = var;
@ -220,7 +218,7 @@ protected:
bool m_virtualMember; bool m_virtualMember;
VARIANT m_constantValue; BaseTypeVariant m_constantValue;
LONG m_virtualBasePtr; LONG m_virtualBasePtr;

View File

@ -60,107 +60,103 @@ ULONG64 VarDataMemory::readPtr() const
VarDataConst::VarDataConst( SymbolPtr &symData) : VarDataConst::VarDataConst( SymbolPtr &symData) :
m_fieldOffset(0) m_fieldOffset(0)
, m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) )
{ {
VARIANT vtValue = {0}; symData->getValue(m_value);
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" );
}
} }
//////////////////////////////////////////////////////////////////////////////// // 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 std::string VarDataConst::asString() const
{ {
return "<constant>"; return "<constant>";
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
ULONG64 VarDataConst::getAddr() const ULONG64 VarDataConst::getAddr() const
{ {
throw DbgException("Constant does not have address"); throw DbgException("Constant does not have address");
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
VarDataPtr VarDataConst::fork(ULONG offset) const VarDataPtr VarDataConst::fork(ULONG offset) const
{ {
return VarDataPtr(new VarDataConst(*this, offset)); return VarDataPtr(new VarDataConst(*this, offset));
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const 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__); throw DbgException("Internal error in " __FUNCTION__);
RtlCopyMemory(buffer, &m_dataBuff->at(offset), length);
RtlCopyMemory(buffer, (char*)&val + offset, length);
} }
////////////////////////////////////////////////////////////////////////////////' //////////////////////////////////////////////////////////////////////////////////'
ULONG64 VarDataConst::readPtr() const ULONG64 VarDataConst::readPtr() const
{ {
ULONG64 val = 0; return boost::apply_visitor( VariantToULong64(), m_value );
const ULONG length = ptrSize();
if (length > m_dataBuff->size())
throw DbgException("Internal error in " __FUNCTION__);
RtlCopyMemory(&val, &m_dataBuff->at(0), length);
return val;
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) : VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) :
m_fieldOffset(from.m_fieldOffset + fieldOffset) m_fieldOffset(from.m_fieldOffset + fieldOffset),
, m_dataBuff(from.m_dataBuff) m_value(from.m_value)
{ {
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
} // end pykd namespace

View File

@ -75,16 +75,21 @@ protected:
VarDataConst(SymbolPtr &symData); VarDataConst(SymbolPtr &symData);
VarDataConst(const VarDataConst &from, ULONG fieldOffset); VarDataConst(const VarDataConst &from, ULONG fieldOffset);
template<typename T> //template<typename T>
void fillDataBuff(const T &data) //void fillDataBuff(const T &data)
{ //{
RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) ); // RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) );
} //}
private: private:
ULONG m_fieldOffset; BaseTypeVariant m_value;
boost::shared_ptr< std::vector<UCHAR> > m_dataBuff; ULONG m_fieldOffset;
//ULONG m_fieldOffset;
//boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
}; };
} }

View File

@ -1,5 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include <boost\algorithm\string\case_conv.hpp>
#include "win/dbgeng.h" #include "win/dbgeng.h"
#include "dbgexcept.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 ) std::string getSymbolByOffset( ULONG64 offset )
{ {
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
@ -344,8 +361,127 @@ std::string getSymbolByOffset( ULONG64 offset )
return symbolName; 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 &regName )
{
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<char> 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

View File

@ -23,6 +23,7 @@ public:
CComQIPtr<IDebugSymbols3> symbols; CComQIPtr<IDebugSymbols3> symbols;
CComQIPtr<IDebugDataSpaces4> dataspace; CComQIPtr<IDebugDataSpaces4> dataspace;
CComQIPtr<IDebugAdvanced2> advanced; CComQIPtr<IDebugAdvanced2> advanced;
CComQIPtr<IDebugRegisters2> registers;
DbgEngBind( PDEBUG_CLIENT4 c ) DbgEngBind( PDEBUG_CLIENT4 c )
{ {
@ -32,6 +33,7 @@ public:
symbols = c; symbols = c;
dataspace = c; dataspace = c;
advanced = c; advanced = c;
registers = c;
} }
PyThreadStateSaver pystate; PyThreadStateSaver pystate;

View File

@ -18,6 +18,7 @@ import memtest
import moduletest import moduletest
import typeinfo import typeinfo
import typedvar import typedvar
import regtest
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -29,6 +30,7 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )