diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 1f9e2e3..a7422ad 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -59,6 +59,79 @@ WindbgGlobalSession *WindbgGlobalSession::windbgGlobalSession = NULL; //////////////////////////////////////////////////////////////////////////////// +class InterruptWatch +{ +public: + InterruptWatch( PDEBUG_CLIENT4 client, python::object& global ) + { + m_debugControl = client; + + m_global = global; + + m_stopEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + + m_thread = + CreateThread( + NULL, + 0, + threadRoutine, + this, + 0, + NULL ); + } + + ~InterruptWatch() + { + SetEvent( m_stopEvent ); + + WaitForSingleObject( m_thread, INFINITE ); + + CloseHandle( m_stopEvent ); + + CloseHandle( m_thread ); + } + +private: + + + static int quit(void *) { + PyErr_SetString( PyExc_SystemExit, "" ); + return -1; + } + + DWORD workRoutine(){ + + while( WAIT_TIMEOUT == WaitForSingleObject( m_stopEvent, 250 ) ) + { + HRESULT hres = m_debugControl->GetInterrupt(); + if ( hres == S_OK ) + { + PyGILState_STATE state = PyGILState_Ensure(); + Py_AddPendingCall(&quit, NULL); + PyGILState_Release(state); + + break; + } + } + + return 0; + } + + static DWORD WINAPI threadRoutine(LPVOID lpParameter) { + return static_cast(lpParameter)->workRoutine(); + } + + HANDLE m_thread; + + HANDLE m_stopEvent; + + python::object m_global; + + CComQIPtr m_debugControl; +}; + +//////////////////////////////////////////////////////////////////////////////// + BOOL WINAPI DllMain( __in HINSTANCE /*hinstDLL*/, __in DWORD fdwReason, @@ -121,6 +194,8 @@ py( PDEBUG_CLIENT4 client, PCSTR args ) python::object global(main.attr("__dict__")); + InterruptWatch interruptWatch( client, global ); + // настраиваем ввод/вывод ( чтобы в скрипте можно было писать print ) python::object sys = python::import("sys"); @@ -228,24 +303,28 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args ) client->GetOutputMask( &mask ); client->SetOutputMask( mask & ~DEBUG_OUTPUT_PROMPT ); // убрать эхо ввода + InterruptWatch interruptWatch( client, WindbgGlobalSession::global() ); + try { - PyRun_String( - "__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()", - Py_file_input, - WindbgGlobalSession::global().ptr(), - WindbgGlobalSession::global().ptr() + python::exec( + "try:\n" + " __import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()\n" + "except SystemExit:\n" + " print 'Ctrl+Break'\n", + WindbgGlobalSession::global(), + WindbgGlobalSession::global() ); - - // выход из интерпретатора происходит через исключение raise SystemExit(code) - // которое потом может помешать исполнению callback ов - PyErr_Clear(); } catch(...) { eprintln( L"unexpected error" ); } + // выход из интерпретатора происходит через исключение raise SystemExit(code) + // которое потом может помешать исполнению callback ов + PyErr_Clear(); + client->SetOutputMask( mask ); WindbgGlobalSession::SavePyState(); diff --git a/snippets/nbl.py b/snippets/nbl.py index 8e91d04..c3eb67e 100644 --- a/snippets/nbl.py +++ b/snippets/nbl.py @@ -154,8 +154,8 @@ class IpProtocol: def getNextLayerPacket( self, dataPos ): return { - ICMP_PROTO : lambda x : "", - UDP_PROTO : lambda x : UdpPacket(x), + ICMP_PROTO : lambda x : "", + UDP_PROTO : lambda x : UdpPacket(x), TCP_PROTO : lambda x : TcpPacket(x) }.get( self.typeVal, lambda x : "Unknown protocol" )(dataPos) @@ -382,7 +382,7 @@ def getPacketFromNb( nb ): pcktBytes = list() - mdl = typedVar( "ndis", "_MDL", nb.CurrentMdl ) + mdl = typedVar( "ndis!_MDL", nb.CurrentMdl ) dataLength = nb.DataLength dataOffset = nb.CurrentMdlOffset @@ -395,9 +395,9 @@ def getPacketFromNb( nb ): dataLength -= copyData - mdl = typedVar( "ndis", "_MDL", mdl.Next ) + mdl = typedVar( "ndis!_MDL", mdl.Next ) - return pcktBytes + return pcktBytes @@ -405,11 +405,11 @@ def getPacketsFromNbl( nblAddr ): pcktList = list() - nbl = typedVar( "ndis", "_NET_BUFFER_LIST", nblAddr ) + nbl = typedVar( "ndis!_NET_BUFFER_LIST", nblAddr ) while True: - nb = typedVar( "ndis", "_NET_BUFFER", nbl.FirstNetBuffer ) + nb = typedVar( "ndis!_NET_BUFFER", nbl.FirstNetBuffer ) while True: @@ -418,12 +418,12 @@ def getPacketsFromNbl( nblAddr ): if nb.Next == 0: break - nb = typedVar( "ndis", "_NET_BUFFER", nb.Next ) + nb = typedVar( "ndis!_NET_BUFFER", nb.Next ) if nbl.Next == 0: break - nbl = typedVar( "ndis", "_NET_BUFFER_LIST", nbl.Next ) + nbl = typedVar( "ndis!_NET_BUFFER_LIST", nbl.Next ) return pcktList @@ -437,7 +437,7 @@ def printNblStruct( nblAddr ): dprintln( "NET_BUFFER_LIST %#x" % nblAddr ) - nbl = typedVar( "ndis", "_NET_BUFFER_LIST", nblAddr ) + nbl = typedVar( "ndis!_NET_BUFFER_LIST", nblAddr ) nbAddr = nbl.FirstNetBuffer @@ -445,7 +445,7 @@ def printNblStruct( nblAddr ): dprint( "\tNET_BUFFER %#x" % nbAddr ) - nb = typedVar( "ndis", "_NET_BUFFER", nbAddr ) + nb = typedVar( "ndis!_NET_BUFFER", nbAddr ) dprintln( " data length = %d, data offset = %#x " % ( nb.DataLength, nb.DataOffset ) ) @@ -455,7 +455,7 @@ def printNblStruct( nblAddr ): dprint( "\t\tMDL %#x" % mdlAddr ) - mdl = typedVar( "ndis", "_MDL", mdlAddr ) + mdl = typedVar( "ndis!_MDL", mdlAddr ) dprintln( " byte count = %d, byte offset = %#x, mapped addr = %#x" % ( mdl.ByteCount, mdl.ByteOffset, mdl.MappedSystemVa ) )