mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53: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 );
|
||||
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 readMemoryUnsafeNoSafe( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE, ULONG *readed = NULL );
|
||||
bool isVaValid( ULONG64 addr );
|
||||
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( dprintln_, dprintln, 1, 2 );
|
||||
@ -90,8 +91,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Start process for debugging");
|
||||
python::def( "attachProcess", &attachProcess,
|
||||
"Attach debugger to a exsisting process" );
|
||||
python::def( "detachProcess", &detachProcess,
|
||||
"Stop process debugging");
|
||||
python::def( "detachProcess", &detachProcess, detachProcess_( boost::python::args( "pid" ),
|
||||
"Stop process debugging") );
|
||||
python::def( "killProcess", &terminateProcess,
|
||||
"Stop debugging and terminate current process" );
|
||||
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;
|
||||
std::vector<DEBUG_STACK_FRAME> dbgFrames(filledFrames);
|
||||
hres = g_dbgEng->control->GetStackTrace( 0, 0, 0, &dbgFrames[0], filledFrames, &filledFrames);
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugControl::GetStackTrace failed" );
|
||||
|
||||
HRESULT hres =
|
||||
g_dbgEng->control->GetStackTrace(
|
||||
frameOffset,
|
||||
stackOffset,
|
||||
instructionOffset,
|
||||
&dbgFrames[0],
|
||||
filledFrames,
|
||||
&filledFrames);
|
||||
if (S_OK != hres)
|
||||
throw DbgException( "IDebugControl::GetStackTrace", hres );
|
||||
|
||||
frames.resize(filledFrames);
|
||||
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)
|
||||
{
|
||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||
|
Loading…
Reference in New Issue
Block a user