mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[0.1.x] + getWow64Context
git-svn-id: https://pykd.svn.codeplex.com/svn@77588 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
f225f3905e
commit
8ee1e65535
145
pykd/context.cpp
145
pykd/context.cpp
@ -10,7 +10,46 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Fill 32-bit register context
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename TContext>
|
||||||
|
void FillRegistersFromContext32(
|
||||||
|
ThreadContext::RegValues ®Values,
|
||||||
|
const TContext &Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
regValues[CV_REG_DR0] = Context.Dr0;
|
||||||
|
regValues[CV_REG_DR1] = Context.Dr1;
|
||||||
|
regValues[CV_REG_DR2] = Context.Dr2;
|
||||||
|
regValues[CV_REG_DR3] = Context.Dr3;
|
||||||
|
regValues[CV_REG_DR6] = Context.Dr6;
|
||||||
|
regValues[CV_REG_DR7] = Context.Dr7;
|
||||||
|
|
||||||
|
regValues[CV_REG_GS] = Context.SegGs;
|
||||||
|
regValues[CV_REG_FS] = Context.SegFs;
|
||||||
|
regValues[CV_REG_ES] = Context.SegEs;
|
||||||
|
regValues[CV_REG_DS] = Context.SegDs;
|
||||||
|
|
||||||
|
regValues[CV_REG_EDI] = Context.Edi;
|
||||||
|
regValues[CV_REG_ESI] = Context.Esi;
|
||||||
|
regValues[CV_REG_EBX] = Context.Ebx;
|
||||||
|
regValues[CV_REG_EDX] = Context.Edx;
|
||||||
|
regValues[CV_REG_ECX] = Context.Ecx;
|
||||||
|
regValues[CV_REG_EAX] = Context.Eax;
|
||||||
|
|
||||||
|
regValues[CV_REG_EBP] = Context.Ebp;
|
||||||
|
|
||||||
|
regValues[CV_REG_ESP] = Context.Esp;
|
||||||
|
regValues[CV_REG_SS] = Context.SegSs;
|
||||||
|
|
||||||
|
regValues[CV_REG_EIP] = Context.Eip;
|
||||||
|
regValues[CV_REG_CS] = Context.SegCs;
|
||||||
|
|
||||||
|
regValues[CV_REG_EFLAGS] = Context.EFlags;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace I386 {
|
namespace I386 {
|
||||||
@ -27,34 +66,7 @@ void ThreadContext::getI386Context()
|
|||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
throw DbgException( "IDebugAdvanced2::GetThreadContext", hres );
|
throw DbgException( "IDebugAdvanced2::GetThreadContext", hres );
|
||||||
|
|
||||||
m_regValues[CV_REG_DR0] = Context.Dr0;
|
FillRegistersFromContext32(m_regValues, Context);
|
||||||
m_regValues[CV_REG_DR1] = Context.Dr1;
|
|
||||||
m_regValues[CV_REG_DR2] = Context.Dr2;
|
|
||||||
m_regValues[CV_REG_DR3] = Context.Dr3;
|
|
||||||
m_regValues[CV_REG_DR6] = Context.Dr6;
|
|
||||||
m_regValues[CV_REG_DR7] = Context.Dr7;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_GS] = Context.SegGs;
|
|
||||||
m_regValues[CV_REG_FS] = Context.SegFs;
|
|
||||||
m_regValues[CV_REG_ES] = Context.SegEs;
|
|
||||||
m_regValues[CV_REG_DS] = Context.SegDs;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_EDI] = Context.Edi;
|
|
||||||
m_regValues[CV_REG_ESI] = Context.Esi;
|
|
||||||
m_regValues[CV_REG_EBX] = Context.Ebx;
|
|
||||||
m_regValues[CV_REG_EDX] = Context.Edx;
|
|
||||||
m_regValues[CV_REG_ECX] = Context.Ecx;
|
|
||||||
m_regValues[CV_REG_EAX] = Context.Eax;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_EBP] = Context.Ebp;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_ESP] = Context.Esp;
|
|
||||||
m_regValues[CV_REG_SS] = Context.SegSs;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_EIP] = Context.Eip;
|
|
||||||
m_regValues[CV_REG_CS] = Context.SegCs;
|
|
||||||
|
|
||||||
m_regValues[CV_REG_EFLAGS] = Context.EFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -136,6 +148,81 @@ ThreadContext::ThreadContext( IDebugClient4 *client ) :
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ThreadContext::ThreadContext(
|
||||||
|
IDebugClient4 *client,
|
||||||
|
ULONG processorType
|
||||||
|
) : pykd::DbgObject(client)
|
||||||
|
, m_processorType(processorType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ContextPtr ThreadContext::getWow64Context( IDebugClient4 *client )
|
||||||
|
{
|
||||||
|
ContextPtr ptrContext( new ThreadContext(client, IMAGE_FILE_MACHINE_I386) );
|
||||||
|
|
||||||
|
ULONG processorType;
|
||||||
|
HRESULT hres = ptrContext->m_control->GetEffectiveProcessorType(&processorType);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugControl::GetEffectiveProcessorType", hres );
|
||||||
|
if (IMAGE_FILE_MACHINE_I386 != processorType)
|
||||||
|
throw DbgException( "Only for WOW64 processor mode" );
|
||||||
|
|
||||||
|
hres = ptrContext->m_control->GetActualProcessorType(&processorType);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugControl::GetActualProcessorType", hres );
|
||||||
|
if (IMAGE_FILE_MACHINE_AMD64 != processorType)
|
||||||
|
throw DbgException( "Only for WOW64 processor mode" );
|
||||||
|
|
||||||
|
//
|
||||||
|
// *** undoc ***
|
||||||
|
// !wow64exts.r
|
||||||
|
// http://www.woodmann.com/forum/archive/index.php/t-11162.html
|
||||||
|
// http://www.nynaeve.net/Code/GetThreadWow64Context.cpp
|
||||||
|
//
|
||||||
|
|
||||||
|
ULONG64 teb64Address;
|
||||||
|
hres = ptrContext->m_system->GetCurrentThreadTeb(&teb64Address);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugSystemObjects::GetCurrentThreadTeb", hres);
|
||||||
|
|
||||||
|
// ? @@C++(#FIELD_OFFSET(nt!_TEB64, TlsSlots))
|
||||||
|
// hardcoded in !wow64exts.r (6.2.8250.0)
|
||||||
|
static const ULONG teb64ToTlsOffset = 0x01480;
|
||||||
|
static const ULONG WOW64_TLS_CPURESERVED = 1;
|
||||||
|
ULONG64 cpuAreaAddress;
|
||||||
|
ULONG readedBytes;
|
||||||
|
hres =
|
||||||
|
ptrContext->m_dataSpaces->ReadVirtual(
|
||||||
|
teb64Address + teb64ToTlsOffset + (sizeof(ULONG64) * WOW64_TLS_CPURESERVED),
|
||||||
|
&cpuAreaAddress,
|
||||||
|
sizeof(cpuAreaAddress),
|
||||||
|
&readedBytes);
|
||||||
|
if (S_OK != hres || readedBytes != sizeof(cpuAreaAddress))
|
||||||
|
throw DbgException( "IDebugDataSpaces::ReadVirtual", hres);
|
||||||
|
|
||||||
|
// CPU Area is:
|
||||||
|
// +00 unknown ULONG
|
||||||
|
// +04 WOW64_CONTEXT struct
|
||||||
|
static const ULONG cpuAreaToWow64ContextOffset = sizeof(ULONG);
|
||||||
|
WOW64_CONTEXT Context = {0};
|
||||||
|
hres =
|
||||||
|
ptrContext->m_dataSpaces->ReadVirtual(
|
||||||
|
cpuAreaAddress + cpuAreaToWow64ContextOffset,
|
||||||
|
&Context,
|
||||||
|
sizeof(Context),
|
||||||
|
&readedBytes);
|
||||||
|
if (S_OK != hres || readedBytes != sizeof(Context))
|
||||||
|
throw DbgException( "IDebugDataSpaces::ReadVirtual", hres);
|
||||||
|
|
||||||
|
FillRegistersFromContext32(ptrContext->m_regValues, Context);
|
||||||
|
|
||||||
|
return ptrContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG64 ThreadContext::getValue(ULONG cvRegId) const
|
ULONG64 ThreadContext::getValue(ULONG cvRegId) const
|
||||||
{
|
{
|
||||||
ULONG64 val;
|
ULONG64 val;
|
||||||
|
@ -26,7 +26,10 @@ std::string processorToStr(ULONG processorMode);
|
|||||||
class ThreadContext : private DbgObject
|
class ThreadContext : private DbgObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::map<ULONG, ULONG64> RegValues;
|
||||||
|
|
||||||
ThreadContext( IDebugClient4 *client );
|
ThreadContext( IDebugClient4 *client );
|
||||||
|
static ContextPtr getWow64Context( IDebugClient4 *client );
|
||||||
|
|
||||||
// get register value by ID
|
// get register value by ID
|
||||||
ULONG64 getValue(ULONG cvRegId) const;
|
ULONG64 getValue(ULONG cvRegId) const;
|
||||||
@ -58,7 +61,11 @@ public:
|
|||||||
|
|
||||||
std::string print() const;
|
std::string print() const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
ThreadContext(
|
||||||
|
IDebugClient4 *client,
|
||||||
|
ULONG processorType
|
||||||
|
);
|
||||||
|
|
||||||
// query i386 registers
|
// query i386 registers
|
||||||
void getI386Context();
|
void getI386Context();
|
||||||
@ -72,7 +79,6 @@ private:
|
|||||||
void __declspec(noreturn) throwUnsupportedProcessor(PCSTR szFunction) const;
|
void __declspec(noreturn) throwUnsupportedProcessor(PCSTR szFunction) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<ULONG, ULONG64> RegValues;
|
|
||||||
RegValues m_regValues;
|
RegValues m_regValues;
|
||||||
|
|
||||||
ULONG m_processorType;
|
ULONG m_processorType;
|
||||||
|
@ -254,6 +254,9 @@ public:
|
|||||||
ContextPtr getThreadContext() {
|
ContextPtr getThreadContext() {
|
||||||
return ContextPtr( new ThreadContext(m_client) );
|
return ContextPtr( new ThreadContext(m_client) );
|
||||||
}
|
}
|
||||||
|
ContextPtr getThreadWow64Context() {
|
||||||
|
return ThreadContext::getWow64Context(m_client);
|
||||||
|
}
|
||||||
|
|
||||||
python::dict getLocals(
|
python::dict getLocals(
|
||||||
ContextPtr ctx = ContextPtr( reinterpret_cast<ThreadContext*>(0) )
|
ContextPtr ctx = ContextPtr( reinterpret_cast<ThreadContext*>(0) )
|
||||||
@ -472,6 +475,10 @@ inline ContextPtr getThreadContext() {
|
|||||||
return g_dbgClient->getThreadContext();
|
return g_dbgClient->getThreadContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ContextPtr getThreadWow64Context() {
|
||||||
|
return g_dbgClient->getThreadWow64Context();
|
||||||
|
}
|
||||||
|
|
||||||
inline python::dict getLocals(
|
inline python::dict getLocals(
|
||||||
ContextPtr ctx = ContextPtr()
|
ContextPtr ctx = ContextPtr()
|
||||||
)
|
)
|
||||||
|
@ -322,6 +322,9 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get the page size for the currently executing processor context" )
|
"Get the page size for the currently executing processor context" )
|
||||||
.def( "getContext", &DebugClient::getThreadContext,
|
.def( "getContext", &DebugClient::getThreadContext,
|
||||||
"Get context of current thread (register values)" )
|
"Get context of current thread (register values)" )
|
||||||
|
.def( "getWow64Context", &DebugClient::getThreadWow64Context,
|
||||||
|
"Get WOW64-context of current thread (register values)\n"
|
||||||
|
"!wow64exts.r analog")
|
||||||
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
||||||
"Get list of local variables" ) )
|
"Get list of local variables" ) )
|
||||||
.def( "setBp", &DebugClient::setSoftwareBp, DebugClient_setSoftwareBp( python::args( "offset", "callback" ),
|
.def( "setBp", &DebugClient::setSoftwareBp, DebugClient_setSoftwareBp( python::args( "offset", "callback" ),
|
||||||
@ -523,6 +526,9 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get the page size for the currently executing processor context" );
|
"Get the page size for the currently executing processor context" );
|
||||||
python::def( "getContext", &getThreadContext,
|
python::def( "getContext", &getThreadContext,
|
||||||
"Get context of current thread (register values)" );
|
"Get context of current thread (register values)" );
|
||||||
|
python::def( "getWow64Context", &getThreadWow64Context,
|
||||||
|
"Get WOW64-context of current thread (register values)\n"
|
||||||
|
"!wow64exts.r analog" );
|
||||||
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
||||||
"Get list of local variables" ) );
|
"Get list of local variables" ) );
|
||||||
python::def( "setBp", &setSoftwareBp, setSoftwareBp_( python::args( "offset", "callback" ),
|
python::def( "setBp", &setSoftwareBp, setSoftwareBp_( python::args( "offset", "callback" ),
|
||||||
@ -719,7 +725,6 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def("__str__", &ThreadContext::print,
|
.def("__str__", &ThreadContext::print,
|
||||||
"Return context as a string" );
|
"Return context as a string" );
|
||||||
|
|
||||||
|
|
||||||
python::class_<CpuReg, python::bases<intBase> >(
|
python::class_<CpuReg, python::bases<intBase> >(
|
||||||
"cpuReg", "CPU regsiter class", boost::python::no_init )
|
"cpuReg", "CPU regsiter class", boost::python::no_init )
|
||||||
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
||||||
|
Loading…
Reference in New Issue
Block a user