mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
[0.2.x] added : disasm class
git-svn-id: https://pykd.svn.codeplex.com/svn@78578 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
3a47a6574d
commit
98ff37bb29
@ -1,740 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "dbgclient.h"
|
|
||||||
#include "stkframe.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DebugClient::DebugClient( IDebugClient4 *client )
|
|
||||||
: DbgObject( client )
|
|
||||||
, m_symSymbols( new SyntheticSymbols(*m_symbols, *this) )
|
|
||||||
, m_internalDbgEventHandler(client, this, m_symSymbols, m_bpCallbacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DebugClientPtr DebugClient::createDbgClient() {
|
|
||||||
|
|
||||||
HRESULT hres;
|
|
||||||
CComPtr<IDebugClient4> client = NULL;
|
|
||||||
|
|
||||||
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("DebugCreate failed");
|
|
||||||
|
|
||||||
return createDbgClient( client );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DebugClientPtr DebugClient::createDbgClient( IDebugClient4 *client ) {
|
|
||||||
|
|
||||||
//HRESULT hres;
|
|
||||||
//CComPtr<IDebugClient> newClient = NULL;
|
|
||||||
|
|
||||||
//hres = client->CreateClient( &newClient );
|
|
||||||
//if ( FAILED( hres ) )
|
|
||||||
// throw DbgException("DebugCreate failed");
|
|
||||||
|
|
||||||
//CComQIPtr<IDebugClient4> client4= newClient;
|
|
||||||
|
|
||||||
//return DebugClientPtr( new DebugClient(client4) );
|
|
||||||
|
|
||||||
return DebugClientPtr( new DebugClient(client) );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) {
|
|
||||||
DebugClientPtr oldClient = g_dbgClient;
|
|
||||||
g_dbgClient = newDbgClient;
|
|
||||||
return oldClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::tuple DebugClient::getDebuggeeType()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG debugClass, debugQualifier;
|
|
||||||
|
|
||||||
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
|
||||||
|
|
||||||
return python::make_tuple( debugClass, debugQualifier );
|
|
||||||
}
|
|
||||||
|
|
||||||
python::tuple getDebuggeeType()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getDebuggeeType();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG DebugClient::getExecutionStatus()
|
|
||||||
{
|
|
||||||
ULONG currentStatus;
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_control->GetExecutionStatus( ¤tStatus );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
|
||||||
|
|
||||||
return currentStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG getExecutionStatus()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getExecutionStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool DebugClient::is64bitSystem()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_control->IsPointer64Bit();
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
|
|
||||||
|
|
||||||
return hres == S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
is64bitSystem()
|
|
||||||
{
|
|
||||||
return g_dbgClient->is64bitSystem();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool DebugClient::isDumpAnalyzing()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG debugClass, debugQualifier;
|
|
||||||
|
|
||||||
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
|
||||||
|
|
||||||
return debugQualifier >= DEBUG_DUMP_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDumpAnalyzing()
|
|
||||||
{
|
|
||||||
return g_dbgClient->isDumpAnalyzing();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool DebugClient::isKernelDebugging()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG debugClass, debugQualifier;
|
|
||||||
|
|
||||||
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
|
||||||
|
|
||||||
return debugClass == DEBUG_CLASS_KERNEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isKernelDebugging()
|
|
||||||
{
|
|
||||||
return g_dbgClient->isKernelDebugging();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::loadDump( const std::wstring &fileName )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_client->OpenDumpFileWide( fileName.c_str(), NULL );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient4::OpenDumpFileWide failed" );
|
|
||||||
|
|
||||||
hres = safeWaitForEvent();
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadDump( const std::wstring &fileName ) {
|
|
||||||
g_dbgClient->loadDump( fileName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::startProcess( const std::wstring &processName )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
ULONG opt;
|
|
||||||
hres = m_control->GetEngineOptions( &opt );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetEngineOptions failed" );
|
|
||||||
|
|
||||||
opt |= DEBUG_ENGOPT_INITIAL_BREAK;
|
|
||||||
hres = m_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 = m_client->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient4::CreateProcessWide failed" );
|
|
||||||
|
|
||||||
hres = safeWaitForEvent();
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void startProcess( const std::wstring &processName ) {
|
|
||||||
g_dbgClient->startProcess( processName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::attachProcess( ULONG processId )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_client->AttachProcess( 0, processId, 0 );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient::AttachProcess failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachProcess( ULONG processId ) {
|
|
||||||
g_dbgClient->attachProcess( processId );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::detachProcess()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_client->DetachCurrentProcess();
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient::DetachCurrentProcess failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void detachProcess() {
|
|
||||||
g_dbgClient->detachProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::attachKernel( const std::wstring ¶m )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_client5->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient5::AttachKernelWide failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachKernel( const std::wstring ¶m ) {
|
|
||||||
g_dbgClient->attachKernel( param );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string DebugClient::findSymbol( ULONG64 offset )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
offset = addr64( offset );
|
|
||||||
|
|
||||||
char symbolName[0x100];
|
|
||||||
ULONG64 displace = 0;
|
|
||||||
hres = m_symbols->GetNameByOffset( offset, symbolName, sizeof(symbolName), NULL, &displace );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetNameByOffset failed" );
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
displace == 0 ? ss << symbolName : ss << symbolName << '+' << std::hex << displace;
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string findSymbol( ULONG64 offset )
|
|
||||||
{
|
|
||||||
return g_dbgClient->findSymbol( offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64 DebugClient::getOffset( const std::wstring symbolname )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG64 offset;
|
|
||||||
|
|
||||||
hres = m_symbols->GetOffsetByNameWide( symbolname.c_str(), &offset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "failed to find offset for symbol" );
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG64 getOffset( const std::wstring symbolname )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getOffset( symbolname );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string DebugClient::getPdbFile( ULONG64 moduleBase )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
IMAGEHLP_MODULEW64 imageHelpInfo = { 0 };
|
|
||||||
|
|
||||||
hres =
|
|
||||||
m_advanced->GetSymbolInformation(
|
|
||||||
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
|
||||||
moduleBase,
|
|
||||||
0,
|
|
||||||
&imageHelpInfo,
|
|
||||||
sizeof( imageHelpInfo ),
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
|
||||||
|
|
||||||
char fileName[ 256 ];
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, imageHelpInfo.LoadedPdbName, 256, fileName, 256, NULL, NULL );
|
|
||||||
|
|
||||||
return std::string( fileName );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getPdbFile( ULONG64 moduleBase )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getPdbFile( moduleBase );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string DebugClient::dbgSymPath()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
std::string pathStr;
|
|
||||||
|
|
||||||
ULONG size;
|
|
||||||
m_symbols->GetSymbolPath( NULL, 0, &size );
|
|
||||||
|
|
||||||
std::vector<char> path(size);
|
|
||||||
hres = m_symbols->GetSymbolPath( &path[0], size, NULL );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbols::GetSymbolPath failed" );
|
|
||||||
|
|
||||||
return std::string(&path[0],size);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dbgSymPath()
|
|
||||||
{
|
|
||||||
return g_dbgClient->dbgSymPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::setExecutionStatus( ULONG status )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_control->SetExecutionStatus( status );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setExecutionStatus( ULONG status )
|
|
||||||
{
|
|
||||||
g_dbgClient->setExecutionStatus( status );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT DebugClient::safeWaitForEvent(ULONG timeout /*= INFINITE*/, ULONG flags /*= DEBUG_WAIT_DEFAULT*/)
|
|
||||||
{
|
|
||||||
PyThread_StateRestore pyThreadRestore( m_pyThreadState );
|
|
||||||
return m_control->WaitForEvent( flags, timeout );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::waitForEvent()
|
|
||||||
{
|
|
||||||
HRESULT hres = safeWaitForEvent();
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
{
|
|
||||||
if (E_UNEXPECTED == hres)
|
|
||||||
throw WaitEventException();
|
|
||||||
|
|
||||||
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void waitForEvent()
|
|
||||||
{
|
|
||||||
g_dbgClient->waitForEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG DebugClient::ptrSize()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_control->IsPointer64Bit();
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
|
|
||||||
|
|
||||||
return S_OK == hres ? 8 : 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG ptrSize()
|
|
||||||
{
|
|
||||||
return g_dbgClient->ptrSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::terminateProcess()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_client->TerminateCurrentProcess();
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugClient::TerminateCurrentProcess", hres );
|
|
||||||
}
|
|
||||||
|
|
||||||
void terminateProcess()
|
|
||||||
{
|
|
||||||
g_dbgClient->terminateProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static const boost::regex moduleSymMatch("^(?:([^!]*)!)?([^!]+)$");
|
|
||||||
|
|
||||||
void DebugClient::splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName )
|
|
||||||
{
|
|
||||||
boost::cmatch matchResult;
|
|
||||||
|
|
||||||
OutputReader outputDiscard( m_client );
|
|
||||||
|
|
||||||
if ( !boost::regex_match( fullName.c_str(), matchResult, moduleSymMatch ) )
|
|
||||||
{
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "invalid symbol name: " << fullName;
|
|
||||||
throw SymbolException( sstr.str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
symbolName = std::string( matchResult[2].first, matchResult[2].second );
|
|
||||||
|
|
||||||
if ( matchResult[1].matched )
|
|
||||||
{
|
|
||||||
moduleName = std::string( matchResult[1].first, matchResult[1].second );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG64 base;
|
|
||||||
|
|
||||||
hres = m_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() );
|
|
||||||
}
|
|
||||||
|
|
||||||
char nameBuffer[0x100];
|
|
||||||
|
|
||||||
hres =
|
|
||||||
m_symbols->GetModuleNameString(
|
|
||||||
DEBUG_MODNAME_MODULE,
|
|
||||||
DEBUG_ANY_ID,
|
|
||||||
base,
|
|
||||||
nameBuffer,
|
|
||||||
sizeof(nameBuffer),
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
{
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "failed to find module for symbol: " << symbolName;
|
|
||||||
throw SymbolException( sstr.str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleName = std::string( nameBuffer );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64 DebugClient::getSymbolSize( const std::string &fullName )
|
|
||||||
{
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
if ( TypeInfo::isBaseType( fullName ) )
|
|
||||||
return TypeInfo::getBaseTypeInfo( fullName )->getSize();
|
|
||||||
|
|
||||||
splitSymName( fullName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getSymbolSize(symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG64 getSymbolSize( const std::string &symName )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getSymbolSize(symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypeInfoPtr DebugClient::getTypeInfoByName( const std::string &typeName )
|
|
||||||
{
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
if ( TypeInfo::isBaseType( typeName ) )
|
|
||||||
return TypeInfo::getBaseTypeInfo( typeName );
|
|
||||||
|
|
||||||
splitSymName( typeName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getTypeByName( symName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypedVarPtr DebugClient::getTypedVarByName( const std::string &varName )
|
|
||||||
{
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
splitSymName( varName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getTypedVarByName( symName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypedVarPtr DebugClient::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
|
|
||||||
{
|
|
||||||
addr = addr64( addr );
|
|
||||||
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
splitSymName( typeName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getTypedVarByTypeName( symName, addr );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypedVarPtr DebugClient::containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName )
|
|
||||||
{
|
|
||||||
addr = addr64( addr );
|
|
||||||
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
splitSymName( typeName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->containingRecordByName( addr, symName, fieldName );
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName )
|
|
||||||
{
|
|
||||||
return g_dbgClient->containingRecordByName( addr, typeName, fieldName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypedVarPtr DebugClient::containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
|
||||||
{
|
|
||||||
addr = addr64(addr);
|
|
||||||
|
|
||||||
VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, addr - typeInfo->getFieldOffsetByNameRecirsive(fieldName) );
|
|
||||||
|
|
||||||
return TypedVar::getTypedVar( m_client, typeInfo, varData );
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
|
||||||
{
|
|
||||||
return g_dbgClient->containingRecordByType( addr, typeInfo, fieldName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list DebugClient::getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )\
|
|
||||||
{
|
|
||||||
python::list lst;
|
|
||||||
|
|
||||||
listHeadAddress = addr64( listHeadAddress );
|
|
||||||
|
|
||||||
ULONG64 entryAddress = 0;
|
|
||||||
|
|
||||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
|
||||||
|
|
||||||
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
|
||||||
{
|
|
||||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
|
|
||||||
lst.append( getTypedVarByTypeInfo( typeInfo, entryAddress ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
|
||||||
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return lst;
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarListByType( listHeadAddress, typeInfo, listEntryName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list DebugClient::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
|
||||||
{
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
splitSymName( typeName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getTypedVarListByTypeName( listHeadAddress, symName, listEntryName );
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarListByTypeName( listHeadAddress, typeName, listEntryName );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list DebugClient::getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
|
|
||||||
{
|
|
||||||
address = addr64(address);
|
|
||||||
|
|
||||||
python::list lst;
|
|
||||||
|
|
||||||
for( ULONG i = 0; i < number; ++i )
|
|
||||||
lst.append( getTypedVarByTypeInfo( typeInfo, address + i * typeInfo->getSize() ) );
|
|
||||||
|
|
||||||
return lst;
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarArrayByType( address, typeInfo, number );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list DebugClient::getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
|
||||||
{
|
|
||||||
std::string moduleName;
|
|
||||||
std::string symName;
|
|
||||||
|
|
||||||
splitSymName( typeName, moduleName, symName );
|
|
||||||
|
|
||||||
ModulePtr module = loadModuleByName( moduleName );
|
|
||||||
|
|
||||||
return module->getTypedVarArrayByTypeName( addr, symName, number );
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarArrayByTypeName( addr, typeName, number );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::tuple DebugClient::getSourceLine( ULONG64 offset )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
if ( offset == 0 )
|
|
||||||
{
|
|
||||||
hres = m_registers->GetInstructionOffset( &offset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugRegisters::GetInstructionOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG fileNameLength = 0;
|
|
||||||
|
|
||||||
m_symbols->GetLineByOffset(
|
|
||||||
offset,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&fileNameLength,
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if ( fileNameLength == 0 )
|
|
||||||
throw DbgException( "Failed to find source file" );
|
|
||||||
|
|
||||||
std::vector<CHAR> fileNameBuf( fileNameLength );
|
|
||||||
|
|
||||||
ULONG lineNo;
|
|
||||||
ULONG64 displacement;
|
|
||||||
|
|
||||||
hres =
|
|
||||||
m_symbols->GetLineByOffset(
|
|
||||||
offset,
|
|
||||||
&lineNo,
|
|
||||||
&fileNameBuf[0],
|
|
||||||
fileNameLength,
|
|
||||||
NULL,
|
|
||||||
&displacement );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetLineByOffset method failed" );
|
|
||||||
|
|
||||||
return python::make_tuple( std::string( &fileNameBuf[0] ), lineNo, displacement );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}; // end of namespace pykd
|
|
530
pykd/dbgclient.h
530
pykd/dbgclient.h
@ -1,530 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <dbghelp.h>
|
|
||||||
|
|
||||||
#include <boost\smart_ptr\scoped_ptr.hpp>
|
|
||||||
#include <boost\enable_shared_from_this.hpp>
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "dbgobj.h"
|
|
||||||
#include "dbgexcept.h"
|
|
||||||
#include "module.h"
|
|
||||||
#include "dbgio.h"
|
|
||||||
#include "dbgcmd.h"
|
|
||||||
#include "pyaux.h"
|
|
||||||
#include "disasm.h"
|
|
||||||
#include "cpureg.h"
|
|
||||||
#include "inteventhandler.h"
|
|
||||||
#include "synsymbol.h"
|
|
||||||
#include "context.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class DebugClient;
|
|
||||||
typedef boost::shared_ptr<DebugClient> DebugClientPtr;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef ULONG BPOINT_ID;
|
|
||||||
typedef python::object BpCallback;
|
|
||||||
typedef std::map<BPOINT_ID, BpCallback> BpCallbackMapIml;
|
|
||||||
struct BpCallbackMap {
|
|
||||||
boost::shared_ptr<boost::recursive_mutex> m_lock;
|
|
||||||
BpCallbackMapIml m_map;
|
|
||||||
|
|
||||||
BpCallbackMap() : m_lock(new boost::recursive_mutex) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class DebugClient : private DbgObject
|
|
||||||
, public boost::enable_shared_from_this<DebugClient> {
|
|
||||||
|
|
||||||
private:
|
|
||||||
// simple IDebugControl4 call wrapper
|
|
||||||
template <typename T>
|
|
||||||
T getDbgControlT(
|
|
||||||
HRESULT (STDMETHODCALLTYPE IDebugControl4::*method)(T *),
|
|
||||||
const char *methodName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
T retValue;
|
|
||||||
HRESULT hres = (m_control->*method)(&retValue);
|
|
||||||
if (S_OK != hres)
|
|
||||||
throw DbgException( methodName, hres);
|
|
||||||
return retValue;
|
|
||||||
}
|
|
||||||
#define getDbgControl(method) \
|
|
||||||
getDbgControlT( &IDebugControl4::##method, "IDebugControl4::" #method )
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual ~DebugClient() {}
|
|
||||||
|
|
||||||
static
|
|
||||||
DebugClientPtr createDbgClient() ;
|
|
||||||
|
|
||||||
static
|
|
||||||
DebugClientPtr createDbgClient( IDebugClient4 *client );
|
|
||||||
|
|
||||||
static
|
|
||||||
DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient );
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ULONG64 addr64( ULONG64 addr );
|
|
||||||
|
|
||||||
void breakin();
|
|
||||||
|
|
||||||
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
void detachProcess();
|
|
||||||
|
|
||||||
DbgOut dout() {
|
|
||||||
return DbgOut( m_client );
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgIn din() {
|
|
||||||
return DbgIn( m_client );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dbgCommand( const std::wstring &command );
|
|
||||||
|
|
||||||
void startProcess( const std::wstring &processName );
|
|
||||||
|
|
||||||
void attachProcess( ULONG processId );
|
|
||||||
|
|
||||||
void attachKernel( const std::wstring ¶m );
|
|
||||||
|
|
||||||
Disasm disasm( ULONG offset = 0 ) {
|
|
||||||
return Disasm( m_client, offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
void dprint( const std::wstring &str, bool dml = false );
|
|
||||||
|
|
||||||
void dprintln( const std::wstring &str, bool dml = false );
|
|
||||||
|
|
||||||
void eprint( const std::wstring &str );
|
|
||||||
|
|
||||||
void eprintln( const std::wstring &str );
|
|
||||||
|
|
||||||
ULONG64 evaluate( const std::wstring &expression );
|
|
||||||
|
|
||||||
std::string findSymbol( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 getCurrentProcess();
|
|
||||||
|
|
||||||
python::list getCurrentStack();
|
|
||||||
|
|
||||||
python::tuple getDebuggeeType();
|
|
||||||
|
|
||||||
ULONG64 getImplicitThread();
|
|
||||||
|
|
||||||
ULONG getExecutionStatus();
|
|
||||||
|
|
||||||
ULONG64 getOffset( const std::wstring symbolname );
|
|
||||||
|
|
||||||
std::string getPdbFile( ULONG64 moduleBase );
|
|
||||||
|
|
||||||
std::string getProcessorMode();
|
|
||||||
|
|
||||||
std::string getProcessorType();
|
|
||||||
|
|
||||||
std::string dbgSymPath();
|
|
||||||
|
|
||||||
python::tuple getSourceLine( ULONG64 offset = 0);
|
|
||||||
|
|
||||||
python::list getThreadList();
|
|
||||||
|
|
||||||
template<ULONG status>
|
|
||||||
void changeDebuggerStatus();
|
|
||||||
|
|
||||||
bool is64bitSystem();
|
|
||||||
|
|
||||||
bool isKernelDebugging();
|
|
||||||
|
|
||||||
bool isDumpAnalyzing();
|
|
||||||
|
|
||||||
bool isVaValid( ULONG64 addr );
|
|
||||||
|
|
||||||
void loadDump( const std::wstring &fileName );
|
|
||||||
|
|
||||||
ModulePtr loadModuleByName( const std::string &moduleName ) {
|
|
||||||
return ModulePtr( new Module( m_client, m_symSymbols, moduleName ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ModulePtr loadModuleByOffset( ULONG64 offset ) {
|
|
||||||
return ModulePtr( new Module( m_client, m_symSymbols, offset ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgExtensionPtr loadExtension( const std::wstring &extPath ) {
|
|
||||||
return DbgExtensionPtr( new DbgExtension( m_client, extPath ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
std::string loadChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
std::string loadCStr( ULONG64 offset );
|
|
||||||
|
|
||||||
std::wstring loadWStr( ULONG64 offset );
|
|
||||||
|
|
||||||
std::string loadAnsiStr( ULONG64 address );
|
|
||||||
|
|
||||||
std::wstring loadUnicodeStr( ULONG64 address );
|
|
||||||
|
|
||||||
python::list loadPtrList( ULONG64 address );
|
|
||||||
|
|
||||||
python::list loadPtrArray( ULONG64 address, ULONG number );
|
|
||||||
|
|
||||||
ULONG64 loadMSR( ULONG msr );
|
|
||||||
|
|
||||||
ULONG ptrSize();
|
|
||||||
|
|
||||||
ULONG64 ptrByte( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 ptrWord( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 ptrDWord( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 ptrQWord( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 ptrMWord( ULONG64 offset );
|
|
||||||
|
|
||||||
LONG64 ptrSignByte( ULONG64 offset );
|
|
||||||
|
|
||||||
LONG64 ptrSignWord( ULONG64 offset );
|
|
||||||
|
|
||||||
LONG64 ptrSignDWord( ULONG64 offset );
|
|
||||||
|
|
||||||
LONG64 ptrSignQWord( ULONG64 offset );
|
|
||||||
|
|
||||||
LONG64 ptrSignMWord( ULONG64 offset );
|
|
||||||
|
|
||||||
ULONG64 ptrPtr( ULONG64 offset );
|
|
||||||
|
|
||||||
void setMSR( ULONG msr, ULONG64 value);
|
|
||||||
|
|
||||||
CpuReg getRegByName( const std::string ®Name );
|
|
||||||
|
|
||||||
CpuReg getRegByIndex( ULONG index );
|
|
||||||
|
|
||||||
void setCurrentProcess( ULONG64 addr );
|
|
||||||
|
|
||||||
void setExecutionStatus( ULONG status );
|
|
||||||
|
|
||||||
void setImplicitThread( ULONG64 threadAddr );
|
|
||||||
|
|
||||||
void setProcessorMode( const std::wstring &mode );
|
|
||||||
|
|
||||||
void terminateProcess();
|
|
||||||
|
|
||||||
void waitForEvent();
|
|
||||||
|
|
||||||
ULONG getNumberProcessors() {
|
|
||||||
return getDbgControl(GetNumberProcessors);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG getPageSize() {
|
|
||||||
return getDbgControl(GetPageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextPtr getThreadContext() {
|
|
||||||
return ContextPtr( new ThreadContext(m_client) );
|
|
||||||
}
|
|
||||||
ContextPtr getThreadWow64Context() {
|
|
||||||
return ThreadContext::getWow64Context(m_client);
|
|
||||||
}
|
|
||||||
|
|
||||||
python::dict getLocals(
|
|
||||||
ContextPtr ctx = ContextPtr( reinterpret_cast<ThreadContext*>(0) )
|
|
||||||
);
|
|
||||||
public:
|
|
||||||
|
|
||||||
CComPtr<IDebugClient4>&
|
|
||||||
client() {
|
|
||||||
return m_client;
|
|
||||||
}
|
|
||||||
|
|
||||||
CComPtr<IDebugClient5>&
|
|
||||||
client5() {
|
|
||||||
return m_client5;
|
|
||||||
}
|
|
||||||
|
|
||||||
CComPtr<IDebugControl4>&
|
|
||||||
control() {
|
|
||||||
return m_control;
|
|
||||||
}
|
|
||||||
|
|
||||||
CComPtr< IDebugDataSpaces4>&
|
|
||||||
dataSpace() {
|
|
||||||
return m_dataSpaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyThreadStateSaver&
|
|
||||||
getThreadState() {
|
|
||||||
return m_pyThreadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addSyntheticSymbol(
|
|
||||||
ULONG64 addr,
|
|
||||||
ULONG size,
|
|
||||||
const std::string &symName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_symSymbols->add(addr, size, symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void delAllSyntheticSymbols()
|
|
||||||
{
|
|
||||||
return m_symSymbols->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG delSyntheticSymbol(
|
|
||||||
ULONG64 addr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_symSymbols->remove(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG delSyntheticSymbolsMask(
|
|
||||||
const std::string &moduleName,
|
|
||||||
const std::string &symName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_symSymbols->removeByMask(moduleName, symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
SynSymbolsPtr getSynSymbols() {
|
|
||||||
return m_symSymbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
// breakpoints management
|
|
||||||
BPOINT_ID setSoftwareBp(ULONG64 addr, BpCallback &callback = BpCallback());
|
|
||||||
BPOINT_ID setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback = BpCallback());
|
|
||||||
|
|
||||||
python::list getAllBp();
|
|
||||||
|
|
||||||
void removeBp(BPOINT_ID Id);
|
|
||||||
void removeAllBp();
|
|
||||||
|
|
||||||
void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName );
|
|
||||||
|
|
||||||
TypeInfoPtr getTypeInfoByName( const std::string &typeName );
|
|
||||||
|
|
||||||
TypedVarPtr getTypedVarByName( const std::string &varName );
|
|
||||||
|
|
||||||
TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
|
|
||||||
|
|
||||||
TypedVarPtr getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr ) {
|
|
||||||
return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, addr) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
|
||||||
|
|
||||||
|
|
||||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
|
||||||
|
|
||||||
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
|
||||||
|
|
||||||
ULONG64 getSymbolSize( const std::string &symName );
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
HRESULT safeWaitForEvent(ULONG timeout = INFINITE, ULONG flags = DEBUG_WAIT_DEFAULT);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
python::list
|
|
||||||
loadArray( ULONG64 offset, ULONG count, bool phyAddr );
|
|
||||||
|
|
||||||
BpCallbackMap m_bpCallbacks;
|
|
||||||
|
|
||||||
SynSymbolsPtr m_symSymbols; // DebugClient is creator
|
|
||||||
InternalDbgEventHandler m_internalDbgEventHandler;
|
|
||||||
|
|
||||||
DebugClient( IDebugClient4 *client );
|
|
||||||
|
|
||||||
PyThreadStateSaver m_pyThreadState;
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
extern DebugClientPtr g_dbgClient;
|
|
||||||
|
|
||||||
void loadDump( const std::wstring &fileName );
|
|
||||||
|
|
||||||
void startProcess( const std::wstring &processName );
|
|
||||||
|
|
||||||
void attachProcess( ULONG processId );
|
|
||||||
|
|
||||||
void attachKernel( const std::wstring ¶m );
|
|
||||||
|
|
||||||
void detachProcess();
|
|
||||||
|
|
||||||
std::string findSymbol( ULONG64 offset );
|
|
||||||
|
|
||||||
python::tuple getDebuggeeType();
|
|
||||||
|
|
||||||
ULONG getExecutionStatus();
|
|
||||||
|
|
||||||
ULONG64 getOffset( const std::wstring symbolname );
|
|
||||||
|
|
||||||
std::string getPdbFile( ULONG64 moduleBase );
|
|
||||||
|
|
||||||
std::string dbgSymPath();
|
|
||||||
|
|
||||||
bool is64bitSystem();
|
|
||||||
|
|
||||||
bool isKernelDebugging();
|
|
||||||
|
|
||||||
bool isDumpAnalyzing();
|
|
||||||
|
|
||||||
ULONG ptrSize();
|
|
||||||
|
|
||||||
void setExecutionStatus( ULONG status );
|
|
||||||
|
|
||||||
void terminateProcess();
|
|
||||||
|
|
||||||
void waitForEvent();
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
|
||||||
|
|
||||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
|
||||||
|
|
||||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
|
||||||
|
|
||||||
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
|
||||||
|
|
||||||
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
|
||||||
|
|
||||||
ULONG64 getSymbolSize( const std::string &symName );
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Synthetic symbols global finctions:
|
|
||||||
|
|
||||||
inline void addSyntheticSymbol(
|
|
||||||
ULONG64 addr,
|
|
||||||
ULONG size,
|
|
||||||
const std::string &symName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return g_dbgClient->addSyntheticSymbol(addr, size, symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void delAllSyntheticSymbols()
|
|
||||||
{
|
|
||||||
return g_dbgClient->delAllSyntheticSymbols();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ULONG delSyntheticSymbol(
|
|
||||||
ULONG64 addr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return g_dbgClient->delSyntheticSymbol(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ULONG delSyntheticSymbolsMask(
|
|
||||||
const std::string &moduleName,
|
|
||||||
const std::string &symName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return g_dbgClient->delSyntheticSymbolsMask(moduleName, symName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline ULONG getNumberProcessors() {
|
|
||||||
return g_dbgClient->getNumberProcessors();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ULONG getPageSize() {
|
|
||||||
return g_dbgClient->getPageSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ContextPtr getThreadContext() {
|
|
||||||
return g_dbgClient->getThreadContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ContextPtr getThreadWow64Context() {
|
|
||||||
return g_dbgClient->getThreadWow64Context();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline python::dict getLocals(
|
|
||||||
ContextPtr ctx = ContextPtr()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return g_dbgClient->getLocals(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<ULONG status>
|
|
||||||
void DebugClient::changeDebuggerStatus()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = m_control->SetExecutionStatus( status );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
|
||||||
|
|
||||||
ULONG currentStatus;
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
waitForEvent();
|
|
||||||
|
|
||||||
hres = m_control->GetExecutionStatus( ¤tStatus );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
|
||||||
|
|
||||||
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<ULONG status>
|
|
||||||
void changeDebuggerStatus()
|
|
||||||
{
|
|
||||||
g_dbgClient->changeDebuggerStatus<status>();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline python::tuple getSourceLine( ULONG64 offset = 0 )
|
|
||||||
{
|
|
||||||
return g_dbgClient->getSourceLine(offset);
|
|
||||||
}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
}; // namespace pykd
|
|
||||||
|
|
||||||
|
|
@ -30,6 +30,7 @@ ULONG getModuleCheckSum( ULONG64 baseOffset );
|
|||||||
ULONG getRegIndexByName( const std::string ®Name );
|
ULONG getRegIndexByName( const std::string ®Name );
|
||||||
std::string getRegNameByIndex( ULONG index );
|
std::string getRegNameByIndex( ULONG index );
|
||||||
BaseTypeVariant getRegVariantValue( ULONG index );
|
BaseTypeVariant getRegVariantValue( ULONG index );
|
||||||
|
ULONG64 getRegInstructionPointer();
|
||||||
|
|
||||||
// ýòî íóæíî ñäåëàòü ïî-äðóãîìó!
|
// ýòî íóæíî ñäåëàòü ïî-äðóãîìó!
|
||||||
std::string getSymbolByOffset( ULONG64 offset );
|
std::string getSymbolByOffset( ULONG64 offset );
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dbgexcept.h"
|
|
||||||
#include "synsymbol.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class DbgObject {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
DbgObject( IDebugClient4 *client )
|
|
||||||
{
|
|
||||||
|
|
||||||
m_client = client;
|
|
||||||
|
|
||||||
HRESULT hres;
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugClient5), (void **)&m_client5 );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugClient5 failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugControl4 failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugSymbols3), (void**)&m_symbols );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugSymbols3 failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugAdvanced2), (void**)&m_advanced );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugAdvanced2 failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugDataSpaces4), (void**)&m_dataSpaces );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugDataSpaces failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugRegisters2), (void**)&m_registers );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugDataSpaces failed");
|
|
||||||
|
|
||||||
hres = client->QueryInterface( __uuidof(IDebugSystemObjects), (void**)&m_system );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugSystem2 failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~DbgObject() {};
|
|
||||||
|
|
||||||
CComPtr<IDebugClient5> m_client5;
|
|
||||||
CComPtr<IDebugClient4> m_client;
|
|
||||||
CComPtr<IDebugControl4> m_control;
|
|
||||||
CComPtr<IDebugSymbols3> m_symbols;
|
|
||||||
CComPtr<IDebugAdvanced2> m_advanced;
|
|
||||||
CComPtr<IDebugDataSpaces4> m_dataSpaces;
|
|
||||||
CComPtr<IDebugRegisters2> m_registers;
|
|
||||||
CComPtr<IDebugSystemObjects2> m_system;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}; // end of namespace pykd
|
|
@ -1,47 +1,20 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "dbgengine.h"
|
||||||
|
#include "disasmengine.h"
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "dbgmem.h"
|
|
||||||
#include "dbgclient.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Disasm::Disasm( IDebugClient4 *client, ULONG64 offset ) :
|
Disasm::Disasm( ULONG64 offset )
|
||||||
DbgObject( client )
|
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
m_beginOffset = addr64(offset);
|
m_beginOffset = addr64(offset);
|
||||||
|
|
||||||
if ( m_beginOffset == 0 )
|
if ( m_beginOffset == 0 )
|
||||||
{
|
m_beginOffset = getRegInstructionPointer();
|
||||||
hres = m_registers->GetInstructionOffset( &m_beginOffset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugRegisters::GetInstructionOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_currentOffset = m_beginOffset;
|
|
||||||
|
|
||||||
doDisasm();
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
Disasm::Disasm( ULONG64 offset ) :
|
|
||||||
DbgObject( g_dbgClient->client() )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
m_beginOffset = addr64(offset);
|
|
||||||
|
|
||||||
if ( m_beginOffset == 0 )
|
|
||||||
{
|
|
||||||
hres = m_registers->GetInstructionOffset( &m_beginOffset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugRegisters::GetInstructionOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_currentOffset = m_beginOffset;
|
m_currentOffset = m_beginOffset;
|
||||||
|
|
||||||
@ -52,30 +25,11 @@ Disasm::Disasm( ULONG64 offset ) :
|
|||||||
|
|
||||||
void Disasm::doDisasm()
|
void Disasm::doDisasm()
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
|
||||||
char buffer[0x100];
|
|
||||||
ULONG disasmSize = 0;
|
|
||||||
ULONG64 endOffset = 0;
|
ULONG64 endOffset = 0;
|
||||||
|
|
||||||
hres =
|
|
||||||
m_control->Disassemble(
|
|
||||||
m_currentOffset,
|
|
||||||
DEBUG_DISASM_EFFECTIVE_ADDRESS,
|
|
||||||
buffer,
|
|
||||||
sizeof(buffer),
|
|
||||||
&disasmSize,
|
|
||||||
&endOffset );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
disasmDisassembly( m_currentOffset, m_disasm, endOffset );
|
||||||
throw DbgException( "IDebugControl::Disassemble failed" );
|
|
||||||
|
|
||||||
hres = m_control->GetDisassembleEffectiveOffset( &m_ea );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
m_ea = 0;
|
|
||||||
|
|
||||||
m_length = (ULONG)(endOffset - m_currentOffset);
|
m_length = (ULONG)(endOffset - m_currentOffset);
|
||||||
|
|
||||||
m_disasm = std::string( buffer, disasmSize - 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -83,17 +37,13 @@ void Disasm::doDisasm()
|
|||||||
std::string
|
std::string
|
||||||
Disasm::assembly( const std::string &instr )
|
Disasm::assembly( const std::string &instr )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
ULONG64 endOffset = 0;
|
ULONG64 endOffset = 0;
|
||||||
hres = m_control->Assemble( m_currentOffset, instr.c_str(), &endOffset );
|
disasmAssemblay( m_currentOffset, instr, endOffset );
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::Assemble failed" );
|
|
||||||
|
|
||||||
m_currentOffset = endOffset;
|
m_currentOffset = endOffset;
|
||||||
|
|
||||||
doDisasm();
|
doDisasm();
|
||||||
|
|
||||||
return m_disasm;
|
return m_disasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dbgobj.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class Disasm : private DbgObject {
|
class Disasm {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Disasm( IDebugClient4 *client, ULONG64 offset = 0 );
|
|
||||||
|
|
||||||
Disasm( ULONG64 offset = 0);
|
Disasm( ULONG64 offset = 0);
|
||||||
|
|
||||||
std::string disassemble() {
|
std::string disassemble() {
|
||||||
|
8
pykd/disasmengine.h
Normal file
8
pykd/disasmengine.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
void disasmAssemblay( ULONG64 offset, const std::string &instruction, ULONG64 &nextOffset );
|
||||||
|
void disasmDisassembly( ULONG64 offset, std::string &instruction, ULONG64 &nextOffset );
|
||||||
|
|
||||||
|
} // end pykd namespace
|
@ -365,6 +365,10 @@
|
|||||||
RelativePath=".\dbgmem.cpp"
|
RelativePath=".\dbgmem.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\disasm.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\module.cpp"
|
RelativePath=".\module.cpp"
|
||||||
>
|
>
|
||||||
@ -451,6 +455,14 @@
|
|||||||
RelativePath=".\dbgmem.h"
|
RelativePath=".\dbgmem.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\disasm.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\disasmengine.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\module.h"
|
RelativePath=".\module.h"
|
||||||
>
|
>
|
||||||
@ -505,6 +517,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="win"
|
Name="win"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\win\dbgasm.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\win\dbgeng.cpp"
|
RelativePath=".\win\dbgeng.cpp"
|
||||||
>
|
>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "typeinfo.h"
|
#include "typeinfo.h"
|
||||||
#include "typedvar.h"
|
#include "typedvar.h"
|
||||||
#include "cpureg.h"
|
#include "cpureg.h"
|
||||||
|
#include "disasm.h"
|
||||||
|
|
||||||
using namespace pykd;
|
using namespace pykd;
|
||||||
|
|
||||||
@ -288,12 +289,24 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def("__getitem__", &TypedVar::getElementByIndex )
|
.def("__getitem__", &TypedVar::getElementByIndex )
|
||||||
.def("__getitem__", &TypedVar::getElementByIndexPtr );
|
.def("__getitem__", &TypedVar::getElementByIndexPtr );
|
||||||
|
|
||||||
|
|
||||||
python::class_<CpuReg, python::bases<intBase> >(
|
python::class_<CpuReg, python::bases<intBase> >(
|
||||||
"cpuReg", "CPU regsiter class", boost::python::no_init )
|
"cpuReg", "CPU regsiter class", boost::python::no_init )
|
||||||
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
||||||
.def( "index", &CpuReg::index, "The index of thr register" );
|
.def( "index", &CpuReg::index, "The index of thr register" );
|
||||||
|
|
||||||
|
python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
|
||||||
|
.def( python::init<>( "constructor" ) )
|
||||||
|
.def( python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
|
||||||
|
.def( "disasm", &Disasm::disassemble, "Disassemble next instruction" )
|
||||||
|
.def( "disasm", &Disasm::jump, "Disassemble from the specified offset" )
|
||||||
|
.def( "asm", &Disasm::assembly, "Insert assemblied instuction to current offset" )
|
||||||
|
.def( "begin", &Disasm::begin, "Return begin offset" )
|
||||||
|
.def( "current", &Disasm::current, "Return current offset" )
|
||||||
|
.def( "length", &Disasm::length, "Return current instruction length" )
|
||||||
|
.def( "instruction", &Disasm::instruction, "Returm current disassembled instruction" )
|
||||||
|
.def( "ea", &Disasm::ea, "Return effective address for last disassembled instruction or 0" )
|
||||||
|
.def( "reset", &Disasm::reset, "Reset current offset to begin" );
|
||||||
|
|
||||||
// wrapper for standart python exceptions
|
// wrapper for standart python exceptions
|
||||||
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
|
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
|
||||||
|
|
||||||
|
48
pykd/win/dbgasm.cpp
Normal file
48
pykd/win/dbgasm.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "win/dbgeng.h"
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void disasmAssemblay( ULONG64 offset, const std::string &instruction, ULONG64 &nextOffset )
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->Assemble( offset, instruction.c_str(), &nextOffset );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugControl::Assemble failed" );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void disasmDisassembly( ULONG64 offset, std::string &instruction, ULONG64 &nextOffset )
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
char buffer[0x100];
|
||||||
|
ULONG disasmSize = 0;
|
||||||
|
ULONG64 endOffset = 0;
|
||||||
|
|
||||||
|
hres =
|
||||||
|
g_dbgEng->control->Disassemble(
|
||||||
|
offset,
|
||||||
|
DEBUG_DISASM_EFFECTIVE_ADDRESS,
|
||||||
|
buffer,
|
||||||
|
sizeof(buffer),
|
||||||
|
&disasmSize,
|
||||||
|
&nextOffset );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugControl::Disassemble failed" );
|
||||||
|
|
||||||
|
instruction = std::string( buffer, disasmSize - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
} // end pykd namespace
|
@ -451,7 +451,7 @@ BaseTypeVariant getRegVariantValue( ULONG index )
|
|||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
DEBUG_VALUE debugValue;
|
DEBUG_VALUE debugValue;
|
||||||
hres = g_dbgEng->registers->GetValue( index, &debugValue );
|
hres = g_dbgEng->registers->GetValue( index, &debugValue );
|
||||||
@ -482,6 +482,22 @@ BaseTypeVariant getRegVariantValue( ULONG index )
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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
|
} // end pykd namespace
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user