mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 21:03:23 +08:00
[0.2.x] + getStackTraceWow64 implementation
git-svn-id: https://pykd.svn.codeplex.com/svn@81742 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
3e2969ab6a
commit
bba6f842ed
@ -8,6 +8,7 @@ ULONG64 addr64( ULONG64 offset );
|
|||||||
ULONG64 addr64NoSafe( ULONG64 addr );
|
ULONG64 addr64NoSafe( ULONG64 addr );
|
||||||
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
||||||
bool readMemoryUnsafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
bool readMemoryUnsafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
||||||
|
bool readMemoryUnsafeNoSafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
||||||
bool isVaValid( ULONG64 addr );
|
bool isVaValid( ULONG64 addr );
|
||||||
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
|
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ static const std::string pykdVersion = PYKD_VERSION_BUILD_STR
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_, detachProcess, 0, 1 );
|
||||||
|
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, dprint, 1, 2 );
|
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, dprint, 1, 2 );
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 );
|
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 );
|
||||||
@ -90,8 +91,8 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Start process for debugging");
|
"Start process for debugging");
|
||||||
python::def( "attachProcess", &attachProcess,
|
python::def( "attachProcess", &attachProcess,
|
||||||
"Attach debugger to a exsisting process" );
|
"Attach debugger to a exsisting process" );
|
||||||
python::def( "detachProcess", &detachProcess,
|
python::def( "detachProcess", &detachProcess, detachProcess_( boost::python::args( "pid" ),
|
||||||
"Stop process debugging");
|
"Stop process debugging") );
|
||||||
python::def( "killProcess", &terminateProcess,
|
python::def( "killProcess", &terminateProcess,
|
||||||
"Stop debugging and terminate current process" );
|
"Stop debugging and terminate current process" );
|
||||||
python::def( "loadDump", &loadDump,
|
python::def( "loadDump", &loadDump,
|
||||||
|
@ -726,16 +726,25 @@ ULONG64 getRegInstructionPointer()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
|
static void buildStacksFrames(
|
||||||
|
std::vector<STACK_FRAME_DESC> &frames,
|
||||||
|
ULONG64 frameOffset = 0,
|
||||||
|
ULONG64 stackOffset = 0,
|
||||||
|
ULONG64 instructionOffset = 0)
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
||||||
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG filledFrames = 1024;
|
ULONG filledFrames = 1024;
|
||||||
std::vector<DEBUG_STACK_FRAME> dbgFrames(filledFrames);
|
std::vector<DEBUG_STACK_FRAME> dbgFrames(filledFrames);
|
||||||
hres = g_dbgEng->control->GetStackTrace( 0, 0, 0, &dbgFrames[0], filledFrames, &filledFrames);
|
|
||||||
if ( FAILED( hres ) )
|
HRESULT hres =
|
||||||
throw DbgException( "IDebugControl::GetStackTrace failed" );
|
g_dbgEng->control->GetStackTrace(
|
||||||
|
frameOffset,
|
||||||
|
stackOffset,
|
||||||
|
instructionOffset,
|
||||||
|
&dbgFrames[0],
|
||||||
|
filledFrames,
|
||||||
|
&filledFrames);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugControl::GetStackTrace", hres );
|
||||||
|
|
||||||
frames.resize(filledFrames);
|
frames.resize(filledFrames);
|
||||||
for ( ULONG i = 0; i < filledFrames; ++i )
|
for ( ULONG i = 0; i < filledFrames; ++i )
|
||||||
@ -750,11 +759,121 @@ void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
frames.resize(0);
|
||||||
|
|
||||||
|
buildStacksFrames(frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void ReadWow64Context(WOW64_CONTEXT &Context)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// *** undoc ***
|
||||||
|
// !wow64exts.r
|
||||||
|
// http://www.woodmann.com/forum/archive/index.php/t-11162.html
|
||||||
|
// http://www.nynaeve.net/Code/GetThreadWow64Context.cpp
|
||||||
|
//
|
||||||
|
|
||||||
|
ULONG64 teb64Address;
|
||||||
|
HRESULT hres = g_dbgEng->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;
|
||||||
|
|
||||||
|
bool readRes;
|
||||||
|
readRes =
|
||||||
|
readMemoryUnsafeNoSafe(
|
||||||
|
teb64Address + teb64ToTlsOffset + (sizeof(ULONG64) * WOW64_TLS_CPURESERVED),
|
||||||
|
&cpuAreaAddress,
|
||||||
|
sizeof(cpuAreaAddress),
|
||||||
|
false,
|
||||||
|
&readedBytes);
|
||||||
|
if (!readRes || readedBytes != sizeof(cpuAreaAddress))
|
||||||
|
throw DbgException( "IDebugDataSpaces::ReadVirtual", hres);
|
||||||
|
|
||||||
|
// CPU Area is:
|
||||||
|
// +00 unknown ULONG
|
||||||
|
// +04 WOW64_CONTEXT struct
|
||||||
|
static const ULONG cpuAreaToWow64ContextOffset = sizeof(ULONG);
|
||||||
|
readRes =
|
||||||
|
readMemoryUnsafeNoSafe(
|
||||||
|
cpuAreaAddress + cpuAreaToWow64ContextOffset,
|
||||||
|
&Context,
|
||||||
|
sizeof(Context),
|
||||||
|
false,
|
||||||
|
&readedBytes);
|
||||||
|
if (!readRes || readedBytes != sizeof(Context))
|
||||||
|
throw DbgException( "IDebugDataSpaces::ReadVirtual", hres);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class AutoRevertEffectiveProcessorType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoRevertEffectiveProcessorType()
|
||||||
|
: m_processType(IMAGE_FILE_MACHINE_UNKNOWN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoRevertEffectiveProcessorType()
|
||||||
|
{
|
||||||
|
if (IMAGE_FILE_MACHINE_UNKNOWN != m_processType)
|
||||||
|
BOOST_VERIFY(S_OK == g_dbgEng->control->SetEffectiveProcessorType(m_processType));
|
||||||
|
}
|
||||||
|
|
||||||
|
void to(ULONG processType) { m_processType = processType; }
|
||||||
|
private:
|
||||||
|
ULONG m_processType;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void getStackTraceWow64(std::vector<STACK_FRAME_DESC> &frames)
|
void getStackTraceWow64(std::vector<STACK_FRAME_DESC> &frames)
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
frames.resize(0);
|
frames.resize(0);
|
||||||
|
|
||||||
|
ULONG processorType;
|
||||||
|
HRESULT hres = g_dbgEng->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" );
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->GetEffectiveProcessorType(&processorType);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugControl::GetEffectiveProcessorType", hres );
|
||||||
|
|
||||||
|
AutoRevertEffectiveProcessorType autoRevertEffectiveProcessorType;
|
||||||
|
if (IMAGE_FILE_MACHINE_I386 != processorType)
|
||||||
|
{
|
||||||
|
if (IMAGE_FILE_MACHINE_AMD64 != processorType)
|
||||||
|
throw DbgException( "Only for WOW64 processor mode" );
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->SetEffectiveProcessorType(IMAGE_FILE_MACHINE_I386);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DbgException( "IDebugControl::SetEffectiveProcessorType", hres );
|
||||||
|
|
||||||
|
autoRevertEffectiveProcessorType.to(IMAGE_FILE_MACHINE_AMD64);
|
||||||
|
}
|
||||||
|
|
||||||
|
WOW64_CONTEXT Context;
|
||||||
|
ReadWow64Context(Context);
|
||||||
|
|
||||||
|
buildStacksFrames(frames, Context.Ebp, Context.Esp, Context.Eip);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -95,10 +95,8 @@ void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr, ULONG
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool readMemoryUnsafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr, ULONG *readed )
|
bool readMemoryUnsafeNoSafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr, ULONG *readed )
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
||||||
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
if ( phyAddr == false )
|
if ( phyAddr == false )
|
||||||
{
|
{
|
||||||
@ -122,6 +120,14 @@ bool readMemoryUnsafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr,
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool readMemoryUnsafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr, ULONG *readed )
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
return readMemoryUnsafeNoSafe(offset, buffer, length, phyAddr, readed);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string loadCStr( ULONG64 offset )
|
std::string loadCStr( ULONG64 offset )
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
Loading…
Reference in New Issue
Block a user