pykd/pykd/context.cpp
2017-11-08 17:42:50 +04:00

586 lines
21 KiB
C++

#include "stdafx.h"
#include <boost\python\tuple.hpp>
#include <boost\algorithm\string\case_conv.hpp>
#include "context.h"
#include "stkframe.h"
#include "dbgmem.h"
/////////////////////////////////////////////////////////////////////////////////
namespace pykd {
//////////////////////////////////////////////////////////////////////////////////
//// Fill 32-bit register context
//////////////////////////////////////////////////////////////////////////////////
//template <typename TContext>
//void FillRegistersFromContext32(
// ThreadContext::RegValues &regValues,
// 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;
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//struct CvRegName
//{
// CvRegName(CV_HREG_e cvValue, const std::string &name)
// : m_cvValue( cvValue ), m_name( boost::to_lower_copy(name) )
// {
// }
// CV_HREG_e m_cvValue;
// std::string m_name;
//};
//#define _REG_NAME(prefix, regName) CvRegName(CV_##prefix##regName, #regName)
//
///////////////////////////////////////////////////////////////////////////////////
//#define _REG_X86(regName) _REG_NAME(REG_, regName)
//static const CvRegName g_x86Registers[] = {
// _REG_X86(DR0), _REG_X86(DR1), _REG_X86(DR2), _REG_X86(DR3), _REG_X86(DR6), _REG_X86(DR7),
// _REG_X86(GS), _REG_X86(FS), _REG_X86(ES), _REG_X86(DS),
// _REG_X86(EDI), _REG_X86(EBX), _REG_X86(EDX), _REG_X86(ECX), _REG_X86(EAX),
// _REG_X86(EBP), _REG_X86(ESP), _REG_X86(SS),
// _REG_X86(EIP), _REG_X86(CS),
// CvRegName(CV_REG_EFLAGS, "efl")
//};
//#undef _REG_X86
//
///////////////////////////////////////////////////////////////////////////////////
//#define _REG_X64(regName) _REG_NAME(AMD64_, regName)
//static const CvRegName g_x64Registers[] = {
// _REG_X64(MXCSR),
// _REG_X64(CS), _REG_X64(DS), _REG_X64(ES), _REG_X64(FS), _REG_X64(GS), _REG_X64(SS),
//
// _REG_X64(DR0), _REG_X64(DR1), _REG_X64(DR2), _REG_X64(DR3), _REG_X64(DR6), _REG_X64(DR7),
//
// _REG_X64(RAX), _REG_X64(RCX), _REG_X64(RDX), _REG_X64(RBX), _REG_X64(RSP), _REG_X64(RBP), _REG_X64(RSI), _REG_X64(RDI),
// _REG_X64(R8), _REG_X64(R9), _REG_X64(R10), _REG_X64(R11), _REG_X64(R12), _REG_X64(R13), _REG_X64(R14), _REG_X64(R15),
//
// _REG_X64(RIP),
// CvRegName(CV_AMD64_EFLAGS, "efl")
//};
//#undef _REG_X64
//
//#undef _REG_NAME
//
///////////////////////////////////////////////////////////////////////////////////
//
//void ThreadContext::getI386Context()
//{
// queryRegisters(g_x86Registers, _countof(g_x86Registers));
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void ThreadContext::getAmd64Context()
//{
// queryRegisters(g_x64Registers, _countof(g_x64Registers));
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ThreadContext::ThreadContext( IDebugClient4 *client ) :
// pykd::DbgObject( client )
//{
// HRESULT hres = m_control->GetEffectiveProcessorType(&m_processorType);
// if (S_OK != hres)
// throw DbgException( "IDebugControl::GetEffectiveProcessorType", hres );
//
// switch (m_processorType)
// {
// case IMAGE_FILE_MACHINE_I386:
// getI386Context();
// return;
//
// case IMAGE_FILE_MACHINE_AMD64:
// getAmd64Context();
// return;
// }
//
// throwUnsupportedProcessor(__FUNCTION__);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ThreadContext::ThreadContext(
// IDebugClient4 *client,
// ULONG processorType
//) : pykd::DbgObject(client)
// , m_processorType(processorType)
//{
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void ThreadContext::queryRegisters(
// const CvRegName *regs,
// ULONG countOfRegs
//)
//{
// HRESULT hres;
//
// std::vector<ULONG> regIndices( countOfRegs );
//
// for (ULONG i = 0; i < countOfRegs; ++i)
// {
// hres = m_registers->GetIndexByName(regs[i].m_name.c_str(), &regIndices[i]);
// if (S_OK != hres)
// throw DbgException( "IDebugRegisters::GetIndexByName", hres);
// }
//
// std::vector<DEBUG_VALUE> regValues( countOfRegs );
// hres =
// m_registers->GetValues(
// static_cast<ULONG>(countOfRegs),
// &regIndices[0],
// 0,
// &regValues[0]);
// if (S_OK != hres)
// throw DbgException( "IDebugRegisters::GetValues", hres);
//
// for (ULONG i = 0; i < countOfRegs; ++i)
// {
// const DEBUG_VALUE &regValue = regValues[i];
// switch (regValue.Type)
// {
// case DEBUG_VALUE_INT8:
// m_regValues[regs[i].m_cvValue] = regValue.I8;
// break;
// case DEBUG_VALUE_INT16:
// m_regValues[regs[i].m_cvValue] = regValue.I16;
// break;
// case DEBUG_VALUE_INT32:
// m_regValues[regs[i].m_cvValue] = regValue.I32;
// break;
// case DEBUG_VALUE_INT64:
// m_regValues[regs[i].m_cvValue] = regValue.I64;
// break;
// }
// }
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//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 =
// readVirtual(
// ptrContext->m_dataSpaces,
// 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 =
// readVirtual(
// ptrContext->m_dataSpaces,
// 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 val;
//
// if ( getValueNoThrow( cvRegId, val ) )
// return val;
//
// throw DbgException(__FUNCTION__ ": Register missing");
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG64 ThreadContext::getValueByName( const std::string &regName ) const
//{
// std::string upcaseName = boost::to_upper_copy( regName );
//
// if ( IMAGE_FILE_MACHINE_I386 == m_processorType )
// {
// for ( ULONG i = 0; i < pyDia::Symbol::cntI386RegName; ++i )
// {
// if ( upcaseName == pyDia::Symbol::i386RegName[i].second )
// return getValue( pyDia::Symbol::i386RegName[i].first );
// }
// }
// else
// {
// for ( ULONG i = 0; i < pyDia::Symbol::cntAmd64RegName; ++i )
// {
// if ( upcaseName == pyDia::Symbol::amd64RegName[i].second )
// return getValue( pyDia::Symbol::amd64RegName[i].first );
// }
// }
//
// throwUnsupportedProcessor(__FUNCTION__);
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
//{
// if ( getSubValue(cvRegId, val ) )
// return true;
//
// RegValues::const_iterator it = m_regValues.find(cvRegId);
// if (it == m_regValues.end())
// return false;
//
// val = it->second;
// return true;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG64 ThreadContext::getIp() const
//{
// return getValue(
// IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EIP : CV_AMD64_RIP
// );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG64 ThreadContext::getRetReg() const
//{
// return getValue(
// IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EAX : CV_AMD64_RAX
// );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG64 ThreadContext::getSp() const
//{
// return getValue(
// IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_ESP : CV_AMD64_RSP
// );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ContextPtr ThreadContext::forkByStackFrame(const StackFrame &stkFrmae) const
//{
// ContextPtr newContext( new ThreadContext(*this) );
// switch (m_processorType)
// {
// case IMAGE_FILE_MACHINE_I386:
// newContext->m_regValues[CV_REG_EIP] = stkFrmae.m_instructionOffset;
// newContext->m_regValues[CV_REG_EBP] = stkFrmae.m_frameOffset;
// newContext->m_regValues[CV_REG_ESP] = stkFrmae.m_stackOffset;
// return newContext;
//
// case IMAGE_FILE_MACHINE_AMD64:
// newContext->m_regValues[CV_AMD64_RIP] = stkFrmae.m_instructionOffset;
// newContext->m_regValues[CV_AMD64_RBP] = stkFrmae.m_frameOffset;
// newContext->m_regValues[CV_AMD64_RSP] = stkFrmae.m_stackOffset;
// return newContext;
// }
//
// throwUnsupportedProcessor(__FUNCTION__);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//python::object ThreadContext::getByIndex(ULONG ind) const
//{
// RegValues::const_iterator it = m_regValues.begin();
// for (ULONG i = 0; it != m_regValues.end(); ++i, ++it )
// {
// if (i == ind)
// {
// switch (m_processorType)
// {
// case IMAGE_FILE_MACHINE_I386:
//
// for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j )
// if ( pyDia::Symbol::i386RegName[j].first == it->first )
// return python::make_tuple( it->first, pyDia::Symbol::i386RegName[j].second, it->second);
//
// break;
//
//
// case IMAGE_FILE_MACHINE_AMD64:
//
// for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j )
// if ( pyDia::Symbol::amd64RegName[j].first == it->first )
// return python::make_tuple( it->first, pyDia::Symbol::amd64RegName[j].second, it->second);
//
// break;
// }
// }
// }
//
// throw PyException( PyExc_IndexError, "Index out of range");
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//struct SubRegister {
// ULONG m_fromReg;
// ULONG m_bitsShift;
// ULONG m_bitsMask;
//
// void set(ULONG fromReg, ULONG bitsShift, ULONG bitsMask)
// {
// m_fromReg = fromReg; m_bitsShift = bitsShift; m_bitsMask = bitsMask;
// }
//};
//
///////////////////////////////////////////////////////////////////////////////////
//
//
//struct SubRegisterMapI386 {
//
// std::map<ULONG, SubRegister> subRegs;
//
// SubRegisterMapI386()
// {
// subRegs[CV_REG_AL].set(CV_REG_EAX, 0x00, 0xff);
// subRegs[CV_REG_CL].set(CV_REG_ECX, 0x00, 0xff);
// subRegs[CV_REG_DL].set(CV_REG_EDX, 0x00, 0xff);
// subRegs[CV_REG_BL].set(CV_REG_EBX, 0x00, 0xff);
//
// subRegs[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff);
// subRegs[CV_REG_CH].set(CV_REG_ECX, 0x08, 0xff);
// subRegs[CV_REG_DH].set(CV_REG_EDX, 0x08, 0xff);
// subRegs[CV_REG_BH].set(CV_REG_EBX, 0x08, 0xff);
//
// subRegs[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff);
// subRegs[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff);
// subRegs[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff);
// subRegs[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff);
//
// subRegs[CV_REG_SP].set(CV_REG_ESP, 0x00, 0xffff);
// subRegs[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff);
// subRegs[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff);
// subRegs[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff);
// }
//
//};
//
//static const std::map<ULONG, SubRegister> g_SubRegistersI386 = SubRegisterMapI386().subRegs;
//
///////////////////////////////////////////////////////////////////////////////////
//
//struct SubRegisterMapAmd64 {
//
// std::map<ULONG, SubRegister> subRegs;
//
// SubRegisterMapAmd64()
// {
// subRegs[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff);
// subRegs[CV_AMD64_CL].set(CV_AMD64_RCX, 0x00, 0xff);
// subRegs[CV_AMD64_DL].set(CV_AMD64_RDX, 0x00, 0xff);
// subRegs[CV_AMD64_BL].set(CV_AMD64_RBX, 0x00, 0xff);
//
// subRegs[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff);
// subRegs[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff);
// subRegs[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff);
// subRegs[CV_AMD64_BH].set(CV_AMD64_RBX, 0x08, 0xff);
//
// subRegs[CV_AMD64_AX].set(CV_AMD64_RAX, 0x00, 0xffff);
// subRegs[CV_AMD64_CX].set(CV_AMD64_RCX, 0x00, 0xffff);
// subRegs[CV_AMD64_DX].set(CV_AMD64_RDX, 0x00, 0xffff);
// subRegs[CV_AMD64_BX].set(CV_AMD64_RBX, 0x00, 0xffff);
//
// subRegs[CV_AMD64_SP].set(CV_AMD64_RSP, 0x00, 0xffff);
// subRegs[CV_AMD64_BP].set(CV_AMD64_RBP, 0x00, 0xffff);
// subRegs[CV_AMD64_SI].set(CV_AMD64_RSI, 0x00, 0xffff);
// subRegs[CV_AMD64_DI].set(CV_AMD64_RDI, 0x00, 0xffff);
//
// subRegs[CV_AMD64_EAX].set(CV_AMD64_RAX, 0x00, 0xffffffff);
// subRegs[CV_AMD64_ECX].set(CV_AMD64_RCX, 0x00, 0xffffffff);
// subRegs[CV_AMD64_EDX].set(CV_AMD64_RDX, 0x00, 0xffffffff);
// subRegs[CV_AMD64_EBX].set(CV_AMD64_RBX, 0x00, 0xffffffff);
//
// subRegs[CV_AMD64_ESP].set(CV_AMD64_RSP, 0x00, 0xffffffff);
// subRegs[CV_AMD64_EBP].set(CV_AMD64_RBP, 0x00, 0xffffffff);
// subRegs[CV_AMD64_ESI].set(CV_AMD64_RSI, 0x00, 0xffffffff);
// subRegs[CV_AMD64_EDI].set(CV_AMD64_RDI, 0x00, 0xffffffff);
//
// subRegs[CV_AMD64_R8B].set(CV_AMD64_R8, 0x00, 0xff);
// subRegs[CV_AMD64_R9B].set(CV_AMD64_R9, 0x00, 0xff);
// subRegs[CV_AMD64_R10B].set(CV_AMD64_R10, 0x00, 0xff);
// subRegs[CV_AMD64_R11B].set(CV_AMD64_R11, 0x00, 0xff);
// subRegs[CV_AMD64_R12B].set(CV_AMD64_R12, 0x00, 0xff);
// subRegs[CV_AMD64_R13B].set(CV_AMD64_R13, 0x00, 0xff);
// subRegs[CV_AMD64_R14B].set(CV_AMD64_R14, 0x00, 0xff);
// subRegs[CV_AMD64_R15B].set(CV_AMD64_R15, 0x00, 0xff);
//
// subRegs[CV_AMD64_R8W].set(CV_AMD64_R8, 0x00, 0xffff);
// subRegs[CV_AMD64_R9W].set(CV_AMD64_R9, 0x00, 0xffff);
// subRegs[CV_AMD64_R10W].set(CV_AMD64_R10, 0x00, 0xffff);
// subRegs[CV_AMD64_R11W].set(CV_AMD64_R11, 0x00, 0xffff);
// subRegs[CV_AMD64_R12W].set(CV_AMD64_R12, 0x00, 0xffff);
// subRegs[CV_AMD64_R13W].set(CV_AMD64_R13, 0x00, 0xffff);
// subRegs[CV_AMD64_R14W].set(CV_AMD64_R14, 0x00, 0xffff);
// subRegs[CV_AMD64_R15W].set(CV_AMD64_R15, 0x00, 0xffff);
//
// subRegs[CV_AMD64_R8D].set(CV_AMD64_R8, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R9D].set(CV_AMD64_R9, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R10D].set(CV_AMD64_R10, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R11D].set(CV_AMD64_R11, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R12D].set(CV_AMD64_R12, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R13D].set(CV_AMD64_R13, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R14D].set(CV_AMD64_R14, 0x00, 0xffffffff);
// subRegs[CV_AMD64_R15D].set(CV_AMD64_R15, 0x00, 0xffffffff);
// }
//};
//
//static const std::map<ULONG, SubRegister> g_SubRegistersAmd64 = SubRegisterMapAmd64().subRegs;
//
///////////////////////////////////////////////////////////////////////////////////
//
//bool ThreadContext::getSubValue(ULONG cvRegId, ULONG64 &val) const
//{
// const std::map<ULONG, SubRegister> *subRegs = NULL;
// if (IMAGE_FILE_MACHINE_I386 == m_processorType)
// subRegs = &g_SubRegistersI386;
// else
// subRegs = &g_SubRegistersAmd64;
//
// std::map<ULONG, SubRegister>::const_iterator itSubReg =
// subRegs->find(cvRegId);
// if (itSubReg == subRegs->end())
// return false;
//
// RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg);
// if (itFullReg == m_regValues.end())
// return false;
//
// val = (itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
//
// return true;
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void ThreadContext::throwUnsupportedProcessor(PCSTR szFunction) const
//{
// std::stringstream sstream;
// sstream << szFunction << ":\n";
// sstream << "Unsupported processor type: 0x" << std::hex << m_processorType;
// throw DbgException( sstream.str() );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//std::string ThreadContext::print() const
//{
// std::stringstream sstr;
//
// RegValues::const_iterator it = m_regValues.begin();
// for (; it != m_regValues.end(); ++it )
// {
// switch (m_processorType)
// {
// case IMAGE_FILE_MACHINE_I386:
//
// for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j )
// if ( pyDia::Symbol::i386RegName[j].first == it->first )
// sstr << pyDia::Symbol::i386RegName[j].second << '=' << std::hex << it->second << std::endl;
//
// break;
//
//
// case IMAGE_FILE_MACHINE_AMD64:
//
// for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j )
// if ( pyDia::Symbol::amd64RegName[j].first == it->first )
// sstr << pyDia::Symbol::amd64RegName[j].second << '=' << std::hex << it->second << std::endl;
//
// break;
// }
//
// }
//
// return sstr.str();
//}
/////////////////////////////////////////////////////////////////////////////////
}