mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +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
|
||||
{
|
||||
try
|
||||
{
|
||||
return getSubValue(cvRegId);
|
||||
}
|
||||
catch (const IsNotSubRegister &)
|
||||
{
|
||||
}
|
||||
|
||||
RegValues::const_iterator it = m_regValues.find(cvRegId);
|
||||
if (it == m_regValues.end())
|
||||
throw Exception(__FUNCTION__ ": Register missing");
|
||||
@ -155,6 +163,19 @@ ULONG64 Registers::getValue(ULONG cvRegId) 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);
|
||||
if (it == m_regValues.end())
|
||||
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
|
||||
|
||||
namespace pykd{
|
||||
std::string processorToStr(ULONG processorMode);
|
||||
}
|
||||
|
||||
namespace Ctx {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -42,8 +46,17 @@ public:
|
||||
}
|
||||
python::object getByIndex(ULONG ind) const;
|
||||
|
||||
// get processor type
|
||||
std::string getProcessorType() const {
|
||||
return pykd::processorToStr(m_processorType);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct IsNotSubRegister : public std::exception {
|
||||
IsNotSubRegister() : std::exception("is not sub-register") { }
|
||||
};
|
||||
|
||||
// query i386 registers
|
||||
void getI386Context(
|
||||
IDebugAdvanced2 *advanced
|
||||
@ -54,6 +67,9 @@ private:
|
||||
IDebugAdvanced2 *advanced
|
||||
);
|
||||
|
||||
// try query as "sub-register"
|
||||
ULONG64 getSubValue(ULONG cvRegId) const;
|
||||
|
||||
private:
|
||||
typedef std::map<ULONG, ULONG64> RegValues;
|
||||
RegValues m_regValues;
|
||||
|
@ -604,6 +604,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Get current stack pointer" )
|
||||
.def( "get", &Ctx::Registers::getValue,
|
||||
"Get register value by ID (CV_REG_XXX)" )
|
||||
.def( "processorType", &Ctx::Registers::getProcessorType,
|
||||
"Get processor type as string")
|
||||
.def("__len__", &Ctx::Registers::getCount,
|
||||
"Return count of registers")
|
||||
.def("__getitem__", &Ctx::Registers::getByIndex,
|
||||
|
@ -78,7 +78,7 @@ getCurrentStack()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static std::string processorToStr(ULONG processorMode)
|
||||
std::string processorToStr(ULONG processorMode)
|
||||
{
|
||||
switch( processorMode )
|
||||
{
|
||||
|
@ -26,15 +26,25 @@ class DbgClientTest( unittest.TestCase ):
|
||||
ctx = pykd.getContext()
|
||||
# for reg in ctx:
|
||||
# regName = ""
|
||||
# try:
|
||||
# if ctx.processorType() == "X86":
|
||||
# regName = pykd.diaI386Regs[ reg[0] ]
|
||||
# except KeyError:
|
||||
# else:
|
||||
# regName = pykd.diaAmd64Regs[ reg[0] ]
|
||||
# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1])
|
||||
self.assertNotEqual( 0, len(ctx) )
|
||||
self.assertNotEqual( 0, ctx.ip() )
|
||||
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 ):
|
||||
self.assertFalse( pykd.isDumpAnalyzing() )
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user