From 61bab00356de41fdf9bb676f46ed5c88044aec00 Mon Sep 17 00:00:00 2001 From: "SND\\ussrhero_cp" Date: Tue, 3 Oct 2017 17:41:17 +0000 Subject: [PATCH] [0.3.x] added : targetProcess.getMangedHeap ( Return object representing a managed heap ) [0.3.x] added : targetProcess.getManagedVar (Return object representing a managed object in the target managed process) git-svn-id: https://pykd.svn.codeplex.com/svn@91257 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/pydbgeng.h | 4 +-- pykd/pykdver.h | 4 +-- pykd/pymod.cpp | 27 ++++++++++++++---- pykd/pyprocess.h | 67 +++++++++++++++++++++++++++++++++++++++++++++ pykd/pytypedvar.cpp | 2 +- 5 files changed, 94 insertions(+), 10 deletions(-) diff --git a/pykd/pydbgeng.h b/pykd/pydbgeng.h index c86c710..f94a06f 100644 --- a/pykd/pydbgeng.h +++ b/pykd/pydbgeng.h @@ -19,10 +19,10 @@ kdlib::PROCESS_DEBUG_ID startProcess(const std::wstring &processName, const kdl } inline -kdlib::PROCESS_DEBUG_ID attachProcess(kdlib::PROCESS_ID pid, const kdlib::ProcessDebugFlags& flags = kdlib::ProcessDebugDefault) +kdlib::PROCESS_DEBUG_ID attachProcess(kdlib::PROCESS_ID pid) { AutoRestorePyState pystate; - return kdlib::attachProcess(pid, flags); + return kdlib::attachProcess(pid); } inline diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 29494af..03dbab3 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -1,8 +1,8 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 -#define PYKD_VERSION_SUBVERSION 2 -#define PYKD_VERSION_BUILDNO 8 +#define PYKD_VERSION_SUBVERSION 3 +#define PYKD_VERSION_BUILDNO 0 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index aa903a9..4898929 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -1,4 +1,3 @@ - #include "stdafx.h" #include @@ -36,7 +35,6 @@ static const std::string pykdVersion = PYKD_VERSION_BUILD_STR BOOST_PYTHON_FUNCTION_OVERLOADS( startProcess_, pykd::startProcess, 1, 2 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( attachProcess_, pykd::attachProcess, 1, 2); BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_, pykd::detachProcess, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_, pykd::terminateProcess, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS(closeDump_, pykd::closeDump, 0, 1); @@ -94,6 +92,8 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( defineFunction_, pykd::defineFunction, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBreakpoint_, Breakpoint::setSoftwareBreakpoint, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBreakpoint_, Breakpoint::setHardwareBreakpoint, 3, 4 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( TargetHeap_getEntries, TargetHeapAdapter::getEntries, 1, 4); + BOOST_PYTHON_FUNCTION_OVERLOADS( Module_enumSymbols, ModuleAdapter::enumSymbols, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( Module_findSymbol, ModuleAdapter::findSymbol, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( Module_enumTypes, ModuleAdapter::enumTypes, 1, 2 ); @@ -156,8 +156,8 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "startProcess", pykd::startProcess, startProcess_( boost::python::args( "commandline", "debugOptions"), "Start process for debugging" ) ); - python::def("attachProcess", pykd::attachProcess, attachProcess_(boost::python::args("pid", "debugOptions"), - "Attach debugger to a exsisting process") ); + python::def("attachProcess", pykd::attachProcess, + "Attach debugger to a exsisting process"); python::def( "detachProcess", pykd::detachProcess, detachProcess_( boost::python::args( "id" ), "Stop process debugging") ); python::def( "detachAllProcesses", pykd::detachAllProcesses, @@ -706,6 +706,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return the process executable file name") .def("isCurrent", TargetProcessAdapter::isCurrent, "Check if the target is current") + .def("isManaged", TargetProcessAdapter::isManaged, + "Check if the taget process is managed") .def("getNumberThreads", TargetProcessAdapter::getNumberThreads, "Return number of threads for this process" ) .def("getThread", TargetProcessAdapter::getThreadByIndex, @@ -736,10 +738,14 @@ BOOST_PYTHON_MODULE( pykd ) "Return list of breakpoints for the target process") .def("modules", TargetProcessAdapter::getModulesList, "Return list of modules for the target process") + .def("getManagedHeap", TargetProcessAdapter::getManagedHeap, + "Return object representing a managed heap") + .def("getManagedVar", TargetProcessAdapter::getManagedVar, + "Return object representing a managed object in the target managed process") .def("__str__", TargetProcessAdapter::print) ; - python::class_("targetThread", "Class representing process in the target system", python::no_init ) + python::class_("targetThread", "Class representing thread in the target process", python::no_init ) .def("__init__", python::make_constructor(&TargetThreadAdapter::getThread)) .def("__init__", python::make_constructor(&TargetThreadAdapter::getCurrent)) .def("getNumber", TargetThreadAdapter::getNumberThreads, @@ -775,6 +781,17 @@ BOOST_PYTHON_MODULE( pykd ) .def("__str__", TargetThreadAdapter::print) ; + python::class_("targetHeapIterator", "iterator for typedVar array", python::no_init) + .def("__iter__", &TargetHeapIterator::self) + .def("__len__", &TargetHeapIterator::length) + .def("next", &TargetHeapIterator::next) + ; + + python::class_("targetHeap", "Class representing heap in the target process", python::no_init ) + .def("entries", &TargetHeapAdapter::getEntries, TargetHeap_getEntries(python::args("typeName", "minSize", "maxSize"), + "Return heap's entries iterator object")[python::return_value_policy()] ) + ; + python::class_, boost::noncopyable>("module", "Class representing executable module", python::no_init) .def("__init__", python::make_constructor(&ModuleAdapter::loadModuleByName)) .def("__init__", python::make_constructor(&ModuleAdapter::loadModuleByOffset)) diff --git a/pykd/pyprocess.h b/pykd/pyprocess.h index 1ed4fab..47fc376 100644 --- a/pykd/pyprocess.h +++ b/pykd/pyprocess.h @@ -4,6 +4,7 @@ #include "pythreadstate.h" #include "pyeventhandler.h" +#include "dbgexcept.h" namespace pykd { @@ -245,6 +246,24 @@ struct TargetProcessAdapter { return process.getModuleByName(name); } + static bool isManaged(kdlib::TargetProcess& process) + { + AutoRestorePyState pystate; + return process.isManaged(); + } + + static kdlib::TargetHeapPtr getManagedHeap(kdlib::TargetProcess& process) + { + AutoRestorePyState pystate; + return process.getManagedHeap(); + } + + static kdlib::TypedVarPtr getManagedVar(kdlib::TargetProcess& process, kdlib::MEMOFFSET_64 address) + { + AutoRestorePyState pystate; + return process.getManagedVar(address); + } + static python::list getThreadList(kdlib::TargetProcess& process); static python::list getBreakpointsList(kdlib::TargetProcess& process); @@ -334,5 +353,53 @@ struct TargetThreadAdapter { static std::wstring print(kdlib::TargetThread& thread); }; + +class TargetHeapIterator +{ +public: + + explicit TargetHeapIterator(kdlib::TargetHeapEnumPtr& heapEnum) : + m_heapEnum(heapEnum) + {} + + static python::object self(const python::object& obj) + { + return obj; + } + + python::tuple next() + { + AutoRestorePyState pystate; + + kdlib::MEMOFFSET_64 addr; + std::wstring name; + size_t size; + + if (!m_heapEnum->next(addr, name, size)) + throw StopIteration("No more data."); + + return python::make_tuple(addr, name, size); + } + + size_t length() + { + AutoRestorePyState pystate; + return m_heapEnum->getCount(); + } + +private: + + kdlib::TargetHeapEnumPtr m_heapEnum; +}; + +struct TargetHeapAdapter { + + static TargetHeapIterator* getEntries(kdlib::TargetHeap& heap, const std::wstring& typeName=L"", size_t minSize=0, size_t maxSize=-1) + { + return new TargetHeapIterator(heap.getEnum(typeName, minSize, maxSize)); + } + +}; + } // pykd namespace diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp index 936bcaa..0bfba2b 100644 --- a/pykd/pytypedvar.cpp +++ b/pykd/pytypedvar.cpp @@ -258,5 +258,5 @@ void TypedVarAdapter::setFieldAttr(kdlib::TypedVar& typedVar, const std::wstring /////////////////////////////////////////////////////////////////////////////// -} // namesapce pykd +} // namespace pykd