mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 20:03:33 +08:00
[0.1.x] + context of current thread
git-svn-id: https://pykd.svn.codeplex.com/svn@72757 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
932fc93926
commit
380410a521
214
pykd/context.cpp
Normal file
214
pykd/context.cpp
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <boost\python\tuple.hpp>
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Ctx {
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace I386 {
|
||||||
|
#include "defctxi386.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Registers::getI386Context(
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
)
|
||||||
|
{
|
||||||
|
I386::CONTEXT Context = {0};
|
||||||
|
|
||||||
|
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context));
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception( pykd::buildExceptDesc("IDebugAdvanced2::GetThreadContext", hres) );
|
||||||
|
|
||||||
|
m_regValues[CV_REG_DR0] = Context.Dr0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace AMD64 {
|
||||||
|
#include "defctxamd64.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Registers::getAmd64Context(
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AMD64::CONTEXT Context = {0};
|
||||||
|
|
||||||
|
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context));
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception( pykd::buildExceptDesc("IDebugAdvanced2::GetThreadContext", hres) );
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_MXCSR] = Context.MxCsr;
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_CS] = Context.SegCs;
|
||||||
|
m_regValues[CV_AMD64_DS] = Context.SegDs;
|
||||||
|
m_regValues[CV_AMD64_ES] = Context.SegEs;
|
||||||
|
m_regValues[CV_AMD64_FS] = Context.SegFs;
|
||||||
|
m_regValues[CV_AMD64_GS] = Context.SegGs;
|
||||||
|
m_regValues[CV_AMD64_SS] = Context.SegSs;
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_EFLAGS] = Context.EFlags;
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_DR0] = Context.Dr0;
|
||||||
|
m_regValues[CV_AMD64_DR1] = Context.Dr1;
|
||||||
|
m_regValues[CV_AMD64_DR2] = Context.Dr2;
|
||||||
|
m_regValues[CV_AMD64_DR3] = Context.Dr3;
|
||||||
|
m_regValues[CV_AMD64_DR6] = Context.Dr6;
|
||||||
|
m_regValues[CV_AMD64_DR7] = Context.Dr7;
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_RAX] = Context.Rax;
|
||||||
|
m_regValues[CV_AMD64_RCX] = Context.Rcx;
|
||||||
|
m_regValues[CV_AMD64_RDX] = Context.Rdx;
|
||||||
|
m_regValues[CV_AMD64_RBX] = Context.Rbx;
|
||||||
|
m_regValues[CV_AMD64_RSP] = Context.Rsp;
|
||||||
|
m_regValues[CV_AMD64_RBP] = Context.Rbp;
|
||||||
|
m_regValues[CV_AMD64_RSI] = Context.Rdi;
|
||||||
|
m_regValues[CV_AMD64_RDI] = Context.Rdi;
|
||||||
|
m_regValues[CV_AMD64_R8] = Context.R8;
|
||||||
|
m_regValues[CV_AMD64_R9] = Context.R9;
|
||||||
|
m_regValues[CV_AMD64_R10] = Context.R10;
|
||||||
|
m_regValues[CV_AMD64_R11] = Context.R11;
|
||||||
|
m_regValues[CV_AMD64_R12] = Context.R12;
|
||||||
|
m_regValues[CV_AMD64_R13] = Context.R13;
|
||||||
|
m_regValues[CV_AMD64_R14] = Context.R14;
|
||||||
|
m_regValues[CV_AMD64_R15] = Context.R15;
|
||||||
|
|
||||||
|
m_regValues[CV_AMD64_RIP] = Context.Rip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Registers::Registers(
|
||||||
|
IDebugControl4 *control,
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hres = control->GetExecutingProcessorType(&m_processorType);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception( pykd::buildExceptDesc("IDebugControl::GetExecutingProcessorType", hres) );
|
||||||
|
|
||||||
|
switch (m_processorType)
|
||||||
|
{
|
||||||
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
|
getI386Context(advanced);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
|
getAmd64Context(advanced);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream sstream;
|
||||||
|
sstream << __FUNCTION__ << ":\n";
|
||||||
|
sstream << "Unsupported processor type: 0x" << std::hex << m_processorType;
|
||||||
|
throw Exception( sstream.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG64 Registers::getValue(ULONG cvRegId) const
|
||||||
|
{
|
||||||
|
RegValues::const_iterator it = m_regValues.find(cvRegId);
|
||||||
|
if (it == m_regValues.end())
|
||||||
|
throw Exception(__FUNCTION__ ": Register missing");
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
|
||||||
|
{
|
||||||
|
RegValues::const_iterator it = m_regValues.find(cvRegId);
|
||||||
|
if (it == m_regValues.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
val = it->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG64 Registers::getIp() const
|
||||||
|
{
|
||||||
|
return getValue(
|
||||||
|
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EIP : CV_AMD64_RIP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG64 Registers::getRetReg() const
|
||||||
|
{
|
||||||
|
return getValue(
|
||||||
|
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EAX : CV_AMD64_RAX
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG64 Registers::getSp() const
|
||||||
|
{
|
||||||
|
return getValue(
|
||||||
|
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_ESP : CV_AMD64_RSP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::object Registers::getByIndex(ULONG ind) const
|
||||||
|
{
|
||||||
|
RegValues::const_iterator it = m_regValues.begin();
|
||||||
|
for (ULONG i = 0; it != m_regValues.end(); ++i, ++it )
|
||||||
|
{
|
||||||
|
if (i == ind)
|
||||||
|
return python::make_tuple(it->first, it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_SetString(PyExc_IndexError, "Index out of range");
|
||||||
|
python::throw_error_already_set();
|
||||||
|
|
||||||
|
return python::object();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
71
pykd/context.h
Normal file
71
pykd/context.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <DbgEng.h>
|
||||||
|
#include <CvConst.h>
|
||||||
|
|
||||||
|
#include "dbgexcept.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Ctx {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef pykd::DbgException Exception;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Registers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Registers(
|
||||||
|
IDebugControl4 *control,
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
);
|
||||||
|
|
||||||
|
// get register value by ID
|
||||||
|
ULONG64 getValue(ULONG cvRegId) const;
|
||||||
|
bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const;
|
||||||
|
|
||||||
|
// get @$ip pseudo register
|
||||||
|
ULONG64 getIp() const;
|
||||||
|
|
||||||
|
// get @$retreg pseudo register
|
||||||
|
ULONG64 getRetReg() const;
|
||||||
|
|
||||||
|
// get @$csp pseudo register
|
||||||
|
ULONG64 getSp() const;
|
||||||
|
|
||||||
|
// enumerate register values: tuple<CV_REG_ID, VALUE>
|
||||||
|
ULONG getCount() const {
|
||||||
|
return static_cast<ULONG>( m_regValues.size() );
|
||||||
|
}
|
||||||
|
python::object getByIndex(ULONG ind) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// query i386 registers
|
||||||
|
void getI386Context(
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
);
|
||||||
|
|
||||||
|
// query AMD64 registers
|
||||||
|
void getAmd64Context(
|
||||||
|
IDebugAdvanced2 *advanced
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<ULONG, ULONG64> RegValues;
|
||||||
|
RegValues m_regValues;
|
||||||
|
|
||||||
|
ULONG m_processorType;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef boost::shared_ptr< Registers > ContextPtr;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
|||||||
#include "cpureg.h"
|
#include "cpureg.h"
|
||||||
#include "inteventhandler.h"
|
#include "inteventhandler.h"
|
||||||
#include "synsymbol.h"
|
#include "synsymbol.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -233,6 +234,12 @@ public:
|
|||||||
return getDbgControl(GetPageSize);
|
return getDbgControl(GetPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ctx::ContextPtr getThreadContext() {
|
||||||
|
return Ctx::ContextPtr(
|
||||||
|
new Ctx::Registers(m_control, m_advanced)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CComPtr<IDebugClient4>&
|
CComPtr<IDebugClient4>&
|
||||||
@ -387,6 +394,10 @@ inline ULONG getPageSize() {
|
|||||||
return g_dbgClient->getPageSize();
|
return g_dbgClient->getPageSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Ctx::ContextPtr getThreadContext() {
|
||||||
|
return g_dbgClient->getThreadContext();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<ULONG status>
|
template<ULONG status>
|
||||||
|
@ -283,6 +283,8 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get the number of actual processors in the machine" )
|
"Get the number of actual processors in the machine" )
|
||||||
.def( "getPageSize", &DebugClient::getPageSize,
|
.def( "getPageSize", &DebugClient::getPageSize,
|
||||||
"Get the page size for the currently executing processor context" )
|
"Get the page size for the currently executing processor context" )
|
||||||
|
.def( "getContext", &DebugClient::getThreadContext,
|
||||||
|
"Get context of current thread (register values)" )
|
||||||
.def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
|
.def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
|
||||||
"Add new synthetic symbol for virtual address" )
|
"Add new synthetic symbol for virtual address" )
|
||||||
.def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols,
|
.def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols,
|
||||||
@ -454,6 +456,8 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get the number of actual processors in the machine" );
|
"Get the number of actual processors in the machine" );
|
||||||
python::def( "getPageSize", &getPageSize,
|
python::def( "getPageSize", &getPageSize,
|
||||||
"Get the page size for the currently executing processor context" );
|
"Get the page size for the currently executing processor context" );
|
||||||
|
python::def( "getContext", &getThreadContext,
|
||||||
|
"Get context of current thread (register values)" );
|
||||||
|
|
||||||
python::class_<TypeInfo, TypeInfoPtr, python::bases<intBase>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
python::class_<TypeInfo, TypeInfoPtr, python::bases<intBase>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
||||||
.def( "name", &TypeInfo::getName )
|
.def( "name", &TypeInfo::getName )
|
||||||
@ -586,6 +590,21 @@ 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>(
|
||||||
|
"Context", "Context of thread (register values)", python::no_init )
|
||||||
|
.def( "ip", &Ctx::Registers::getIp,
|
||||||
|
"Get instruction pointer register" )
|
||||||
|
.def( "retreg", &Ctx::Registers::getIp,
|
||||||
|
"Get primary return value register" )
|
||||||
|
.def( "csp", &Ctx::Registers::getSp,
|
||||||
|
"Get current stack pointer" )
|
||||||
|
.def( "get", &Ctx::Registers::getValue,
|
||||||
|
"Get register value by ID (CV_REG_XXX)" )
|
||||||
|
.def("__len__", &Ctx::Registers::getCount,
|
||||||
|
"Return count of registers")
|
||||||
|
.def("__getitem__", &Ctx::Registers::getByIndex,
|
||||||
|
"Return tuple<ID, VALUE> by index");
|
||||||
|
|
||||||
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
|
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
|
||||||
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
|
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
|
||||||
|
|
||||||
|
95
pykd/defctxamd64.h
Normal file
95
pykd/defctxamd64.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
struct DECLSPEC_ALIGN(16) M128A {
|
||||||
|
ULONGLONG Low;
|
||||||
|
LONGLONG High;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XMM_SAVE_AREA32 {
|
||||||
|
USHORT ControlWord;
|
||||||
|
USHORT StatusWord;
|
||||||
|
UCHAR TagWord;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
USHORT ErrorOpcode;
|
||||||
|
ULONG ErrorOffset;
|
||||||
|
USHORT ErrorSelector;
|
||||||
|
USHORT Reserved2;
|
||||||
|
ULONG DataOffset;
|
||||||
|
USHORT DataSelector;
|
||||||
|
USHORT Reserved3;
|
||||||
|
ULONG MxCsr;
|
||||||
|
ULONG MxCsr_Mask;
|
||||||
|
M128A FloatRegisters[8];
|
||||||
|
M128A XmmRegisters[16];
|
||||||
|
UCHAR Reserved4[96];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DECLSPEC_ALIGN(16) CONTEXT {
|
||||||
|
ULONG64 P1Home;
|
||||||
|
ULONG64 P2Home;
|
||||||
|
ULONG64 P3Home;
|
||||||
|
ULONG64 P4Home;
|
||||||
|
ULONG64 P5Home;
|
||||||
|
ULONG64 P6Home;
|
||||||
|
ULONG ContextFlags;
|
||||||
|
ULONG MxCsr;
|
||||||
|
USHORT SegCs;
|
||||||
|
USHORT SegDs;
|
||||||
|
USHORT SegEs;
|
||||||
|
USHORT SegFs;
|
||||||
|
USHORT SegGs;
|
||||||
|
USHORT SegSs;
|
||||||
|
ULONG EFlags;
|
||||||
|
ULONG64 Dr0;
|
||||||
|
ULONG64 Dr1;
|
||||||
|
ULONG64 Dr2;
|
||||||
|
ULONG64 Dr3;
|
||||||
|
ULONG64 Dr6;
|
||||||
|
ULONG64 Dr7;
|
||||||
|
ULONG64 Rax;
|
||||||
|
ULONG64 Rcx;
|
||||||
|
ULONG64 Rdx;
|
||||||
|
ULONG64 Rbx;
|
||||||
|
ULONG64 Rsp;
|
||||||
|
ULONG64 Rbp;
|
||||||
|
ULONG64 Rsi;
|
||||||
|
ULONG64 Rdi;
|
||||||
|
ULONG64 R8;
|
||||||
|
ULONG64 R9;
|
||||||
|
ULONG64 R10;
|
||||||
|
ULONG64 R11;
|
||||||
|
ULONG64 R12;
|
||||||
|
ULONG64 R13;
|
||||||
|
ULONG64 R14;
|
||||||
|
ULONG64 R15;
|
||||||
|
ULONG64 Rip;
|
||||||
|
union {
|
||||||
|
XMM_SAVE_AREA32 FltSave;
|
||||||
|
struct {
|
||||||
|
M128A Header[2];
|
||||||
|
M128A Legacy[8];
|
||||||
|
M128A Xmm0;
|
||||||
|
M128A Xmm1;
|
||||||
|
M128A Xmm2;
|
||||||
|
M128A Xmm3;
|
||||||
|
M128A Xmm4;
|
||||||
|
M128A Xmm5;
|
||||||
|
M128A Xmm6;
|
||||||
|
M128A Xmm7;
|
||||||
|
M128A Xmm8;
|
||||||
|
M128A Xmm9;
|
||||||
|
M128A Xmm10;
|
||||||
|
M128A Xmm11;
|
||||||
|
M128A Xmm12;
|
||||||
|
M128A Xmm13;
|
||||||
|
M128A Xmm14;
|
||||||
|
M128A Xmm15;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
M128A VectorRegister[26];
|
||||||
|
ULONG64 VectorControl;
|
||||||
|
ULONG64 DebugControl;
|
||||||
|
ULONG64 LastBranchToRip;
|
||||||
|
ULONG64 LastBranchFromRip;
|
||||||
|
ULONG64 LastExceptionToRip;
|
||||||
|
ULONG64 LastExceptionFromRip;
|
||||||
|
};
|
54
pykd/defctxi386.h
Normal file
54
pykd/defctxi386.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#define MAXIMUM_SUPPORTED_EXTENSION 512
|
||||||
|
|
||||||
|
#define SIZE_OF_80387_REGISTERS 80
|
||||||
|
|
||||||
|
struct FLOATING_SAVE_AREA {
|
||||||
|
ULONG ControlWord;
|
||||||
|
ULONG StatusWord;
|
||||||
|
ULONG TagWord;
|
||||||
|
ULONG ErrorOffset;
|
||||||
|
ULONG ErrorSelector;
|
||||||
|
ULONG DataOffset;
|
||||||
|
ULONG DataSelector;
|
||||||
|
UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];
|
||||||
|
ULONG Cr0NpxState;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CONTEXT {
|
||||||
|
|
||||||
|
ULONG ContextFlags;
|
||||||
|
|
||||||
|
ULONG Dr0;
|
||||||
|
ULONG Dr1;
|
||||||
|
ULONG Dr2;
|
||||||
|
ULONG Dr3;
|
||||||
|
ULONG Dr6;
|
||||||
|
ULONG Dr7;
|
||||||
|
|
||||||
|
|
||||||
|
FLOATING_SAVE_AREA FloatSave;
|
||||||
|
|
||||||
|
|
||||||
|
ULONG SegGs;
|
||||||
|
ULONG SegFs;
|
||||||
|
ULONG SegEs;
|
||||||
|
ULONG SegDs;
|
||||||
|
|
||||||
|
ULONG Edi;
|
||||||
|
ULONG Esi;
|
||||||
|
ULONG Ebx;
|
||||||
|
ULONG Edx;
|
||||||
|
ULONG Ecx;
|
||||||
|
ULONG Eax;
|
||||||
|
|
||||||
|
ULONG Ebp;
|
||||||
|
ULONG Eip;
|
||||||
|
ULONG SegCs;
|
||||||
|
ULONG EFlags;
|
||||||
|
ULONG Esp;
|
||||||
|
ULONG SegSs;
|
||||||
|
|
||||||
|
UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="windows-1251"?>
|
<?xml version="1.0" encoding="windows-1251"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9,00"
|
Version="9.00"
|
||||||
Name="pykd"
|
Name="pykd"
|
||||||
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
||||||
RootNamespace="pykd"
|
RootNamespace="pykd"
|
||||||
@ -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=".\context.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\cpureg.cpp"
|
RelativePath=".\cpureg.cpp"
|
||||||
>
|
>
|
||||||
@ -475,6 +479,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=".\context.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\cpureg.h"
|
RelativePath=".\cpureg.h"
|
||||||
>
|
>
|
||||||
@ -511,6 +519,14 @@
|
|||||||
RelativePath=".\dbgpath.h"
|
RelativePath=".\dbgpath.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\defctxamd64.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\defctxi386.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\diaregs.h"
|
RelativePath=".\diaregs.h"
|
||||||
>
|
>
|
||||||
|
@ -21,6 +21,20 @@ class DbgClientTest( unittest.TestCase ):
|
|||||||
"""Size of memory page must be >= 4kb"""
|
"""Size of memory page must be >= 4kb"""
|
||||||
self.assertTrue( pykd.getPageSize() >= 4*1024 )
|
self.assertTrue( pykd.getPageSize() >= 4*1024 )
|
||||||
|
|
||||||
|
def testCurrentThreadContext( self ):
|
||||||
|
"""Some check of current thread context content"""
|
||||||
|
ctx = pykd.getContext()
|
||||||
|
# for reg in ctx:
|
||||||
|
# regName = ""
|
||||||
|
# try:
|
||||||
|
# regName = pykd.diaI386Regs[ reg[0] ]
|
||||||
|
# except KeyError:
|
||||||
|
# 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() )
|
||||||
|
|
||||||
def testIsDumpAnalyzing( self ):
|
def testIsDumpAnalyzing( self ):
|
||||||
self.assertFalse( pykd.isDumpAnalyzing() )
|
self.assertFalse( pykd.isDumpAnalyzing() )
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#pragma pack( push, 4 )
|
#pragma pack( push, 4 )
|
||||||
|
|
||||||
const ULONG g_constNumValue = 0x5555;
|
const ULONG g_constNumValue = 0x5555;
|
||||||
@ -160,6 +162,10 @@ listStruct1 g_listItem11 = { 100 };
|
|||||||
listStruct1 g_listItem12 = { 200 };
|
listStruct1 g_listItem12 = { 200 };
|
||||||
listStruct1 g_listItem13 = { 300 };
|
listStruct1 g_listItem13 = { 300 };
|
||||||
|
|
||||||
|
#pragma pack( pop )
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define InitializeListHead(ListHead) (\
|
#define InitializeListHead(ListHead) (\
|
||||||
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
|
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
|
||||||
|
|
||||||
@ -174,6 +180,8 @@ listStruct1 g_listItem13 = { 300 };
|
|||||||
_EX_ListHead->Blink = (Entry);\
|
_EX_ListHead->Blink = (Entry);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void FuncWithName0()
|
void FuncWithName0()
|
||||||
{
|
{
|
||||||
classChild _classChild;
|
classChild _classChild;
|
||||||
@ -212,6 +220,8 @@ void FuncWithName0()
|
|||||||
std::cout << g_classChild.m_enumField;
|
std::cout << g_classChild.m_enumField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void FuncWithName1(int a)
|
void FuncWithName1(int a)
|
||||||
{
|
{
|
||||||
unionTest _unionTest[2] = {0};
|
unionTest _unionTest[2] = {0};
|
||||||
@ -227,49 +237,23 @@ void FuncWithName1(int a)
|
|||||||
std::cout << g_string;
|
std::cout << g_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuncWithVolatileArg(volatile long *arg1)
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
{
|
|
||||||
InterlockedIncrement(arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CALLBACK EnumWindowsProc(
|
BOOL CALLBACK EnumWindowsProc(
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
LPARAM lParam
|
LPARAM lParam
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
DWORD dwProccessId = 0;
|
||||||
if (hWindow)
|
if (hWindow)
|
||||||
std::cout << lParam;
|
std::cout << lParam;
|
||||||
|
|
||||||
switch(lParam)
|
|
||||||
{
|
{
|
||||||
case 1:
|
DWORD dwThreadId = ::GetWindowThreadProcessId(hWindow, &dwProccessId);
|
||||||
std::cout << "case 1";
|
std::cout << dwProccessId << dwThreadId;
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
std::cout << "case 2";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
std::cout << "case 2";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
DWORD dwProccessId = 0;
|
|
||||||
DWORD dwThreadId = ::GetWindowThreadProcessId(hWindow, &dwProccessId);
|
|
||||||
std::cout << dwProccessId << dwThreadId;
|
|
||||||
classWithDestructor classInstance(dwProccessId);
|
|
||||||
std::cout << GetWindowLong(hWindow, GWL_STYLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack( pop )
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int doLoadUnload()
|
int doLoadUnload()
|
||||||
@ -328,3 +312,4 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user