mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[0.1.x]
+ eventHandler.onLoadModule + eventHandler.onUnloadModule ~ change eventHandler.onUnloadModule parameter: Module -> base addresss + test load/unload modules handling git-svn-id: https://pykd.svn.codeplex.com/svn@72056 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
8e59db7fcc
commit
7889544689
@ -295,7 +295,12 @@ void DebugClient::waitForEvent()
|
|||||||
} while( false );
|
} while( false );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
|
{
|
||||||
|
if (E_UNEXPECTED == hres)
|
||||||
|
throw WaitEventException();
|
||||||
|
|
||||||
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForEvent()
|
void waitForEvent()
|
||||||
@ -317,6 +322,8 @@ ULONG DebugClient::ptrSize()
|
|||||||
return S_OK == hres ? 8 : 4;
|
return S_OK == hres ? 8 : 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG ptrSize()
|
ULONG ptrSize()
|
||||||
{
|
{
|
||||||
return g_dbgClient->ptrSize();
|
return g_dbgClient->ptrSize();
|
||||||
|
@ -222,6 +222,10 @@ public:
|
|||||||
return m_symSymbols->removeByMask(moduleName, symName);
|
return m_symSymbols->removeByMask(moduleName, symName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SynSymbolsPtr getSynSymbols() {
|
||||||
|
return m_symSymbols;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -177,25 +177,8 @@ HRESULT EventHandler::LoadModule(
|
|||||||
__in ULONG TimeDateStamp
|
__in ULONG TimeDateStamp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
||||||
|
return onLoadModule( m_parentClient->loadModuleByOffset(BaseOffset) );
|
||||||
//return onLoadModule( module );
|
|
||||||
|
|
||||||
//std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
|
|
||||||
|
|
||||||
//ULONG64 moduleBase;
|
|
||||||
//ULONG moduleSize;
|
|
||||||
//std::string moduleName;
|
|
||||||
//
|
|
||||||
//queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
|
|
||||||
//dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
|
||||||
//silentMode.reset();
|
|
||||||
|
|
||||||
//PyThread_StateSave pyThreadSave;
|
|
||||||
//return onLoadModule( module );
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -205,19 +188,9 @@ HRESULT EventHandler::UnloadModule(
|
|||||||
__in ULONG64 BaseOffset
|
__in ULONG64 BaseOffset
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
|
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
||||||
|
BaseOffset = m_parentClient->addr64(BaseOffset);
|
||||||
//ULONG64 moduleBase;
|
return onUnloadModule( BaseOffset );
|
||||||
//ULONG moduleSize;
|
|
||||||
//std::string moduleName;
|
|
||||||
//
|
|
||||||
//queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
|
|
||||||
//dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
|
||||||
//silentMode.reset();
|
|
||||||
|
|
||||||
//PyThread_StateSave pyThreadSave;
|
|
||||||
//return onUnloadModule( module );
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -75,7 +75,7 @@ protected:
|
|||||||
|
|
||||||
virtual ULONG onLoadModule(const Module &/* module */) = 0;
|
virtual ULONG onLoadModule(const Module &/* module */) = 0;
|
||||||
|
|
||||||
virtual ULONG onUnloadModule(const Module &/* module */) = 0;
|
virtual ULONG onUnloadModule(ULONG64 /*modBase*/) = 0;
|
||||||
|
|
||||||
virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
|
virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
|
||||||
|
|
||||||
@ -113,8 +113,8 @@ public:
|
|||||||
return handler<const Module&>("onLoadModule", module );
|
return handler<const Module&>("onLoadModule", module );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG onUnloadModule(const Module &module) {
|
ULONG onUnloadModule(ULONG64 modBase) {
|
||||||
return handler<const Module&>("onUnloadModule", module );
|
return handler<ULONG64>("onUnloadModule", modBase );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG onChangeSessionStatus( ULONG status ) {
|
ULONG onChangeSessionStatus( ULONG status ) {
|
||||||
|
@ -7,6 +7,7 @@ namespace pykd {
|
|||||||
|
|
||||||
PyObject *DbgException::baseExceptTypeObject = NULL;
|
PyObject *DbgException::baseExceptTypeObject = NULL;
|
||||||
PyObject *MemoryException::memoryExceptionTypeObject = NULL;
|
PyObject *MemoryException::memoryExceptionTypeObject = NULL;
|
||||||
|
PyObject *WaitEventException::waitEventExceptTypeObject = NULL;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -36,6 +37,16 @@ std::string buildExceptDesc(PCSTR routineName, HRESULT hres)
|
|||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void WaitEventException::exceptionTranslate( const WaitEventException &e )
|
||||||
|
{
|
||||||
|
python::object pyExcept(e);
|
||||||
|
|
||||||
|
PyErr_SetObject( waitEventExceptTypeObject, pyExcept.ptr() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // end namespace pykd
|
}; // end namespace pykd
|
||||||
|
@ -116,6 +116,25 @@ private:
|
|||||||
std::string buildExceptDesc(PCSTR routineName, HRESULT hres);
|
std::string buildExceptDesc(PCSTR routineName, HRESULT hres);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class WaitEventException : public DbgException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaitEventException()
|
||||||
|
: DbgException( "None of the targets could generate events" )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exceptionTranslate(const WaitEventException &e);
|
||||||
|
|
||||||
|
static void setTypeObject(PyObject *p) {
|
||||||
|
waitEventExceptTypeObject = p;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static PyObject *waitEventExceptTypeObject;
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // namespace pykd
|
}; // namespace pykd
|
||||||
|
@ -448,10 +448,10 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Detailed information: http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx \n"
|
"Detailed information: http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx \n"
|
||||||
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
||||||
.def( "onLoadModule", &pykd::EventHandlerWrap::onLoadModule,
|
.def( "onLoadModule", &pykd::EventHandlerWrap::onLoadModule,
|
||||||
"Load module event. Parameter is instance of dbgModuleClass.\n"
|
"Load module event. Parameter is instance of module.\n"
|
||||||
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
||||||
.def( "onUnloadModule", &pykd::EventHandlerWrap::onUnloadModule,
|
.def( "onUnloadModule", &pykd::EventHandlerWrap::onUnloadModule,
|
||||||
"Unload module event. Parameter is instance of dbgModuleClass.\n"
|
"Unload module event. Parameter is base address of unloaded module.\n"
|
||||||
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
|
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
|
||||||
|
|
||||||
python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
|
python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
|
||||||
@ -662,6 +662,15 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
python::register_exception_translator<pykd::MemoryException>(
|
python::register_exception_translator<pykd::MemoryException>(
|
||||||
&pykd::MemoryException::exceptionTranslate );
|
&pykd::MemoryException::exceptionTranslate );
|
||||||
|
|
||||||
|
// Wait debug event exception
|
||||||
|
python::class_<WaitEventException, python::bases<DbgException> > waitEventException(
|
||||||
|
"WaitEventException", "Debug interface access exception", python::no_init);
|
||||||
|
waitEventException
|
||||||
|
_DECL_BASE_EXCEPT_STR;
|
||||||
|
WaitEventException::setTypeObject( waitEventException.ptr() );
|
||||||
|
python::register_exception_translator<WaitEventException>(
|
||||||
|
&WaitEventException::exceptionTranslate );
|
||||||
|
|
||||||
DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED );
|
DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED );
|
||||||
DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL );
|
DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL );
|
||||||
DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS );
|
DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS );
|
||||||
|
51
test/scripts/ehloadtest.py
Normal file
51
test/scripts/ehloadtest.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
"""Debug events handler: test [un-]load modules notification"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import target
|
||||||
|
import pykd
|
||||||
|
import fnmatch
|
||||||
|
|
||||||
|
class ModuleLoadHandler(pykd.eventHandler):
|
||||||
|
"""Track load/unload module implementation"""
|
||||||
|
def __init__(self, client, moduleMask):
|
||||||
|
pykd.eventHandler.__init__(self, client)
|
||||||
|
|
||||||
|
self.moduleMask = moduleMask.lower()
|
||||||
|
|
||||||
|
self.wasLoad = 0
|
||||||
|
self.wasUnload = False
|
||||||
|
|
||||||
|
def onLoadModule(self, module):
|
||||||
|
"""Load module handler"""
|
||||||
|
|
||||||
|
if ( fnmatch.fnmatch(module.name().lower(), self.moduleMask) ):
|
||||||
|
self.wasLoad = module.begin()
|
||||||
|
|
||||||
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
def onUnloadModule(self, modBase):
|
||||||
|
"""Unload module handler"""
|
||||||
|
|
||||||
|
if ( self.wasLoad and (self.wasLoad == modBase) ):
|
||||||
|
self.wasUnload = True
|
||||||
|
|
||||||
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
class EhLoadTest(unittest.TestCase):
|
||||||
|
"""Unit tests of [un-]load modules notification"""
|
||||||
|
|
||||||
|
def testLoadUnload(self):
|
||||||
|
"""Start new process and track loading and unloading modules"""
|
||||||
|
testClient = pykd.createDbgClient()
|
||||||
|
testClient.startProcess( target.appPath + " -testLoadUnload" )
|
||||||
|
|
||||||
|
modLoadHandler = ModuleLoadHandler( testClient, "*Iphlpapi*" )
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
testClient.go()
|
||||||
|
except pykd.WaitEventException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertTrue(modLoadHandler.wasLoad)
|
||||||
|
self.assertTrue(modLoadHandler.wasUnload)
|
||||||
|
|
@ -23,6 +23,7 @@ import typedvar
|
|||||||
import memtest
|
import memtest
|
||||||
import intbase
|
import intbase
|
||||||
import synsymtest
|
import synsymtest
|
||||||
|
import ehloadtest
|
||||||
|
|
||||||
def getTestSuite( singleName = "" ):
|
def getTestSuite( singleName = "" ):
|
||||||
if singleName == "":
|
if singleName == "":
|
||||||
@ -37,7 +38,8 @@ def getTestSuite( singleName = "" ):
|
|||||||
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ),
|
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
|
unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest )
|
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
|
||||||
|
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest )
|
||||||
] )
|
] )
|
||||||
else:
|
else:
|
||||||
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
||||||
@ -45,12 +47,12 @@ def getTestSuite( singleName = "" ):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
targetAppPath = sys.argv[1]
|
target.appPath = sys.argv[1]
|
||||||
|
|
||||||
target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0]
|
target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
|
||||||
print "\nTest module: %s" % targetAppPath
|
print "\nTest module: %s" % target.appPath
|
||||||
|
|
||||||
pykd.startProcess( targetAppPath )
|
pykd.startProcess( target.appPath )
|
||||||
|
|
||||||
target.module = pykd.loadModule( target.moduleName )
|
target.module = pykd.loadModule( target.moduleName )
|
||||||
target.module.reload();
|
target.module.reload();
|
||||||
|
@ -5,3 +5,4 @@
|
|||||||
module = None
|
module = None
|
||||||
moduleName = None
|
moduleName = None
|
||||||
dbgext = None
|
dbgext = None
|
||||||
|
appPath = None
|
||||||
|
@ -159,6 +159,7 @@ void FuncWithName1(int a)
|
|||||||
|
|
||||||
int doLoadUnload()
|
int doLoadUnload()
|
||||||
{
|
{
|
||||||
|
__debugbreak();
|
||||||
HMODULE hmod = ::LoadLibrary( _T("iphlpapi.dll") );
|
HMODULE hmod = ::LoadLibrary( _T("iphlpapi.dll") );
|
||||||
if (hmod)
|
if (hmod)
|
||||||
::FreeLibrary(hmod);
|
::FreeLibrary(hmod);
|
||||||
@ -172,6 +173,9 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Let test scripts to execute
|
||||||
|
__debugbreak();
|
||||||
|
|
||||||
if (2 == argc)
|
if (2 == argc)
|
||||||
{
|
{
|
||||||
// run with parameters
|
// run with parameters
|
||||||
@ -179,8 +183,6 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
return doLoadUnload();
|
return doLoadUnload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let test scripts to execute
|
|
||||||
__debugbreak();
|
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
@ -416,6 +416,10 @@
|
|||||||
RelativePath="..\scripts\diatest.py"
|
RelativePath="..\scripts\diatest.py"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\scripts\ehloadtest.py"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\scripts\eventtest.py"
|
RelativePath="..\scripts\eventtest.py"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user