pykd/pykd/win/dbgeng.cpp
SND\kernelnet_cp 98ff37bb29 [0.2.x] added : disasm class
git-svn-id: https://pykd.svn.codeplex.com/svn@78578 9b283d60-5439-405e-af05-b73fd8c4d996
2017-11-08 17:42:50 +04:00

504 lines
14 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 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( &currentStatus );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
}
///////////////////////////////////////////////////////////////////////////////////
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 );
}
///////////////////////////////////////////////////////////////////////////////////
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;
}
///////////////////////////////////////////////////////////////////////////////////
std::string getSymbolByOffset( ULONG64 offset )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
char nameBuf[0x100];
hres =
g_dbgEng->symbols->GetNameByOffset(
offset,
nameBuf,
sizeof(nameBuf),
NULL,
NULL );
std::string fullName( nameBuf );
size_t symPos = fullName.find ( '!' ) + 1;
std::string symbolName;
symbolName.assign( fullName, symPos, fullName.length() - symPos );
return symbolName;
}
///////////////////////////////////////////////////////////////////////////////
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 &regName )
{
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;
}
///////////////////////////////////////////////////////////////////////////////
} // end pykd namespace