mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
858 lines
24 KiB
C++
858 lines
24 KiB
C++
#include "stdafx.h"
|
|
|
|
#include <boost\algorithm\string\case_conv.hpp>
|
|
|
|
#include "win/dbgeng.h"
|
|
#include "dbgexcept.h"
|
|
|
|
namespace pykd {
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DebugEngine g_dbgEng;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG startProcess( const std::wstring &processName )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
ULONG opt;
|
|
hres = g_dbgEng->control->GetEngineOptions( &opt );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetEngineOptions failed" );
|
|
|
|
opt |= DEBUG_ENGOPT_INITIAL_BREAK;
|
|
hres = g_dbgEng->control->SetEngineOptions( opt );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::SetEngineOptions failed" );
|
|
|
|
std::vector< std::wstring::value_type > cmdLine( processName.size() + 1 );
|
|
wcscpy_s( &cmdLine[0], cmdLine.size(), processName.c_str() );
|
|
|
|
hres = g_dbgEng->client->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugClient4::CreateProcessWide failed" );
|
|
|
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
|
|
ULONG processId = -1;
|
|
hres = g_dbgEng->system->GetCurrentProcessId( &processId );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSystemObjects::GetCurrentProcessId failed" );
|
|
|
|
return processId;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void detachProcess( ULONG processId )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
if ( processId != -1 )
|
|
{
|
|
hres = g_dbgEng->system->SetCurrentProcessId(processId);
|
|
if ( FAILED(hres) )
|
|
throw DbgException( "IDebugSystemObjects::SetCurrentProcessId failed" );
|
|
}
|
|
|
|
hres = g_dbgEng->client->DetachCurrentProcess();
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugClient::DetachCurrentProcess failed" );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void terminateProcess( ULONG processId )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
if ( processId != -1 )
|
|
{
|
|
hres = g_dbgEng->system->SetCurrentProcessId(processId);
|
|
if ( FAILED(hres) )
|
|
throw DbgException( "IDebugSystemObjects::SetCurrentProcessId failed" );
|
|
}
|
|
|
|
hres = g_dbgEng->client->TerminateCurrentProcess();
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugClient::TerminateCurrentProcess", hres );
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void loadDump( const std::wstring &fileName )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->client->OpenDumpFileWide( fileName.c_str(), NULL );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugClient4::OpenDumpFileWide failed" );
|
|
|
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool isDumpAnalyzing()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG debugClass, debugQualifier;
|
|
|
|
hres = g_dbgEng->control->GetDebuggeeType( &debugClass, &debugQualifier );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
|
|
|
return debugQualifier >= DEBUG_DUMP_SMALL;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool isKernelDebugging()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG debugClass, debugQualifier;
|
|
|
|
hres = g_dbgEng->control->GetDebuggeeType( &debugClass, &debugQualifier );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
|
|
|
return debugClass == DEBUG_CLASS_KERNEL;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void debugGo()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->SetExecutionStatus( DEBUG_STATUS_GO );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
|
|
|
ULONG currentStatus;
|
|
|
|
do {
|
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
|
|
hres = g_dbgEng->control->GetExecutionStatus( ¤tStatus );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
|
|
|
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void debugStep()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->SetExecutionStatus( DEBUG_STATUS_STEP_OVER );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
|
|
|
ULONG currentStatus;
|
|
|
|
do {
|
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
|
|
hres = g_dbgEng->control->GetExecutionStatus( ¤tStatus );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
|
|
|
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void debugStepIn()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->SetExecutionStatus( DEBUG_STATUS_STEP_INTO );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
|
|
|
ULONG currentStatus;
|
|
|
|
do {
|
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
|
|
hres = g_dbgEng->control->GetExecutionStatus( ¤tStatus );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
|
|
|
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void debugBreak()
|
|
{
|
|
PyThreadState *pystate = PyEval_SaveThread();
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
|
|
|
|
PyEval_RestoreThread( pystate );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::SetInterrupt" );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 evaluate( const std::wstring &expression )
|
|
{
|
|
PyThreadState *pystate = PyEval_SaveThread();
|
|
|
|
HRESULT hres;
|
|
ULONG64 value = 0;
|
|
|
|
DEBUG_VALUE debugValue = {};
|
|
ULONG remainderIndex = 0;
|
|
|
|
hres = g_dbgEng->control->IsPointer64Bit();
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
|
|
|
|
if ( hres == S_OK )
|
|
{
|
|
hres = g_dbgEng->control->EvaluateWide(
|
|
expression.c_str(),
|
|
DEBUG_VALUE_INT64,
|
|
&debugValue,
|
|
&remainderIndex );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::Evaluate failed" );
|
|
|
|
if ( remainderIndex == expression.length() )
|
|
value = debugValue.I64;
|
|
}
|
|
else
|
|
{
|
|
hres = g_dbgEng->control->EvaluateWide(
|
|
expression.c_str(),
|
|
DEBUG_VALUE_INT32,
|
|
&debugValue,
|
|
&remainderIndex );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::Evaluate failed" );
|
|
|
|
if ( remainderIndex == expression.length() )
|
|
value = debugValue.I32;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 findModuleBase( const std::string &moduleName )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG64 base;
|
|
|
|
hres = g_dbgEng->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &base );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
|
|
|
return base;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 findModuleBase( ULONG64 offset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG64 base;
|
|
ULONG moduleIndex;
|
|
|
|
hres = g_dbgEng->symbols->GetModuleByOffset( offset, 0, &moduleIndex, &base );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleByOffset failed" );
|
|
|
|
return base;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 findModuleBySymbol( const std::string &symbolName )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG64 base;
|
|
|
|
hres = g_dbgEng->symbols->GetSymbolModule( ( std::string("!") + symbolName ).c_str(), &base );
|
|
if ( FAILED( hres ) )
|
|
{
|
|
std::stringstream sstr;
|
|
sstr << "failed to find module for symbol: " << symbolName;
|
|
throw SymbolException( sstr.str() );
|
|
}
|
|
|
|
return base;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getModuleName( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
char moduleName[0x100];
|
|
|
|
hres = g_dbgEng->symbols->GetModuleNameString(
|
|
DEBUG_MODNAME_MODULE,
|
|
DEBUG_ANY_ID,
|
|
baseOffset,
|
|
moduleName,
|
|
sizeof( moduleName ),
|
|
NULL );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
|
|
|
|
return std::string( moduleName );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getModuleImageName( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
char imageName[0x100];
|
|
|
|
hres = g_dbgEng->symbols->GetModuleNameString(
|
|
DEBUG_MODNAME_IMAGE,
|
|
DEBUG_ANY_ID,
|
|
baseOffset,
|
|
imageName,
|
|
sizeof( imageName ),
|
|
NULL );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
|
|
|
|
return std::string( imageName );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG getModuleSize( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
|
|
|
|
hres = g_dbgEng->symbols->GetModuleParameters( 1, &baseOffset, 0, &moduleParam );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
|
|
|
return moduleParam.Size;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getModuleSymbolFileName( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
IMAGEHLP_MODULEW64 moduleInfo = {};
|
|
|
|
hres = g_dbgEng->advanced->GetSymbolInformation(
|
|
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
|
baseOffset,
|
|
0,
|
|
&moduleInfo,
|
|
sizeof(moduleInfo),
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
|
|
|
if (!*moduleInfo.LoadedPdbName)
|
|
{
|
|
std::wstring param = L"/f ";
|
|
param += moduleInfo.ImageName;
|
|
|
|
hres = g_dbgEng->symbols->ReloadWide( param.c_str() );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException("IDebugSymbols::Reload failed" );
|
|
|
|
hres = g_dbgEng->advanced->GetSymbolInformation(
|
|
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
|
baseOffset,
|
|
0,
|
|
&moduleInfo,
|
|
sizeof(moduleInfo),
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
|
}
|
|
|
|
char pdbName[ 256 ];
|
|
WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
|
|
|
|
return std::string( pdbName );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG getModuleTimeStamp( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
|
|
|
|
hres = g_dbgEng->symbols->GetModuleParameters( 1, &baseOffset, 0, &moduleParam );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
|
|
|
return moduleParam.TimeDateStamp;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG getModuleCheckSum( ULONG64 baseOffset )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
|
|
|
|
hres = g_dbgEng->symbols->GetModuleParameters( 1, &baseOffset, 0, &moduleParam );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
|
|
|
return moduleParam.Checksum;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG ptrSize()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->IsPointer64Bit();
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
|
|
|
|
return S_OK == hres ? 8 : 4;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool is64bitSystem()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->control->IsPointer64Bit();
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
|
|
|
|
return hres == S_OK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG getPageSize()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG pageSize;
|
|
|
|
hres = g_dbgEng->control->GetPageSize( &pageSize );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetPageSize failed" );
|
|
|
|
return pageSize;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 loadMSR( ULONG msr )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG64 value;
|
|
|
|
hres = g_dbgEng->dataspace->ReadMsr( msr, &value );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugDataSpaces::ReadMsr", hres );
|
|
|
|
return value;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void setMSR( ULONG msr, ULONG64 value)
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
hres = g_dbgEng->dataspace->WriteMsr(msr, value);
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugDataSpaces::WriteMsr", hres );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG getRegIndexByName( const std::string ®Name )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG index;
|
|
|
|
hres = g_dbgEng->registers->GetIndexByName( boost::to_lower_copy(regName).c_str(), &index );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugRegister::GetIndexByName", hres );
|
|
|
|
return index;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getRegNameByIndex( ULONG index )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
ULONG nameSize = 0;
|
|
|
|
hres =
|
|
g_dbgEng->registers->GetDescription(
|
|
index,
|
|
NULL,
|
|
0,
|
|
&nameSize,
|
|
NULL );
|
|
|
|
if ( nameSize == 0 )
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugRegister::GetDescription", hres );
|
|
|
|
std::vector<char> nameBuffer(nameSize);
|
|
DEBUG_REGISTER_DESCRIPTION desc = {};
|
|
|
|
hres =
|
|
g_dbgEng->registers->GetDescription(
|
|
index,
|
|
&nameBuffer[0],
|
|
nameSize,
|
|
NULL,
|
|
&desc );
|
|
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugRegister::GetDescription", hres );
|
|
|
|
return std::string( &nameBuffer[0] );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BaseTypeVariant getRegVariantValue( ULONG index )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
DEBUG_VALUE debugValue;
|
|
hres = g_dbgEng->registers->GetValue( index, &debugValue );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugRegister::GetValue", hres );
|
|
|
|
switch( debugValue.Type )
|
|
{
|
|
case DEBUG_VALUE_INT8:
|
|
return BaseTypeVariant( (LONG)debugValue.I8 );
|
|
break;
|
|
|
|
case DEBUG_VALUE_INT16:
|
|
return BaseTypeVariant( (LONG)debugValue.I16 );
|
|
break;
|
|
|
|
case DEBUG_VALUE_INT32:
|
|
return BaseTypeVariant( debugValue.I32 );
|
|
break;
|
|
|
|
case DEBUG_VALUE_INT64:
|
|
return BaseTypeVariant( debugValue.I64 );
|
|
break;
|
|
}
|
|
|
|
throw DbgException( "Failed to convert register value" );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG64 getRegInstructionPointer()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG64 ip = 0;
|
|
|
|
hres = g_dbgEng->registers->GetInstructionOffset( &ip );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugRegisters::GetInstructionOffset failed" );
|
|
|
|
return ip;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
|
|
{
|
|
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" );
|
|
|
|
frames.resize(filledFrames);
|
|
for ( ULONG i = 0; i < filledFrames; ++i )
|
|
{
|
|
frames[i].number = dbgFrames[i].FrameNumber;
|
|
frames[i].instructionOffset = dbgFrames[i].InstructionOffset;
|
|
frames[i].returnOffset = dbgFrames[i].ReturnOffset;
|
|
frames[i].frameOffset = dbgFrames[i].FrameOffset;
|
|
frames[i].stackOffset = dbgFrames[i].StackOffset;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string processorToStr(ULONG processorMode)
|
|
{
|
|
switch( processorMode )
|
|
{
|
|
case IMAGE_FILE_MACHINE_I386:
|
|
return "X86";
|
|
|
|
case IMAGE_FILE_MACHINE_ARM:
|
|
return "ARM";
|
|
|
|
case IMAGE_FILE_MACHINE_IA64:
|
|
return "IA64";
|
|
|
|
case IMAGE_FILE_MACHINE_AMD64:
|
|
return "X64";
|
|
}
|
|
|
|
throw DbgException( "Unknown CPU type" );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getProcessorMode()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG processorMode;
|
|
|
|
hres = g_dbgEng->control->GetEffectiveProcessorType( &processorMode );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
|
|
|
|
return processorToStr(processorMode);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string getProcessorType()
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
ULONG processorMode;
|
|
|
|
hres = g_dbgEng->control->GetActualProcessorType( &processorMode );
|
|
if ( FAILED( hres ) )
|
|
throw DbgException( "IDebugControl::GetActualProcessorType failed" );
|
|
|
|
return processorToStr(processorMode);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG breakPointSet( ULONG64 offset, bool hardware, ULONG size, ULONG accessType )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
HRESULT hres;
|
|
|
|
IDebugBreakpoint *bp;
|
|
hres = g_dbgEng->control->AddBreakpoint(
|
|
hardware ? DEBUG_BREAKPOINT_DATA : DEBUG_BREAKPOINT_CODE,
|
|
DEBUG_ANY_ID,
|
|
&bp);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::AddBreakpoint", hres);
|
|
|
|
hres = bp->SetOffset(offset);
|
|
if (S_OK != hres)
|
|
{
|
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
throw DbgException("IDebugBreakpoint::SetOffset", hres);
|
|
}
|
|
|
|
ULONG bpFlags;
|
|
hres = bp->GetFlags(&bpFlags);
|
|
if (S_OK != hres)
|
|
{
|
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
throw DbgException("IDebugBreakpoint::GetFlags", hres);
|
|
}
|
|
|
|
bpFlags |= DEBUG_BREAKPOINT_ENABLED;
|
|
hres = bp->SetFlags(bpFlags);
|
|
if (S_OK != hres)
|
|
{
|
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
throw DbgException("IDebugBreakpoint::SetFlags", hres);
|
|
}
|
|
|
|
if ( hardware )
|
|
{
|
|
HRESULT hres = bp->SetDataParameters(size, accessType);
|
|
if (S_OK != hres)
|
|
{
|
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
|
|
}
|
|
}
|
|
|
|
ULONG breakId;
|
|
hres = bp->GetId(&breakId);
|
|
if (S_OK != hres)
|
|
{
|
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
throw DbgException("IDebugBreakpoint::GetId", hres);
|
|
}
|
|
|
|
return breakId;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void breakPointRemove( ULONG id )
|
|
{
|
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
|
|
|
IDebugBreakpoint *bp;
|
|
HRESULT hres = g_dbgEng->control->GetBreakpointById(id, &bp);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::GetBreakpointById", hres);
|
|
|
|
hres = g_dbgEng->control->RemoveBreakpoint(bp);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::RemoveBreakpoint", hres);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void breakPointRemoveAll()
|
|
{
|
|
ULONG numberOfBps;
|
|
do {
|
|
HRESULT hres = g_dbgEng->control->GetNumberBreakpoints(&numberOfBps);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
|
|
|
|
if (!numberOfBps)
|
|
break;
|
|
|
|
IDebugBreakpoint *bp;
|
|
hres = g_dbgEng->control->GetBreakpointByIndex(0, &bp);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
|
|
|
|
hres = g_dbgEng->control->RemoveBreakpoint(bp);
|
|
if (S_OK != hres)
|
|
throw DbgException("IDebugControl::RemoveBreakpoint", hres);
|
|
|
|
} while (numberOfBps);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
} // end pykd namespace
|
|
|
|
|