mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[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:
parent
3333bdac13
commit
f0127ccff3
@ -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 ¶m ) {
|
||||
g_dbgClient->attachKernel( param );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -89,4 +111,6 @@ void DebugClient::attachKernel( const std::wstring ¶m )
|
||||
throw DbgException( "IDebugClient5::AttachKernelWide failed" );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // end of namespace pykd
|
@ -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 ¶m );
|
||||
|
||||
Module loadModule( const std::string &moduleName );
|
||||
|
||||
Module findModule( ULONG64 offset );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
||||
|
||||
|
||||
|
@ -19,6 +19,11 @@ void DbgException::exceptionTranslate( const DbgException &e )
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//PyObject *eventExceptionType = NULL;
|
||||
//PyObject *typeExceptionType = NULL;
|
||||
//PyObject *memoryExceptionType = NULL;
|
||||
|
@ -42,6 +42,17 @@ private:
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//class WaitEventException : public DbgException
|
||||
//{
|
||||
|
@ -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(
|
||||
|
@ -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"
|
||||
|
@ -1,5 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG64
|
||||
addr64( ULONG64 addr );
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//#include <boost/scoped_array.hpp>
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
110
pykd/module.cpp
110
pykd/module.cpp
@ -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() );
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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>
|
||||
//
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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
|
||||
|
@ -34,13 +34,11 @@ if __name__ == "__main__":
|
||||
|
||||
target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0]
|
||||
print "\nTest module: %s" % targetAppPath
|
||||
|
||||
dbg = pykd.dbgClient()
|
||||
|
||||
dbg.startProcess( targetAppPath )
|
||||
# pykd.go()
|
||||
|
||||
pykd.startProcess( targetAppPath )
|
||||
|
||||
target.module = dbg.loadModule( target.moduleName )
|
||||
target.module = pykd.loadModule( target.moduleName )
|
||||
target.module.reload();
|
||||
|
||||
suite = getTestSuite()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user