mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[0.1.x] +sub-registers in thread context
git-svn-id: https://pykd.svn.codeplex.com/svn@72770 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
c465d4c110
commit
df1c3afb65
159
pykd/context.cpp
159
pykd/context.cpp
@ -145,6 +145,14 @@ Registers::Registers(
|
|||||||
|
|
||||||
ULONG64 Registers::getValue(ULONG cvRegId) const
|
ULONG64 Registers::getValue(ULONG cvRegId) const
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getSubValue(cvRegId);
|
||||||
|
}
|
||||||
|
catch (const IsNotSubRegister &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
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())
|
||||||
throw Exception(__FUNCTION__ ": Register missing");
|
throw Exception(__FUNCTION__ ": Register missing");
|
||||||
@ -155,6 +163,19 @@ ULONG64 Registers::getValue(ULONG cvRegId) const
|
|||||||
|
|
||||||
bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
|
bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
val = getSubValue(cvRegId);
|
||||||
|
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())
|
||||||
return false;
|
return false;
|
||||||
@ -209,6 +230,144 @@ python::object Registers::getByIndex(ULONG ind) const
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct SubRegister {
|
||||||
|
ULONG m_fromReg;
|
||||||
|
ULONG m_bitsShift;
|
||||||
|
ULONG m_bitsMask;
|
||||||
|
|
||||||
|
void set(ULONG fromReg, ULONG bitsShift, ULONG bitsMask)
|
||||||
|
{
|
||||||
|
m_fromReg = fromReg; m_bitsShift = bitsShift; m_bitsMask = bitsMask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static const class SubRegisterMapI386 : public std::map<ULONG, SubRegister> {
|
||||||
|
public:
|
||||||
|
SubRegisterMapI386();
|
||||||
|
} g_SubRegistersI386;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
(*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);
|
||||||
|
|
||||||
|
(*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);
|
||||||
|
|
||||||
|
(*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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static const class SubRegisterMapAmd64 : public std::map<ULONG, SubRegister> {
|
||||||
|
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;
|
||||||
|
if (IMAGE_FILE_MACHINE_I386 == m_processorType)
|
||||||
|
subRegs = &g_SubRegistersI386;
|
||||||
|
else
|
||||||
|
subRegs = &g_SubRegistersAmd64;
|
||||||
|
|
||||||
|
std::map<ULONG, SubRegister>::const_iterator itSubReg =
|
||||||
|
subRegs->find(cvRegId);
|
||||||
|
if (itSubReg == subRegs->end())
|
||||||
|
throw IsNotSubRegister();
|
||||||
|
|
||||||
|
RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg);
|
||||||
|
if (itFullReg == m_regValues.end())
|
||||||
|
throw Exception(__FUNCTION__ ": Register missing");
|
||||||
|
|
||||||
|
return
|
||||||
|
(itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace pykd{
|
||||||
|
std::string processorToStr(ULONG processorMode);
|
||||||
|
}
|
||||||
|
|
||||||
namespace Ctx {
|
namespace Ctx {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -42,8 +46,17 @@ public:
|
|||||||
}
|
}
|
||||||
python::object getByIndex(ULONG ind) const;
|
python::object getByIndex(ULONG ind) const;
|
||||||
|
|
||||||
|
// get processor type
|
||||||
|
std::string getProcessorType() const {
|
||||||
|
return pykd::processorToStr(m_processorType);
|
||||||
|
}
|
||||||
|
|
||||||
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
|
IDebugAdvanced2 *advanced
|
||||||
@ -54,6 +67,9 @@ private:
|
|||||||
IDebugAdvanced2 *advanced
|
IDebugAdvanced2 *advanced
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// try query as "sub-register"
|
||||||
|
ULONG64 getSubValue(ULONG cvRegId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<ULONG, ULONG64> RegValues;
|
typedef std::map<ULONG, ULONG64> RegValues;
|
||||||
RegValues m_regValues;
|
RegValues m_regValues;
|
||||||
|
@ -604,6 +604,8 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get current stack pointer" )
|
"Get current stack pointer" )
|
||||||
.def( "get", &Ctx::Registers::getValue,
|
.def( "get", &Ctx::Registers::getValue,
|
||||||
"Get register value by ID (CV_REG_XXX)" )
|
"Get register value by ID (CV_REG_XXX)" )
|
||||||
|
.def( "processorType", &Ctx::Registers::getProcessorType,
|
||||||
|
"Get processor type as string")
|
||||||
.def("__len__", &Ctx::Registers::getCount,
|
.def("__len__", &Ctx::Registers::getCount,
|
||||||
"Return count of registers")
|
"Return count of registers")
|
||||||
.def("__getitem__", &Ctx::Registers::getByIndex,
|
.def("__getitem__", &Ctx::Registers::getByIndex,
|
||||||
|
@ -78,7 +78,7 @@ getCurrentStack()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static std::string processorToStr(ULONG processorMode)
|
std::string processorToStr(ULONG processorMode)
|
||||||
{
|
{
|
||||||
switch( processorMode )
|
switch( processorMode )
|
||||||
{
|
{
|
||||||
|
@ -26,15 +26,25 @@ class DbgClientTest( unittest.TestCase ):
|
|||||||
ctx = pykd.getContext()
|
ctx = pykd.getContext()
|
||||||
# for reg in ctx:
|
# for reg in ctx:
|
||||||
# regName = ""
|
# regName = ""
|
||||||
# try:
|
# if ctx.processorType() == "X86":
|
||||||
# regName = pykd.diaI386Regs[ reg[0] ]
|
# regName = pykd.diaI386Regs[ reg[0] ]
|
||||||
# except KeyError:
|
# else:
|
||||||
# regName = pykd.diaAmd64Regs[ reg[0] ]
|
# regName = pykd.diaAmd64Regs[ reg[0] ]
|
||||||
# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1])
|
# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1])
|
||||||
self.assertNotEqual( 0, len(ctx) )
|
self.assertNotEqual( 0, len(ctx) )
|
||||||
self.assertNotEqual( 0, ctx.ip() )
|
self.assertNotEqual( 0, ctx.ip() )
|
||||||
self.assertNotEqual( 0, ctx.csp() )
|
self.assertNotEqual( 0, ctx.csp() )
|
||||||
|
|
||||||
|
self.assertEqual( (ctx.get(pykd.CV_REG_AH) << 8) | ctx.get(pykd.CV_REG_AL), ctx.get(pykd.CV_REG_AX) )
|
||||||
|
self.assertEqual( ctx.get(pykd.CV_REG_AX), ctx.get(pykd.CV_REG_EAX) & 0xffff )
|
||||||
|
if ctx.processorType() == "X64":
|
||||||
|
self.assertEqual( ctx.get(pykd.CV_REG_EAX), ctx.get(pykd.CV_AMD64_RAX) & 0xffffffff )
|
||||||
|
|
||||||
|
self.assertEqual( (ctx.get(pykd.CV_REG_DH) << 8) | ctx.get(pykd.CV_REG_DL), ctx.get(pykd.CV_REG_DX) )
|
||||||
|
self.assertEqual( ctx.get(pykd.CV_REG_DX), ctx.get(pykd.CV_REG_EDX) & 0xffff )
|
||||||
|
if ctx.processorType() == "X64":
|
||||||
|
self.assertEqual( ctx.get(pykd.CV_REG_EDX), ctx.get(pykd.CV_AMD64_RDX) & 0xffffffff )
|
||||||
|
|
||||||
def testIsDumpAnalyzing( self ):
|
def testIsDumpAnalyzing( self ):
|
||||||
self.assertFalse( pykd.isDumpAnalyzing() )
|
self.assertFalse( pykd.isDumpAnalyzing() )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user