diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index ca9bdb6..d9ade43 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -11,6 +11,7 @@ #include "memaccess.h" #include "typeinfo.h" #include "typedvar.h" +#include "windbgext.h" using namespace pykd; @@ -94,8 +95,8 @@ BOOST_PYTHON_MODULE( pykd ) "Check if it is a dump analyzing ( not living debuggee )" ); python::def( "isKernelDebugging", &kdlib::isKernelDebugging, "Check if kernel dubugging is running" ); - //python::def( "isWindbgExt", &WindbgGlobalSession::isInit, - // "Check if script works in windbg context" ); + python::def( "isWindbgExt", &PykdExt::isInit, + "Check if script works in windbg context" ); python::def( "writeDump", &kdlib::writeDump, "Create memory dump file" ); diff --git a/pykd/windbgext.cpp b/pykd/windbgext.cpp index 1a3c6cc..9b0b034 100644 --- a/pykd/windbgext.cpp +++ b/pykd/windbgext.cpp @@ -1,17 +1,26 @@ #include "stdafx.h" + +#include +namespace python = boost::python; + #include "kdlib/kdlib.h" #include "kdlib/windbg.h" #include "windbgext.h" +#include "dbgexcept.h" using namespace kdlib; using namespace kdlib::windbg; +using namespace pykd; /////////////////////////////////////////////////////////////////////////////// KDLIB_WINDBG_EXTENSION_INIT( PykdExt ); +bool PykdExt::isInit() { + return WinDbgExt->isInit(); +} /////////////////////////////////////////////////////////////////////////////// @@ -25,7 +34,7 @@ void PykdExt::setUp() Py_Initialize(); - boost::python::import( "pykd" ); + python::import( "pykd" ); // перенаправление стандартных потоков ВВ python::object sys = python::import("sys"); @@ -33,6 +42,14 @@ void PykdExt::setUp() sys.attr("stdout") = python::ptr( dbgout ); sys.attr("stderr") = python::ptr( dbgout ); sys.attr("stdin") = python::ptr( dbgin ); + + + python::list pathList(sys.attr("path")); + + python::ssize_t n = python::len(pathList); + + for (python::ssize_t i = 0; i < n ; i++) + m_paths.push_back(boost::python::extract(pathList[i])); } /////////////////////////////////////////////////////////////////////////////// @@ -55,52 +72,50 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py) startConsole(); return; } -} + std::string scriptFileName = getScriptFileName( args[0] ); -/////////////////////////////////////////////////////////////////////////////// - -void printException() -{ - // ошибка в скрипте - PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL; - - PyErr_Fetch( &errtype, &errvalue, &traceback ); - - PyErr_NormalizeException( &errtype, &errvalue, &traceback ); - - if ( errtype == PyExc_SystemExit ) + if ( scriptFileName.empty() ) + { + eprintln( L"script file not found" ); return; + } - python::object tracebackModule = python::import("traceback"); + // устанавиливаем питоновские аргументы + char **pythonArgs = new char* [ args.size() ]; - std::wstringstream sstr; + for ( size_t i = 0; i < args.size(); ++i ) + pythonArgs[i] = const_cast( args[i].c_str() ); - python::object lst = - python::object( tracebackModule.attr("format_exception" ) )( - python::handle<>( errtype ), - python::handle<>( python::allow_null( errvalue ) ), - python::handle<>( python::allow_null( traceback ) ) ); + PySys_SetArgv( (int)args.size(), pythonArgs ); - sstr << std::endl << std::endl; + delete[] pythonArgs; - for ( long i = 0; i < python::len(lst); ++i ) - sstr << std::wstring( python::extract(lst[i]) ) << std::endl; + // получаем достпу к глобальному мапу ( нужен для вызова exec_file ) + python::object main = python::import("__main__"); - eprintln( sstr.str() ); + python::object global(main.attr("__dict__")); + + try { + python::exec_file( scriptFileName.c_str(), global ); + } + catch( python::error_already_set const & ) + { + printException(); + } } /////////////////////////////////////////////////////////////////////////////// void PykdExt::startConsole() { + + // получаем достпу к глобальному мапу ( нужен для вызова exec_file ) + python::object main = python::import("__main__"); + + python::object global(main.attr("__dict__")); + try { - - // получаем достпу к глобальному мапу ( нужен для вызова exec_file ) - python::object main = python::import("__main__"); - - python::object global(main.attr("__dict__")); - python::exec( "__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()\n", global ); } catch( python::error_already_set const & ) @@ -110,3 +125,56 @@ void PykdExt::startConsole() } /////////////////////////////////////////////////////////////////////////////// + +std::string PykdExt::getScriptFileName( const std::string &scriptName ) +{ + bool fileHasPyExt = false; + + if ( scriptName.length() > 3 ) + fileHasPyExt = scriptName.rfind(".py") == scriptName.length() - 3; + + std::string fullFileName = scriptName; + + if (!fileHasPyExt) + fullFileName += ".py"; + + if ( GetFileAttributesA(fullFileName.c_str()) != INVALID_FILE_ATTRIBUTES ) + return fullFileName; + + std::vector::const_iterator it = m_paths.begin(); + for ( ; it != m_paths.end(); ++it) + { + DWORD bufSize = SearchPathA( + (*it).c_str(), + fullFileName.c_str(), + NULL, + 0, + NULL, + NULL); + + if (bufSize > 0) + { + bufSize += 1; + std::vector fullFileNameCStr(bufSize); + char *partFileNameCStr = NULL; + + bufSize = SearchPathA( + (*it).c_str(), + fullFileName.c_str(), + NULL, + bufSize, + &fullFileNameCStr[0], + &partFileNameCStr); + + if (bufSize > 0) + { + fullFileName = std::string(&fullFileNameCStr[0]); + return fullFileName; + } + } + } + + return ""; +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/windbgext.h b/pykd/windbgext.h index cd57ac8..a5f0b1e 100644 --- a/pykd/windbgext.h +++ b/pykd/windbgext.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "kdlib/windbg.h" /////////////////////////////////////////////////////////////////////////////// @@ -10,6 +12,8 @@ public: KDLIB_EXT_COMMAND_METHOD(py); + static bool isInit(); + private: void startConsole(); @@ -18,6 +22,9 @@ private: virtual void tearDown(); + std::string getScriptFileName( const std::string &scriptName ); + + std::vector m_paths; }; ///////////////////////////////////////////////////////////////////////////////