diff --git a/pykd_ext/dbgout.h b/pykd_ext/dbgout.h index 1c6e3dd..d124a4a 100644 --- a/pykd_ext/dbgout.h +++ b/pykd_ext/dbgout.h @@ -57,13 +57,18 @@ public: return false; } + bool isatty() { + return false; + } + public: BEGIN_PYTHON_METHOD_MAP(DbgOut, "dbgout") PYTHON_METHOD1("write", write, "write"); PYTHON_METHOD0("flush", flush, "flush"); - PYTHON_METHOD0("encoding", encoding, "encoding"); - PYTHON_METHOD0("closed", closed, "closed"); + PYTHON_PROPERTY("encoding", encoding, "encoding"); + PYTHON_PROPERTY("closed", closed, "closed"); + PYTHON_METHOD0("isatty", isatty, "isatty"); END_PYTHON_METHOD_MAP private: @@ -104,7 +109,7 @@ public: BEGIN_PYTHON_METHOD_MAP(DbgIn, "dbgin") PYTHON_METHOD0("readline", readline, "readline"); - PYTHON_METHOD0("closed", closed, "closed"); + PYTHON_PROPERTY("closed", closed, "closed"); END_PYTHON_METHOD_MAP private: diff --git a/pykd_ext/dllmain.cpp b/pykd_ext/dllmain.cpp index 6284baf..bc42683 100644 --- a/pykd_ext/dllmain.cpp +++ b/pykd_ext/dllmain.cpp @@ -9,13 +9,13 @@ BOOL APIENTRY DllMain( HMODULE hModule, LPVOID lpReserved ) { - if (!pinHandle) - { - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, - (LPCTSTR)hModule, - &pinHandle); - } + //if (!pinHandle) + //{ + // GetModuleHandleEx( + // GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + // (LPCTSTR)hModule, + // &pinHandle); + //} switch (ul_reason_for_call) { diff --git a/pykd_ext/export.def b/pykd_ext/export.def index e355850..f029bfc 100644 --- a/pykd_ext/export.def +++ b/pykd_ext/export.def @@ -4,3 +4,4 @@ EXPORTS py info pip + help diff --git a/pykd_ext/pyapi.h b/pykd_ext/pyapi.h index d1c9211..9dd2fbd 100644 --- a/pykd_ext/pyapi.h +++ b/pykd_ext/pyapi.h @@ -77,6 +77,7 @@ PyObject* PyBool_FromLong(long v); PyObject* Py_None(); PyObject* PyExc_SystemExit(); PyObject* PyType_Type(); +PyObject* PyProperty_Type(); void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback); void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb); @@ -94,6 +95,8 @@ int __stdcall Py_AddPendingCall(int(*func)(void *), void *arg); PyGILState_STATE __stdcall PyGILState_Ensure(); void __stdcall PyGILState_Release(PyGILState_STATE); +PyObject* __stdcall PyDescr_NewMethod(PyObject* type, struct PyMethodDef *meth); + bool IsPy3(); class PyObjectRef; diff --git a/pykd_ext/pyclass.h b/pykd_ext/pyclass.h index 282c901..85cd875 100644 --- a/pykd_ext/pyclass.h +++ b/pykd_ext/pyclass.h @@ -100,15 +100,12 @@ struct convert_to_python } \ template \ static PyObject* getPythonClass() { \ - PyObject* classNameObj = IsPy3() ? PyUnicode_FromString(className) : PyString_FromString(className); \ - PyObject* classBases = PyTuple_New(0); \ - PyObject* classDictObj = PyDict_New(); \ PyObject* args = PyTuple_New(3); \ - PyTuple_SetItem(args, 0, classNameObj); \ - PyTuple_SetItem(args, 1, classBases); \ - PyTuple_SetItem(args, 2, classDictObj); \ + PyTuple_SetItem(args, 0, IsPy3() ? PyUnicode_FromString(className) : PyString_FromString(className)); \ + PyTuple_SetItem(args, 1, PyTuple_New(0)); \ + PyTuple_SetItem(args, 2, PyDict_New()); \ PyObject* classTypeObj = PyObject_CallObject(PyType_Type(), args); \ - Py_DecRef(args), Py_DecRef(classNameObj), Py_DecRef(classDictObj), Py_DecRef(classBases); \ + Py_DecRef(args); #define END_PYTHON_METHOD_MAP \ return classTypeObj; \ @@ -153,6 +150,32 @@ static PyObject* getPythonClass() { \ Py_DecRef(cFuncObj), Py_DecRef(methodObj); \ } +#define PYTHON_PROPERTY(name, fn, doc) \ + struct Call_##fn{ \ + static PyObject* pycall(PyObject *s, PyObject *args) \ + { \ + PyObject* self = PyTuple_GetItem(args, 0); \ + PyObject* cppobj = PyObject_GetAttrString(self, "cppobject"); \ + T* _this = reinterpret_cast(PyCapsule_GetPointer(cppobj, "cppobject")); \ + Py_DecRef(cppobj); \ + return _this->callMethod0(&fn); \ + } \ + }; \ + {\ + static PyMethodDef methodDef = { name, Call_##fn::pycall, METH_VARARGS }; \ + PyObject* cFuncObj = PyCFunction_NewEx(&methodDef, NULL, NULL); \ + PyObject* methodObj = IsPy3() ? PyInstanceMethod_New(cFuncObj) : PyMethod_New(cFuncObj, NULL, classTypeObj); \ + PyObject* args = PyTuple_New(4); \ + Py_IncRef(PyProperty_Type()); \ + PyTuple_SetItem(args, 0, methodObj); \ + PyTuple_SetItem(args, 1, Py_None()); \ + PyTuple_SetItem(args, 2, Py_None()); \ + PyTuple_SetItem(args, 3, IsPy3() ? PyUnicode_FromString(doc) : PyString_FromString(doc));\ + PyObject* propertyObj = PyObject_CallObject(PyProperty_Type(), args); \ + PyObject_SetAttrString(classTypeObj, name, propertyObj); \ + Py_DecRef(cFuncObj), Py_DecRef(propertyObj), Py_DecRef(args); \ + } + template @@ -167,21 +190,6 @@ PyObject* make_pyobject(const T2& var) { PyObject* cls = T1::getPythonClass(); PyObject* p1 = PyObject_CallObject(cls, NULL); - - PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL; - PyErr_Fetch(&errtype, &errvalue, &traceback); - - char* str; - if (errtype) - Py_DecRef(errtype); - if (errvalue) - { - str = PyString_AsString(errvalue); - Py_DecRef(errvalue); - } - if (traceback) - Py_DecRef(traceback); - Py_DecRef(cls); T1* t1 = new T1(var); diff --git a/pykd_ext/pyinterpret.cpp b/pykd_ext/pyinterpret.cpp index caf2d8b..d987f3d 100644 --- a/pykd_ext/pyinterpret.cpp +++ b/pykd_ext/pyinterpret.cpp @@ -53,6 +53,7 @@ public: bool isPy3; PyObject* PyType_Type; + PyObject* PyProperty_Type; PyObject* Py_None; PyObject* PyExc_SystemExit; @@ -115,6 +116,7 @@ public: int(__stdcall *Py_AddPendingCall)(int(*func)(void *), void *arg); PyGILState_STATE(__stdcall *PyGILState_Ensure)(); void(__stdcall *PyGILState_Release)(PyGILState_STATE state); + PyObject* (__stdcall *PyDescr_NewMethod)(PyObject* type, struct PyMethodDef *meth); HMODULE m_handlePython; PyThreadState* m_globalState; @@ -148,42 +150,26 @@ public: }; - - class PythonSingleton { public: - static PythonInterpreter* getInterpreter(int majorVersion, int minorVersion, bool global) - { - return getSingleton()->_getInterpreter(majorVersion, minorVersion, global); - } - - static void releaseInterpretor(PythonInterpreter* interpret) - { - return getSingleton()->_releaseInterpretor(interpret); - } - - static PythonInterpreter* currentInterpreter() - { - return getSingleton()->m_currentInterpter; - } - -private: - - static std::auto_ptr m_singleton; - - static PythonSingleton* getSingleton() + static PythonSingleton* get() { if (m_singleton.get() == 0) m_singleton.reset(new PythonSingleton()); return m_singleton.get(); } - PythonInterpreter* _getInterpreter(int majorVersion, int minorVersion, bool global) - { + PythonInterpreter* currentInterpreter() + { + return m_currentInterpter; + } + + PythonInterpreter* getInterpreter(int majorVersion, int minorVersion, bool global) + { PyModule* module = 0; if (m_modules.find(std::make_pair(majorVersion, minorVersion)) == m_modules.end()) @@ -219,7 +205,7 @@ private: return m_currentInterpter; } - void _releaseInterpretor(PythonInterpreter* interpret) + void releaseInterpretor(PythonInterpreter* interpret) { PyModule* module = m_currentInterpter->m_module; @@ -236,7 +222,22 @@ private: m_currentInterpter = 0; } -public: + bool isInterpreterLoaded(int majorVersion, int minorVersion) + { + return m_modules.find(std::make_pair(majorVersion, minorVersion)) != m_modules.end(); + } + + void stopAllInterpreter() + { + for (auto m : m_modules) + delete m.second; + + m_modules.clear(); + } + +private: + + static std::auto_ptr m_singleton; std::map, PyModule*> m_modules; @@ -337,6 +338,7 @@ PyModule::PyModule(int majorVesion, int minorVersion) isPy3 = majorVesion == 3; *reinterpret_cast(&PyType_Type) = GetProcAddress(m_handlePython, "PyType_Type"); + *reinterpret_cast(&PyProperty_Type) = GetProcAddress(m_handlePython, "PyProperty_Type"); *reinterpret_cast(&Py_None) = GetProcAddress(m_handlePython, "_Py_NoneStruct"); PyExc_SystemExit = *reinterpret_cast(GetProcAddress(m_handlePython, "PyExc_SystemExit")); @@ -400,6 +402,8 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast(&Py_AddPendingCall) = GetProcAddress(m_handlePython, "Py_AddPendingCall"); *reinterpret_cast(&PyGILState_Ensure) = GetProcAddress(m_handlePython, "PyGILState_Ensure"); *reinterpret_cast(&PyGILState_Release) = GetProcAddress(m_handlePython, "PyGILState_Release"); + *reinterpret_cast(&PyDescr_NewMethod) = GetProcAddress(m_handlePython, "PyDescr_NewMethod"); + Py_Initialize(); PyEval_InitThreads(); @@ -419,274 +423,295 @@ PyModule::~PyModule() PythonInterpreter* activateInterpreter(bool global, int majorVersion, int minorVersion) { - return PythonSingleton::getInterpreter(majorVersion, minorVersion, global); + return PythonSingleton::get()->getInterpreter(majorVersion, minorVersion, global); } void releaseInterpretor(PythonInterpreter* interpret) { - PythonSingleton::releaseInterpretor(interpret); + PythonSingleton::get()->releaseInterpretor(interpret); } +bool isInterpreterLoaded(int majorVersion, int minorVersion) +{ + return PythonSingleton::get()->isInterpreterLoaded(majorVersion, minorVersion); +} + +void stopAllInterpreter() +{ + PythonSingleton::get()->stopAllInterpreter(); +} void __stdcall Py_IncRef(PyObject* object) { - PythonSingleton::currentInterpreter()->m_module->Py_IncRef(object); + PythonSingleton::get()->currentInterpreter()->m_module->Py_IncRef(object); } void __stdcall Py_DecRef(PyObject* object) { - PythonSingleton::currentInterpreter()->m_module->Py_DecRef(object); + PythonSingleton::get()->currentInterpreter()->m_module->Py_DecRef(object); } PyObject* __stdcall PyString_FromString(const char *v) { - return PythonSingleton::currentInterpreter()->m_module->PyString_FromString(v); + return PythonSingleton::get()->currentInterpreter()->m_module->PyString_FromString(v); } PyObject* __stdcall PyDict_New() { - return PythonSingleton::currentInterpreter()->m_module->PyDict_New(); + return PythonSingleton::get()->currentInterpreter()->m_module->PyDict_New(); } PyObject* __stdcall PyDict_GetItemString(PyObject *p, const char *key) { - return PythonSingleton::currentInterpreter()->m_module->PyDict_GetItemString(p, key); + return PythonSingleton::get()->currentInterpreter()->m_module->PyDict_GetItemString(p, key); } int __stdcall PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) { - return PythonSingleton::currentInterpreter()->m_module->PyDict_SetItemString(p, key, val); + return PythonSingleton::get()->currentInterpreter()->m_module->PyDict_SetItemString(p, key, val); } PyObject* __stdcall PyCFunction_NewEx(PyMethodDef* pydef, PyObject *p1, PyObject *p2) { - return PythonSingleton::currentInterpreter()->m_module->PyCFunction_NewEx(pydef, p1, p2); + return PythonSingleton::get()->currentInterpreter()->m_module->PyCFunction_NewEx(pydef, p1, p2); } PyObject* __stdcall PyClass_New(PyObject* className, PyObject* classBases, PyObject* classDict) { - return PythonSingleton::currentInterpreter()->m_module->PyClass_New(className, classBases, classDict); + return PythonSingleton::get()->currentInterpreter()->m_module->PyClass_New(className, classBases, classDict); } PyObject* __stdcall PyMethod_New(PyObject *func, PyObject *self, PyObject *classobj) { - return PythonSingleton::currentInterpreter()->m_module->PyMethod_New(func, self, classobj); + return PythonSingleton::get()->currentInterpreter()->m_module->PyMethod_New(func, self, classobj); } int __stdcall PySys_SetObject(char *name, PyObject *v) { - return PythonSingleton::currentInterpreter()->m_module->PySys_SetObject(name, v); + return PythonSingleton::get()->currentInterpreter()->m_module->PySys_SetObject(name, v); } void __stdcall PySys_SetArgv(int argc, char **argv) { - PythonSingleton::currentInterpreter()->m_module->PySys_SetArgv(argc, argv); + PythonSingleton::get()->currentInterpreter()->m_module->PySys_SetArgv(argc, argv); } void __stdcall PySys_SetArgv_Py3(int argc, wchar_t **argv) { - PythonSingleton::currentInterpreter()->m_module->PySys_SetArgv_Py3(argc, argv); + PythonSingleton::get()->currentInterpreter()->m_module->PySys_SetArgv_Py3(argc, argv); } PyObject* __stdcall PySys_GetObject(char *name) { - return PythonSingleton::currentInterpreter()->m_module->PySys_GetObject(name); + return PythonSingleton::get()->currentInterpreter()->m_module->PySys_GetObject(name); } PyObject* __stdcall PyInstance_New(PyObject *classobj, PyObject *arg, PyObject *kw) { - return PythonSingleton::currentInterpreter()->m_module->PyInstance_New(classobj, arg, kw); + return PythonSingleton::get()->currentInterpreter()->m_module->PyInstance_New(classobj, arg, kw); } int __stdcall PyRun_SimpleString(const char* str) { - return PythonSingleton::currentInterpreter()->m_module->PyRun_SimpleString(str); + return PythonSingleton::get()->currentInterpreter()->m_module->PyRun_SimpleString(str); } PyObject* __stdcall PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals) { - return PythonSingleton::currentInterpreter()->m_module->PyRun_String(str, start, globals, locals); + return PythonSingleton::get()->currentInterpreter()->m_module->PyRun_String(str, start, globals, locals); } PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) { - return PythonSingleton::currentInterpreter()->m_module->PyCapsule_New(pointer, name, destructor); + return PythonSingleton::get()->currentInterpreter()->m_module->PyCapsule_New(pointer, name, destructor); } void* PyCapsule_GetPointer(PyObject *capsule, const char *name) { - return PythonSingleton::currentInterpreter()->m_module->PyCapsule_GetPointer(capsule, name); + return PythonSingleton::get()->currentInterpreter()->m_module->PyCapsule_GetPointer(capsule, name); } int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) { - return PythonSingleton::currentInterpreter()->m_module->PyObject_SetAttrString(o, attr_name, v); + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_SetAttrString(o, attr_name, v); } PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) { - return PythonSingleton::currentInterpreter()->m_module->PyObject_GetAttrString(o, attr_name); + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_GetAttrString(o, attr_name); } PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args) { - return PythonSingleton::currentInterpreter()->m_module->PyObject_CallObject(callable_object, args); + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_CallObject(callable_object, args); } PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw) { - return PythonSingleton::currentInterpreter()->m_module->PyObject_Call(callable_object, args, kw); + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_Call(callable_object, args, kw); } PyObject* __stdcall PyTuple_New(size_t len) { - return PythonSingleton::currentInterpreter()->m_module->PyTuple_New(len); + return PythonSingleton::get()->currentInterpreter()->m_module->PyTuple_New(len); } PyObject* __stdcall PyTuple_GetItem(PyObject *p, size_t pos) { - return PythonSingleton::currentInterpreter()->m_module->PyTuple_GetItem(p, pos); + return PythonSingleton::get()->currentInterpreter()->m_module->PyTuple_GetItem(p, pos); } int __stdcall PyTuple_SetItem(PyObject *p, size_t pos, PyObject *obj) { - return PythonSingleton::currentInterpreter()->m_module->PyTuple_SetItem(p, pos, obj); + return PythonSingleton::get()->currentInterpreter()->m_module->PyTuple_SetItem(p, pos, obj); } size_t __stdcall PyTuple_Size(PyObject *p) { - return PythonSingleton::currentInterpreter()->m_module->PyTuple_Size(p); + return PythonSingleton::get()->currentInterpreter()->m_module->PyTuple_Size(p); } char* PyString_AsString(PyObject *string) { - return PythonSingleton::currentInterpreter()->m_module->PyString_AsString(string); + return PythonSingleton::get()->currentInterpreter()->m_module->PyString_AsString(string); } PyObject* PyUnicode_FromWideChar(const wchar_t *w, size_t size) { - return PythonSingleton::currentInterpreter()->m_module->PyUnicode_FromWideChar(w, size); + return PythonSingleton::get()->currentInterpreter()->m_module->PyUnicode_FromWideChar(w, size); } PyObject* PyImport_Import(PyObject *name) { - return PythonSingleton::currentInterpreter()->m_module->PyImport_Import(name); + return PythonSingleton::get()->currentInterpreter()->m_module->PyImport_Import(name); } PyObject* PyBool_FromLong(long v) { - return PythonSingleton::currentInterpreter()->m_module->PyBool_FromLong(v); + return PythonSingleton::get()->currentInterpreter()->m_module->PyBool_FromLong(v); } PyObject* Py_None() { - return PythonSingleton::currentInterpreter()->m_module->Py_None; + return PythonSingleton::get()->currentInterpreter()->m_module->Py_None; } PyObject* PyExc_SystemExit() { - return PythonSingleton::currentInterpreter()->m_module->PyExc_SystemExit; + return PythonSingleton::get()->currentInterpreter()->m_module->PyExc_SystemExit; } PyObject* PyType_Type() { - return PythonSingleton::currentInterpreter()->m_module->PyType_Type; + return PythonSingleton::get()->currentInterpreter()->m_module->PyType_Type; +} + +PyObject* PyProperty_Type() +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyProperty_Type; } void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) { - PythonSingleton::currentInterpreter()->m_module->PyErr_Fetch(ptype, pvalue, ptraceback); + PythonSingleton::get()->currentInterpreter()->m_module->PyErr_Fetch(ptype, pvalue, ptraceback); } void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) { - PythonSingleton::currentInterpreter()->m_module->PyErr_NormalizeException(exc, val, tb); + PythonSingleton::get()->currentInterpreter()->m_module->PyErr_NormalizeException(exc, val, tb); } void PyErr_SetString(PyObject *type, const char *message) { - PythonSingleton::currentInterpreter()->m_module->PyErr_SetString(type, message); + PythonSingleton::get()->currentInterpreter()->m_module->PyErr_SetString(type, message); } size_t PyList_Size(PyObject* list) { - return PythonSingleton::currentInterpreter()->m_module->PyList_Size(list); + return PythonSingleton::get()->currentInterpreter()->m_module->PyList_Size(list); } PyObject* PyList_GetItem(PyObject *list, size_t index) { - return PythonSingleton::currentInterpreter()->m_module->PyList_GetItem(list, index); + return PythonSingleton::get()->currentInterpreter()->m_module->PyList_GetItem(list, index); } PyObject* PyFile_FromString(char *filename, char *mode) { - return PythonSingleton::currentInterpreter()->m_module->PyFile_FromString(filename, mode); + return PythonSingleton::get()->currentInterpreter()->m_module->PyFile_FromString(filename, mode); } FILE* PyFile_AsFile(PyObject *pyfile) { - return PythonSingleton::currentInterpreter()->m_module->PyFile_AsFile(pyfile); + return PythonSingleton::get()->currentInterpreter()->m_module->PyFile_AsFile(pyfile); } PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals) { - return PythonSingleton::currentInterpreter()->m_module->PyRun_File(fp, filename, start, globals, locals); + return PythonSingleton::get()->currentInterpreter()->m_module->PyRun_File(fp, filename, start, globals, locals); } PyObject* __stdcall PyUnicode_FromString(const char* str) { - return PythonSingleton::currentInterpreter()->m_module->PyUnicode_FromString(str); + return PythonSingleton::get()->currentInterpreter()->m_module->PyUnicode_FromString(str); } PyObject* __stdcall PyInstanceMethod_New(PyObject *func) { - return PythonSingleton::currentInterpreter()->m_module->PyInstanceMethod_New(func); + return PythonSingleton::get()->currentInterpreter()->m_module->PyInstanceMethod_New(func); } size_t __stdcall PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, size_t size) { - return PythonSingleton::currentInterpreter()->m_module->PyUnicode_AsWideChar(unicode, w, size); + return PythonSingleton::get()->currentInterpreter()->m_module->PyUnicode_AsWideChar(unicode, w, size); } PyObject* __stdcall PyImport_ImportModule(const char *name) { - return PythonSingleton::currentInterpreter()->m_module->PyImport_ImportModule(name); + return PythonSingleton::get()->currentInterpreter()->m_module->PyImport_ImportModule(name); } PyThreadState* __stdcall PyEval_SaveThread() { - return PythonSingleton::currentInterpreter()->m_module->PyEval_SaveThread(); + return PythonSingleton::get()->currentInterpreter()->m_module->PyEval_SaveThread(); } void __stdcall PyEval_RestoreThread(PyThreadState *tstate) { - PythonSingleton::currentInterpreter()->m_module->PyEval_RestoreThread(tstate); + PythonSingleton::get()->currentInterpreter()->m_module->PyEval_RestoreThread(tstate); } FILE* _Py_fopen(const char* filename, const char* mode) { - return PythonSingleton::currentInterpreter()->m_module->_Py_fopen(filename, mode); + return PythonSingleton::get()->currentInterpreter()->m_module->_Py_fopen(filename, mode); } int __stdcall Py_AddPendingCall(int(*func)(void *), void *arg) { - return PythonSingleton::currentInterpreter()->m_module->Py_AddPendingCall(func, arg); + return PythonSingleton::get()->currentInterpreter()->m_module->Py_AddPendingCall(func, arg); } PyGILState_STATE __stdcall PyGILState_Ensure() { - return PythonSingleton::currentInterpreter()->m_module->PyGILState_Ensure(); + return PythonSingleton::get()->currentInterpreter()->m_module->PyGILState_Ensure(); } void __stdcall PyGILState_Release(PyGILState_STATE state) { - PythonSingleton::currentInterpreter()->m_module->PyGILState_Release(state); + PythonSingleton::get()->currentInterpreter()->m_module->PyGILState_Release(state); } +PyObject* __stdcall PyDescr_NewMethod(PyObject* type, struct PyMethodDef *meth) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyDescr_NewMethod(type, meth); +} + + + bool IsPy3() { - return PythonSingleton::currentInterpreter()->m_module->isPy3; + return PythonSingleton::get()->currentInterpreter()->m_module->isPy3; } diff --git a/pykd_ext/pyinterpret.h b/pykd_ext/pyinterpret.h index 08f772c..4bff860 100644 --- a/pykd_ext/pyinterpret.h +++ b/pykd_ext/pyinterpret.h @@ -9,8 +9,22 @@ class PythonInterpreter; PythonInterpreter* activateInterpreter(bool global = true, int majorVersion = -1, int minorVersion = -1); + void releaseInterpretor(PythonInterpreter* interpret); +struct InterpreterDesc { + int majorVersion; + int minorVersion; + std::string imagePath; +}; + +std::list getInstalledInterpreter(); + +bool isInterpreterLoaded(int majorVersion, int minorVersion); + +void stopAllInterpreter(); + + class AutoInterpreter { public: @@ -34,13 +48,7 @@ private: }; -struct InterpreterDesc { - int majorVersion; - int minorVersion; - std::string imagePath; -}; - -std::list getInstalledInterpreter(); + diff --git a/pykd_ext/windbgext.cpp b/pykd_ext/windbgext.cpp index f265a80..f87c9c2 100644 --- a/pykd_ext/windbgext.cpp +++ b/pykd_ext/windbgext.cpp @@ -100,6 +100,7 @@ VOID CALLBACK DebugExtensionUninitialize() { + // stopAllInterpreter(); } ////////////////////////////////////////////////////////////////////////////// @@ -107,7 +108,18 @@ DebugExtensionUninitialize() std::string make_version(int major, int minor) { std::stringstream sstr; - sstr << std::dec << major << '.' << minor; + sstr << std::dec << major << '.' << minor; + +#ifdef _WIN64 + + sstr << " x86-64"; + +#else + + sstr << " x86-32"; + +#endif + return sstr.str(); } @@ -123,13 +135,16 @@ info( std::stringstream sstr; sstr << std::endl << "Installed python" << std::endl << std::endl; - sstr << std::setw(12) << std::left << "Version:" << std::left << "Image:" << std::endl; + sstr << std::setw(14) << std::left << "Version:" << std::setw(12) << std::left << "Status: " << std::left << "Image:" << std::endl; sstr << "------------------------------------------------------------------------------" << std::endl; if (interpreterList.size() > 0) { for (const InterpreterDesc& desc : interpreterList) { - sstr << std::setw(12) << std::left << make_version(desc.majorVersion, desc.minorVersion); + sstr << std::setw(14) << std::left << make_version(desc.majorVersion, desc.minorVersion); + + sstr << std::setw(12) << std::left << (isInterpreterLoaded(desc.majorVersion, desc.minorVersion) ? "Loaded" : "Unloaded"); + sstr << desc.imagePath << std::endl; } } @@ -159,8 +174,31 @@ static const char printUsageMsg[] = "\tOptions:\n" "\t-g --global : run code in the common namespace\n" "\t-l --local : run code in the isolate namespace\n" - "!install\n" - "!upgrade\n"; + "!pip\n" + "!info\n"; + +////////////////////////////////////////////////////////////////////////////// + +extern "C" +HRESULT +CALLBACK +help( + PDEBUG_CLIENT client, + PCSTR args + ) +{ + CComQIPtr control = client; + + control->ControlledOutput( + DEBUG_OUTCTL_THIS_CLIENT, + DEBUG_OUTPUT_NORMAL, + printUsageMsg + ); + + return S_OK; +} + +////////////////////////////////////////////////////////////////////////////// extern "C" HRESULT @@ -286,8 +324,56 @@ pip( ) { - return S_OK; + try { + Options opts(getArgsList(args)); + + int majorVersion = opts.pyMajorVersion; + int minorVersion = opts.pyMinorVersion; + + getPythonVersion(majorVersion, minorVersion); + + AutoInterpreter autoInterpreter(opts.global, majorVersion, minorVersion); + + PyObjectRef dbgOut = make_pyobject(client); + PySys_SetObject("stdout", dbgOut); + + PyObjectRef dbgErr = make_pyobject(client); + PySys_SetObject("stderr", dbgErr); + + PyObjectRef dbgIn = make_pyobject(client); + PySys_SetObject("stdin", dbgIn); + + PyObjectRef mainName = IsPy3() ? PyUnicode_FromString("__main__") : PyString_FromString("__main__"); + PyObjectRef mainMod = PyImport_Import(mainName); + PyObjectRef globals = PyObject_GetAttrString(mainMod, "__dict__"); + + + std::stringstream sstr; + sstr << "pip.main(["; + for (auto arg : opts.args) + sstr << '\'' << arg << '\'' << ','; + sstr << "])\n"; + + PyObjectRef result; + result = PyRun_String("import pip\n", Py_file_input, globals, globals); + result = PyRun_String("pip.logger.consumers = []\n", Py_file_input, globals, globals); + result = PyRun_String(sstr.str().c_str(), Py_file_input, globals, globals); + + handleException(); + } + catch (std::exception &e) + { + CComQIPtr control = client; + + control->ControlledOutput( + DEBUG_OUTCTL_THIS_CLIENT, + DEBUG_OUTPUT_ERROR, + e.what() + ); + } + + return S_OK; } @@ -303,7 +389,7 @@ void handleException() PyErr_NormalizeException(&errtype, &errvalue, &traceback); - if (errtype != PyExc_SystemExit() ) + if (errtype && errtype != PyExc_SystemExit()) { PyObjectRef traceback_module = PyImport_ImportModule("traceback"); @@ -329,7 +415,7 @@ void handleException() throw std::exception(sstr.str().c_str()); } - Py_DecRef(errtype); + if (errtype) Py_DecRef(errtype); if (errvalue) Py_DecRef(errvalue); if (traceback) Py_DecRef(traceback); }