[0.1.x] added : cpuReg class

[0.1.x] refactored : context.cpp/h

git-svn-id: https://pykd.svn.codeplex.com/svn@73463 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-01-23 07:50:36 +00:00 committed by Mikhail I. Izmestev
parent 1f7f55917c
commit 0768ce3fe3
9 changed files with 311 additions and 256 deletions

View File

@ -7,9 +7,9 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
namespace Ctx { namespace pykd {
///////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace I386 { namespace I386 {
#include "defctxi386.h" #include "defctxi386.h"
@ -17,15 +17,13 @@ namespace I386 {
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void Registers::getI386Context( void ThreadContext::getI386Context()
IDebugAdvanced2 *advanced
)
{ {
I386::CONTEXT Context = {0}; I386::CONTEXT Context = {0};
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context)); HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context));
if (S_OK != hres) 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_DR0] = Context.Dr0;
m_regValues[CV_REG_DR1] = Context.Dr1; m_regValues[CV_REG_DR1] = Context.Dr1;
@ -65,15 +63,13 @@ namespace AMD64 {
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void Registers::getAmd64Context( void ThreadContext::getAmd64Context()
IDebugAdvanced2 *advanced
)
{ {
AMD64::CONTEXT Context = {0}; AMD64::CONTEXT Context = {0};
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context)); HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context));
if (S_OK != hres) if (S_OK != hres)
throw Exception( "IDebugAdvanced2::GetThreadContext", hres); throw DbgException( "IDebugAdvanced2::GetThreadContext", hres);
m_regValues[CV_AMD64_MXCSR] = Context.MxCsr; m_regValues[CV_AMD64_MXCSR] = Context.MxCsr;
@ -115,66 +111,48 @@ void Registers::getAmd64Context(
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
Registers::Registers( ThreadContext::ThreadContext( IDebugClient4 *client ) :
IDebugControl4 *control, pykd::DbgObject( client )
IDebugAdvanced2 *advanced
)
{ {
HRESULT hres = control->GetExecutingProcessorType(&m_processorType); HRESULT hres = m_control->GetExecutingProcessorType(&m_processorType);
if (S_OK != hres) if (S_OK != hres)
throw Exception( "IDebugControl::GetExecutingProcessorType", hres ); throw DbgException( "IDebugControl::GetExecutingProcessorType", hres );
switch (m_processorType) switch (m_processorType)
{ {
case IMAGE_FILE_MACHINE_I386: case IMAGE_FILE_MACHINE_I386:
getI386Context(advanced); getI386Context();
return; return;
case IMAGE_FILE_MACHINE_AMD64: case IMAGE_FILE_MACHINE_AMD64:
getAmd64Context(advanced); getAmd64Context();
return; return;
} }
std::stringstream sstream; std::stringstream sstream;
sstream << __FUNCTION__ << ":\n"; sstream << __FUNCTION__ << ":\n";
sstream << "Unsupported processor type: 0x" << std::hex << m_processorType; 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 ULONG64 val;
{
return getSubValue(cvRegId);
}
catch (const IsNotSubRegister &)
{
}
RegValues::const_iterator it = m_regValues.find(cvRegId); if ( getValueNoThrow( cvRegId, val ) )
if (it == m_regValues.end()) return val;
throw Exception(__FUNCTION__ ": Register missing");
return it->second; throw DbgException(__FUNCTION__ ": Register missing");
} }
///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
{ {
try if ( getSubValue(cvRegId, val ) )
{
val = getSubValue(cvRegId);
return true; return true;
}
catch (const IsNotSubRegister &)
{
}
catch (const Exception &)
{
return false;
}
RegValues::const_iterator it = m_regValues.find(cvRegId); RegValues::const_iterator it = m_regValues.find(cvRegId);
if (it == m_regValues.end()) if (it == m_regValues.end())
@ -184,9 +162,9 @@ bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
return true; return true;
} }
///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getIp() const ULONG64 ThreadContext::getIp() const
{ {
return getValue( return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EIP : CV_AMD64_RIP 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( return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EAX : CV_AMD64_RAX 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( return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_ESP : CV_AMD64_RSP 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(); RegValues::const_iterator it = m_regValues.begin();
for (ULONG i = 0; it != m_regValues.end(); ++i, ++it ) 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); return python::make_tuple(it->first, it->second);
} }
PyErr_SetString(PyExc_IndexError, "Index out of range"); throw PyException( PyExc_IndexError, "Index out of range");
python::throw_error_already_set();
return python::object();
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -243,109 +218,110 @@ struct SubRegister {
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
static const class SubRegisterMapI386 : public std::map<ULONG, SubRegister> {
public: struct SubRegisterMapI386 {
SubRegisterMapI386();
} g_SubRegistersI386; std::map<ULONG, SubRegister> 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<ULONG, SubRegister> g_SubRegistersI386 = SubRegisterMapI386().subRegs;
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
SubRegisterMapI386::SubRegisterMapI386() struct SubRegisterMapAmd64 {
{
(*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);
(*this)[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff); std::map<ULONG, SubRegister> subRegs;
(*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);
(*this)[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff); SubRegisterMapAmd64()
(*this)[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff); {
(*this)[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff); subRegs[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff);
(*this)[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff); 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); subRegs[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff);
(*this)[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff); subRegs[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff);
(*this)[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff); subRegs[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff);
(*this)[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff); 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<ULONG, SubRegister> g_SubRegistersAmd64 = SubRegisterMapAmd64().subRegs;
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
static const class SubRegisterMapAmd64 : public std::map<ULONG, SubRegister> { bool ThreadContext::getSubValue(ULONG cvRegId, ULONG64 &val) const
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
{ {
const std::map<ULONG, SubRegister> *subRegs = NULL; const std::map<ULONG, SubRegister> *subRegs = NULL;
if (IMAGE_FILE_MACHINE_I386 == m_processorType) if (IMAGE_FILE_MACHINE_I386 == m_processorType)
@ -356,18 +332,17 @@ ULONG64 Registers::getSubValue(ULONG cvRegId) const
std::map<ULONG, SubRegister>::const_iterator itSubReg = std::map<ULONG, SubRegister>::const_iterator itSubReg =
subRegs->find(cvRegId); subRegs->find(cvRegId);
if (itSubReg == subRegs->end()) if (itSubReg == subRegs->end())
throw IsNotSubRegister(); return false;
RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg); RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg);
if (itFullReg == m_regValues.end()) if (itFullReg == m_regValues.end())
throw Exception(__FUNCTION__ ": Register missing"); return false;
return val = (itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
(itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
}
// ----------------------------------------------------------------------------
return true;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
}

View File

@ -1,31 +1,24 @@
#pragma once
#include <map> #include <map>
#include <DbgEng.h> #include <DbgEng.h>
#include <CvConst.h> #include <CvConst.h>
#include "context.h"
#include "dbgobj.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#pragma once namespace pykd {
namespace pykd{ std::string processorToStr(ULONG processorMode);
std::string processorToStr(ULONG processorMode);
}
namespace Ctx {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef pykd::DbgException Exception; class ThreadContext : private DbgObject
////////////////////////////////////////////////////////////////////////////////
class Registers
{ {
public: public:
Registers(
IDebugControl4 *control, ThreadContext( IDebugClient4 *client );
IDebugAdvanced2 *advanced
);
// get register value by ID // get register value by ID
ULONG64 getValue(ULONG cvRegId) const; ULONG64 getValue(ULONG cvRegId) const;
@ -44,6 +37,7 @@ public:
ULONG getCount() const { ULONG getCount() const {
return static_cast<ULONG>( m_regValues.size() ); return static_cast<ULONG>( m_regValues.size() );
} }
python::object getByIndex(ULONG ind) const; python::object getByIndex(ULONG ind) const;
// get processor type // get processor type
@ -53,22 +47,14 @@ public:
private: private:
struct IsNotSubRegister : public std::exception {
IsNotSubRegister() : std::exception("is not sub-register") { }
};
// query i386 registers // query i386 registers
void getI386Context( void getI386Context();
IDebugAdvanced2 *advanced
);
// query AMD64 registers // query AMD64 registers
void getAmd64Context( void getAmd64Context();
IDebugAdvanced2 *advanced
);
// try query as "sub-register" // try query as "sub-register"
ULONG64 getSubValue(ULONG cvRegId) const; bool getSubValue(ULONG cvRegId, ULONG64 &val) const;
private: private:
typedef std::map<ULONG, ULONG64> RegValues; typedef std::map<ULONG, ULONG64> RegValues;
@ -79,7 +65,7 @@ private:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef boost::shared_ptr< Registers > ContextPtr; typedef boost::shared_ptr< ThreadContext > ContextPtr;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -7,60 +7,114 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
python::object DebugClient::getRegByIndex( ULONG index ) CpuReg::CpuReg( IDebugClient4 *client, const std::string &regName ) :
DbgObject( client )
{ {
HRESULT hres; HRESULT hres;
DEBUG_VALUE debugValue; m_name = regName;
hres = m_registers->GetValue( index, &debugValue );
hres = m_registers->GetIndexByName( m_name.c_str(), &m_index );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetValue failed" ); throw DbgException( "IDebugRegister::GetIndexByName", hres );
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 );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
CpuReg::CpuReg( IDebugClient4 *client, ULONG index ) :
python::object DebugClient::getRegByName( const std::wstring &regName ) 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(), &registerIndex );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugRegister2::GetIndexByNameWide failed" ); throw DbgException( "IDebugRegister::GetDescription", hres );
return getRegByIndex( registerIndex ); std::vector<char> nameBuffer(nameSize);
}
python::object getRegByName( const std::wstring &regName ) 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 &regName )
{
return CpuReg( m_client, regName );
}
CpuReg getRegByName( const std::string &regName )
{
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 ); hres = m_dataSpaces->ReadMsr( msr, &value );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpaces::ReadMsr failed" ); throw DbgException( "IDebugDataSpaces::ReadMsr", hres );
return value; return value;
} }
@ -90,7 +144,7 @@ void DebugClient::setMSR( ULONG msr, ULONG64 value)
hres = m_dataSpaces->WriteMsr(msr, value); hres = m_dataSpaces->WriteMsr(msr, value);
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpaces::WriteMsr failed" ); throw DbgException( "IDebugDataSpaces::WriteMsr", hres );
} }
void setMSR( ULONG msr, ULONG64 value) void setMSR( ULONG msr, ULONG64 value)

View File

@ -7,9 +7,37 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
python::object getRegByName( const std::wstring &regName ); class CpuReg : public intBase, protected DbgObject {
python::object getRegByIndex( ULONG index ); public:
CpuReg( IDebugClient4 *client, const std::string &regName );
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 &regName );
CpuReg getRegByIndex( ULONG index );
ULONG64 loadMSR( ULONG msr ); ULONG64 loadMSR( ULONG msr );

View File

@ -210,9 +210,9 @@ public:
void setMSR( ULONG msr, ULONG64 value); void setMSR( ULONG msr, ULONG64 value);
python::object getRegByName( const std::wstring &regName ); CpuReg getRegByName( const std::string &regName );
python::object getRegByIndex( ULONG index ); CpuReg getRegByIndex( ULONG index );
void setCurrentProcess( ULONG64 addr ); void setCurrentProcess( ULONG64 addr );
@ -234,14 +234,12 @@ public:
return getDbgControl(GetPageSize); return getDbgControl(GetPageSize);
} }
Ctx::ContextPtr getThreadContext() { ContextPtr getThreadContext() {
return Ctx::ContextPtr( return ContextPtr( new ThreadContext(m_client) );
new Ctx::Registers(m_control, m_advanced)
);
} }
python::dict getLocals( python::dict getLocals(
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) ) ContextPtr ctx = ContextPtr( reinterpret_cast<ThreadContext*>(0) )
); );
public: public:
@ -397,12 +395,12 @@ inline ULONG getPageSize() {
return g_dbgClient->getPageSize(); return g_dbgClient->getPageSize();
} }
inline Ctx::ContextPtr getThreadContext() { inline ContextPtr getThreadContext() {
return g_dbgClient->getThreadContext(); return g_dbgClient->getThreadContext();
} }
inline python::dict getLocals( inline python::dict getLocals(
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) ) ContextPtr ctx = ContextPtr()
) )
{ {
return g_dbgClient->getLocals(ctx); return g_dbgClient->getLocals(ctx);

View File

@ -143,7 +143,8 @@ BOOST_PYTHON_MODULE( pykd )
.def( "__long__", &intBase::long_ ) .def( "__long__", &intBase::long_ )
.def( "__int__", &intBase::int_ ) .def( "__int__", &intBase::int_ )
.def( "__index__", &intBase::long_ ) .def( "__index__", &intBase::long_ )
.def( "__hash__", &intBase::long_ ); .def( "__hash__", &intBase::long_ )
.def( "__coerce__", &intBase::coerce );
python::class_<DebugClient, DebugClientPtr>("dbgClient", "Class representing a debugging session", python::no_init ) python::class_<DebugClient, DebugClientPtr>("dbgClient", "Class representing a debugging session", python::no_init )
.def( "addr64", &DebugClient::addr64, .def( "addr64", &DebugClient::addr64,
@ -442,11 +443,11 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "ptrSize", &ptrSize, python::def( "ptrSize", &ptrSize,
"Return effective pointer size" ); "Return effective pointer size" );
python::def ( "rdmsr", &DebugClient::loadMSR, python::def ( "rdmsr", &DebugClient::loadMSR,
"Return MSR value" ); "Return MSR value" );
python::def( "reg", &getRegByName, python::def( "reg", &getRegByName,
"Return a CPU regsiter value by the register's name" ); "Return a CPU regsiter value by the register's name" );
python::def( "reg", &getRegByIndex, 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, python::def( "setExecutionStatus", &setExecutionStatus,
"Requests that the debugger engine enter an executable state" ); "Requests that the debugger engine enter an executable state" );
python::def( "setCurrentProcess", &setCurrentProcess, 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( "ea", &Disasm::ea, "Return effective address for last disassembled instruction or 0" )
.def( "reset", &Disasm::reset, "Reset current offset to begin" ); .def( "reset", &Disasm::reset, "Reset current offset to begin" );
python::class_<DEBUG_STACK_FRAME>( "stackFrame", python::class_<DEBUG_STACK_FRAME>( "stackFrame",
"Class representing a frame of the call satck", python::no_init ) "Class representing a frame of the call satck", python::no_init )
.def_readonly( "instructionOffset", &DEBUG_STACK_FRAME::InstructionOffset, .def_readonly( "instructionOffset", &DEBUG_STACK_FRAME::InstructionOffset,
"Return a frame's instruction offset" ) "Return a frame's instruction offset" )
@ -612,23 +613,28 @@ BOOST_PYTHON_MODULE( pykd )
.def_readonly( "frameNumber", &DEBUG_STACK_FRAME::FrameNumber, .def_readonly( "frameNumber", &DEBUG_STACK_FRAME::FrameNumber,
"Return a frame's number" ); "Return a frame's number" );
python::class_<Ctx::Registers, Ctx::ContextPtr>( python::class_<ThreadContext, ContextPtr>(
"Context", "Context of thread (register values)", python::no_init ) "Context", "Context of thread (register values)", python::no_init )
.def( "ip", &Ctx::Registers::getIp, .def( "ip", &ThreadContext::getIp,
"Get instruction pointer register" ) "Get instruction pointer register" )
.def( "retreg", &Ctx::Registers::getIp, .def( "retreg", &ThreadContext::getIp,
"Get primary return value register" ) "Get primary return value register" )
.def( "csp", &Ctx::Registers::getSp, .def( "csp", &ThreadContext::getSp,
"Get current stack pointer" ) "Get current stack pointer" )
.def( "get", &Ctx::Registers::getValue, .def( "get", &ThreadContext::getValue,
"Get register value by ID (CV_REG_XXX)" ) "Get register value by ID (CV_REG_XXX)" )
.def( "processorType", &Ctx::Registers::getProcessorType, .def( "processorType", &ThreadContext::getProcessorType,
"Get processor type as string") "Get processor ThreadContext as string")
.def("__len__", &Ctx::Registers::getCount, .def("__len__", &ThreadContext::getCount,
"Return count of registers") "Return count of registers")
.def("__getitem__", &Ctx::Registers::getByIndex, .def("__getitem__", &ThreadContext::getByIndex,
"Return tuple<ID, VALUE> by index"); "Return tuple<ID, VALUE> by index");
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" );
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
"Open pdb file for querying debug symbols. Return DiaSymbol of global scope"); "Open pdb file for querying debug symbols. Return DiaSymbol of global scope");

View File

@ -185,6 +185,11 @@ public:
return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0; return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0;
} }
python::object coerce() {
__debugbreak();
return python::object();
}
private: private:
virtual BaseTypeVariant getValue() { virtual BaseTypeVariant getValue() {

View File

@ -19,7 +19,7 @@ struct addLocals {
python::dict &m_locals; python::dict &m_locals;
const Module &m_module; const Module &m_module;
ULONG m_rva; ULONG m_rva;
Ctx::ContextPtr m_ctx; ContextPtr m_ctx;
IDebugClient4 *m_client; IDebugClient4 *m_client;
ULONG m_formalNameCounter; 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) if (!ctx)
ctx = getThreadContext(); ctx = getThreadContext();

View File

@ -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_STR2__(x) #x
#define __VER_STR1__(x) __VER_STR2__(x) #define __VER_STR1__(x) __VER_STR2__(x)
#define PYKD_VERSION_MAJOR 1 #define PYKD_VERSION_BUILD PYKD_VERSION_MAJOR, PYKD_VERSION_MINOR, PYKD_VERSION_SUBVERSION, PYKD_VERSION_BUILDNO
#define PYKD_VERSION_MINOR 6
#define PYKD_VERSION_BUILD 0,PYKD_VERSION_MAJOR,0,PYKD_VERSION_MINOR
#define PYKD_VERSION_BUILD_STR __VER_STR1__(PYKD_VERSION_BUILD) #define PYKD_VERSION_BUILD_STR __VER_STR1__(PYKD_VERSION_BUILD)