[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:
SND\EreTIk_cp 2012-12-10 09:39:22 +00:00 committed by Mikhail I. Izmestev
parent 3e2969ab6a
commit bba6f842ed
4 changed files with 139 additions and 12 deletions

View File

@ -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 );

View File

@ -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,

View File

@ -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);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -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 );