[0.1.x] updated : Module class ( Class representing executable module )

git-svn-id: https://pykd.svn.codeplex.com/svn@69930 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-09-21 15:53:02 +00:00 committed by Mikhail I. Izmestev
parent 3333bdac13
commit f0127ccff3
13 changed files with 317 additions and 24 deletions

View File

@ -3,7 +3,29 @@
#include "dbgclient.h"
#include <vector>
using namespace pykd;
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
DebugClient primaryClient;
DebugClient *g_dbgClient = &primaryClient;
void loadDump( const std::wstring &fileName ) {
g_dbgClient->loadDump( fileName );
}
void startProcess( const std::wstring &processName ) {
g_dbgClient->startProcess( processName );
}
void attachProcess( ULONG processId ) {
g_dbgClient->attachProcess( processId );
}
void attachKernel( const std::wstring &param ) {
g_dbgClient->attachKernel( param );
}
///////////////////////////////////////////////////////////////////////////////////
@ -90,3 +112,5 @@ void DebugClient::attachKernel( const std::wstring &param )
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd

View File

@ -33,6 +33,11 @@ public:
return Module( m_client, moduleName );
}
Module findModule( ULONG64 offset ) {
return Module( m_client, offset );
}
ULONG64 addr64( ULONG64 addr );
private:
@ -43,6 +48,22 @@ private:
/////////////////////////////////////////////////////////////////////////////////
extern DebugClient *g_dbgClient;
void loadDump( const std::wstring &fileName );
void startProcess( const std::wstring &processName );
void attachProcess( ULONG processId );
void attachKernel( const std::wstring &param );
Module loadModule( const std::string &moduleName );
Module findModule( ULONG64 offset );
/////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -19,6 +19,11 @@ void DbgException::exceptionTranslate( const DbgException &e )
/////////////////////////////////////////////////////////////////////////////////
//PyObject *eventExceptionType = NULL;
//PyObject *typeExceptionType = NULL;
//PyObject *memoryExceptionType = NULL;

View File

@ -42,6 +42,17 @@ private:
///////////////////////////////////////////////////////////////////////////////////
//
//class WaitEventException : public DbgException
//{

View File

@ -89,11 +89,31 @@ static python::dict genDict(const pyDia::Symbol::ValueNameEntry srcValues[], siz
BOOST_PYTHON_MODULE( pykd )
{
python::class_<pykd::DebugClient>("dbgClient", "Class representing a debugging session" )
.def( "loadDump", &pykd::DebugClient::loadDump, "Load crash dump" )
.def( "startProcess", &pykd::DebugClient::startProcess, "Start process for debugging" )
.def( "attachProcess", &pykd::DebugClient::attachProcess, "Attach debugger to a exsisting process" )
.def( "attachKernel", &pykd::DebugClient::attachKernel, "Attach debugger to a target's kernel" )
.def( "loadModule", &pykd::DebugClient::loadModule, "Create instance of Module class" );
.def( "loadDump", &pykd::DebugClient::loadDump,
"Load crash dump" )
.def( "startProcess", &pykd::DebugClient::startProcess,
"Start process for debugging" )
.def( "attachProcess", &pykd::DebugClient::attachProcess,
"Attach debugger to a exsisting process" )
.def( "attachKernel", &pykd::DebugClient::attachKernel,
"Attach debugger to a target's kernel" )
.def( "loadModule", &pykd::DebugClient::loadModule,
"Return instance of Module class" )
.def( "findModule", &pykd::DebugClient::findModule,
"Return instance of the Module class which posseses specified address" );
boost::python::def( "loadDump", &loadDump,
"Load crash dump (only for console)");
boost::python::def( "startProcess", &startProcess,
"Start process for debugging (only for console)");
boost::python::def( "attachProcess", &attachProcess,
"Attach debugger to a exsisting process" );
boost::python::def( "attachKernel", &attachKernel,
"Attach debugger to a kernel target" );
boost::python::def( "loadModule", &loadModule,
"Return instance of Module class" );
boost::python::def( "findModule", &findModule,
"Return instance of the Module class which posseses specified address" );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase,
@ -103,7 +123,11 @@ BOOST_PYTHON_MODULE( pykd )
.def("size", &pykd::Module::getSize,
"Return size of the module" )
.def("name", &pykd::Module::getName,
"Return name of the module" );
"Return name of the module" )
.def("pdb", &pykd::Module::getPdbName,
"Return the full path to the module's pdb file ( symbol information )" )
.def("reload", &pykd::Module::reloadSymbols,
"(Re)load symbols for the module" );
python::def( "diaOpenPdb", &pyDia::GlobalScope::openPdb,
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
@ -224,16 +248,19 @@ BOOST_PYTHON_MODULE( pykd )
genDict(pyDia::Symbol::basicTypeName, pyDia::Symbol::cntBasicTypeName);
// exception:
// base exception
python::class_<DbgException> dbgExceptionClass( "BaseException",
python::class_<pykd::DbgException> dbgExceptionClass( "BaseException",
"Pykd base exception class",
python::no_init );
dbgExceptionClass
.def( python::init<std::string>( python::args("desc"), "constructor" ) )
.def( "desc", &DbgException::getDesc,
.def( "desc", &pykd::DbgException::getDesc,
"Get exception description" )
.def( "__str__", &DbgException::print);
DbgException::setTypeObject( dbgExceptionClass.ptr() );
.def( "__str__", &pykd::DbgException::print);
pykd::DbgException::setTypeObject( dbgExceptionClass.ptr() );
boost::python::register_exception_translator<pykd::DbgException>(
&pykd::DbgException::exceptionTranslate );
// DIA exceptions
python::class_<pyDia::Exception, python::bases<DbgException> > diaException(

View File

@ -1,5 +1,54 @@
#include "stdafx.h"
#include "dbgclient.h"
#include "dbgexcept.h"
namespace pykd {
/////////////////////////////////////////////////////////////////////////////////////
ULONG64
DebugClient::addr64( ULONG64 addr)
{
HRESULT hres;
ULONG processorMode;
hres = m_control->GetActualProcessorType( &processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
switch( processorMode )
{
case IMAGE_FILE_MACHINE_I386:
if ( *( (ULONG*)&addr + 1 ) == 0 )
return (ULONG64)(LONG)addr;
case IMAGE_FILE_MACHINE_AMD64:
break;
default:
throw DbgException( "Unknown processor type" );
break;
}
return addr;
}
ULONG64
addr64( ULONG64 addr)
{
return g_dbgClient->addr64( addr );
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end of pykd
//#include <boost/scoped_array.hpp>
//
//#include "dbgext.h"

View File

@ -1,5 +1,21 @@
#pragma once
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
ULONG64
addr64( ULONG64 addr );
///////////////////////////////////////////////////////////////////////////////////
};
//#include <boost/scoped_array.hpp>
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -25,6 +25,10 @@ protected:
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");
}
virtual ~DbgObject() {};
@ -32,6 +36,7 @@ protected:
CComPtr<IDebugClient5> m_client;
CComPtr<IDebugControl4> m_control;
CComPtr<IDebugSymbols3> m_symbols;
CComPtr<IDebugAdvanced2> m_advanced;
};

View File

@ -1,8 +1,22 @@
#include "stdafx.h"
#include "module.h"
#include "dbgclient.h"
#include "dbgmem.h"
using namespace pykd;
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
Module loadModule( const std::string &moduleName ) {
return g_dbgClient->loadModule( moduleName );
};
///////////////////////////////////////////////////////////////////////////////////
Module findModule( ULONG64 offset ) {
return g_dbgClient->findModule( offset );
}
///////////////////////////////////////////////////////////////////////////////////
@ -26,6 +40,100 @@ Module::Module( IDebugClient5 *client, const std::string& moduleName ) : DbgObje
///////////////////////////////////////////////////////////////////////////////////
Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client )
{
HRESULT hres;
offset = addr64( offset );
ULONG moduleIndex;
hres = m_symbols->GetModuleByOffset( offset, 0, &moduleIndex, &m_base );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByOffset failed" );
char moduleName[0x100];
hres = m_symbols->GetModuleNameString(
DEBUG_MODNAME_MODULE,
moduleIndex,
0,
moduleName,
sizeof( moduleName ),
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
m_name = std::string( moduleName );
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
m_size = moduleParam.Size;
}
///////////////////////////////////////////////////////////////////////////////////
std::wstring
Module::getPdbName()
{
HRESULT hres;
IMAGEHLP_MODULEW64 moduleInfo = {};
hres = m_advanced->GetSymbolInformation(
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
m_base,
0,
&moduleInfo,
sizeof(moduleInfo),
NULL,
NULL,
0,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
return std::wstring( moduleInfo.LoadedPdbName );
}
///////////////////////////////////////////////////////////////////////////////////
void
Module::reloadSymbols()
{
HRESULT hres;
hres = m_symbols->Reload( "/f" );
if ( FAILED( hres ) )
throw DbgException("IDebugSymbols::Reload failed" );
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd
// // try reload module by entered name, "silent mode"
// OutputReader outputReader( dbgExt->client );
// hres = dbgExt->symbols->Reload( reloadParam.c_str() );

View File

@ -14,6 +14,8 @@ public:
Module( IDebugClient5 *client, const std::string& moduleName );
Module( IDebugClient5 *client, ULONG64 offset );
std::string getName() {
return m_name;
}
@ -30,6 +32,12 @@ public:
return m_size;
}
std::wstring
getPdbName();
void
reloadSymbols();
private:
std::string m_name;
@ -47,11 +55,6 @@ private:
//#include <string>
//#include <map>
//

View File

@ -361,6 +361,10 @@
RelativePath=".\dbgext.cpp"
>
</File>
<File
RelativePath=".\dbgmem.cpp"
>
</File>
<File
RelativePath=".\diawrapper.cpp"
>
@ -423,6 +427,10 @@
RelativePath=".\dbgexcept.h"
>
</File>
<File
RelativePath=".\dbgmem.h"
>
</File>
<File
RelativePath=".\dbgobj.h"
>

View File

@ -22,3 +22,21 @@ class ModuleTest( unittest.TestCase ):
def testEnd( self ):
self.assertEqual( target.module.size(), target.module.end() - target.module.begin() )
def testPdb( self ):
self.assertNotEqual( "", target.module.pdb() );
def testFindModule( self ):
try: pykd.findModule( target.module.begin() - 0x10 )
except pykd.BaseException: pass
#self.assertRaises( pykd.BaseException, pykd.findModule, target.module.begin() - 0x10 )
self.assertNotEqual( None, pykd.findModule( target.module.begin() ) )
self.assertNotEqual( None, pykd.findModule( target.module.begin() + 0x10) )
try: pykd.findModule( target.module.end() )
except pykd.BaseException: pass
try: pykd.findModule( target.module.end() + 0x10)
except pykd.BaseException: pass

View File

@ -35,12 +35,10 @@ if __name__ == "__main__":
target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0]
print "\nTest module: %s" % targetAppPath
dbg = pykd.dbgClient()
pykd.startProcess( targetAppPath )
dbg.startProcess( targetAppPath )
# pykd.go()
target.module = dbg.loadModule( target.moduleName )
target.module = pykd.loadModule( target.moduleName )
target.module.reload();
suite = getTestSuite()