From 4eb0d49c23c2d2f4a80743a5680af522dd17e4be Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 17 Dec 2013 07:49:24 +0000 Subject: [PATCH] [0.3.x] reworked : added GIL release/acquire for any call to kdlibcpp git-svn-id: https://pykd.svn.codeplex.com/svn@86869 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/cpucontext.cpp | 58 --- pykd/cpucontext.h | 69 --- pykd/dbgengine.cpp | 206 -------- pykd/dbgengine.h | 40 -- pykd/memaccess.cpp | 45 -- pykd/memaccess.h | 99 ---- pykd/module.h | 106 ---- pykd/pycpucontext.cpp | 78 +++ pykd/pycpucontext.h | 159 ++++++ pykd/pydbgeng.cpp | 99 ++++ pykd/pydbgeng.h | 338 +++++++++++++ pykd/pydbgio.h | 2 +- pykd/pydisasm.h | 95 ++++ pykd/{eventhandler.cpp => pyeventhandler.cpp} | 10 +- pykd/{eventhandler.h => pyeventhandler.h} | 30 ++ pykd/pykd.vcxproj | 29 +- pykd/pykd.vcxproj.filters | 71 +-- pykd/pymemaccess.cpp | 236 +++++++++ pykd/pymemaccess.h | 241 +++++++++ pykd/pymod.cpp | 463 +++++++++--------- pykd/pymodule.cpp | 129 +++++ pykd/pymodule.h | 145 ++++++ pykd/pysymengine.h | 17 + pykd/{pystate.h => pythreadstate.h} | 0 pykd/pytypedvar.cpp | 97 ++++ pykd/pytypedvar.h | 117 +++++ pykd/pytypeinfo.cpp | 75 +++ pykd/pytypeinfo.h | 228 +++++++++ pykd/typedvar.h | 95 ---- pykd/typeinfo.h | 99 ---- snippets/stkdelta.py | 18 +- test/scripts/customtypestest.py | 17 + 32 files changed, 2416 insertions(+), 1095 deletions(-) delete mode 100644 pykd/cpucontext.cpp delete mode 100644 pykd/cpucontext.h delete mode 100644 pykd/dbgengine.cpp delete mode 100644 pykd/dbgengine.h delete mode 100644 pykd/memaccess.cpp delete mode 100644 pykd/memaccess.h delete mode 100644 pykd/module.h create mode 100644 pykd/pycpucontext.cpp create mode 100644 pykd/pycpucontext.h create mode 100644 pykd/pydbgeng.cpp create mode 100644 pykd/pydbgeng.h create mode 100644 pykd/pydisasm.h rename pykd/{eventhandler.cpp => pyeventhandler.cpp} (92%) rename pykd/{eventhandler.h => pyeventhandler.h} (61%) create mode 100644 pykd/pymemaccess.cpp create mode 100644 pykd/pymemaccess.h create mode 100644 pykd/pymodule.cpp create mode 100644 pykd/pymodule.h create mode 100644 pykd/pysymengine.h rename pykd/{pystate.h => pythreadstate.h} (100%) create mode 100644 pykd/pytypedvar.cpp create mode 100644 pykd/pytypedvar.h create mode 100644 pykd/pytypeinfo.cpp create mode 100644 pykd/pytypeinfo.h delete mode 100644 pykd/typedvar.h delete mode 100644 pykd/typeinfo.h diff --git a/pykd/cpucontext.cpp b/pykd/cpucontext.cpp deleted file mode 100644 index 6185c35..0000000 --- a/pykd/cpucontext.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -#include "stdafx.h" - -#include "cpucontext.h" -#include "variant.h" - -namespace pykd { - -/////////////////////////////////////////////////////////////////////////////// - -python::object CPUContextAdaptor::getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name ) -{ - kdlib::NumVariant var = cpu->getRegisterByName(name); - return NumVariantAdaptor::convertToPython( var ); -} - -/////////////////////////////////////////////////////////////////////////////// - -python::object CPUContextAdaptor::getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long index ) -{ - kdlib::NumVariant var = cpu->getRegisterByIndex(index); - std::wstring name = cpu->getRegisterName(index); - - return python::make_tuple( name, NumVariantAdaptor::convertToPython( var ) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -python::list CPUContextAdaptor::getStack( kdlib::CPUContextPtr& cpu ) -{ - kdlib::StackPtr stack = kdlib::getStack(cpu); - - unsigned long numberFrames = stack->getFrameCount(); - python::list lst; - - for ( unsigned long i = 0; i < numberFrames; ++i ) - lst.append( stack->getFrame(i) ); - - return lst; -} - -/////////////////////////////////////////////////////////////////////////////// - -std::wstring printStackFrame( kdlib::StackFramePtr& frame ) -{ - std::wstringstream sstr; - sstr << L"Frame: "; - sstr << L"IP=" << std::hex << frame->getIP() << L" "; - sstr << L"Return=" << std::hex << frame->getRET() << L" "; - sstr << L"Frame Offset=" << std::hex << frame->getFP() << L" "; - sstr << L"Stack Offset=" << std::hex << frame->getSP(); - - return sstr.str(); -} - -/////////////////////////////////////////////////////////////////////////////// - -} // end namespace pykd diff --git a/pykd/cpucontext.h b/pykd/cpucontext.h deleted file mode 100644 index 8bf54e9..0000000 --- a/pykd/cpucontext.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include -namespace python = boost::python; - -#include "kdlib/dbgengine.h" -#include "kdlib/cpucontext.h" -#include "kdlib/stack.h" - -namespace pykd { - -/////////////////////////////////////////////////////////////////////////////// - -class CPUContextAdaptor -{ -public: - static python::object getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name ); - static python::object getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long index ); - static python::list getStack( kdlib::CPUContextPtr& cpu ); -}; - -//struct StackFrame { -// kdlib::MEMOFFSET_64 ip, ret, fp, sp; -//}; - -std::wstring printStackFrame( kdlib::StackFramePtr& frame ); - -inline python::object getRegisterByName( const std::wstring &name ) -{ - return CPUContextAdaptor::getRegisterByName( kdlib::loadCPUCurrentContext(), name ); -} - -inline unsigned long long loadMSR( unsigned long msrIndex ) -{ - return kdlib::loadCPUCurrentContext()->loadMSR( msrIndex ); -} - -inline void setMSR( unsigned long msrIndex, unsigned long long value ) -{ - return kdlib::loadCPUCurrentContext()->setMSR( msrIndex, value ); -} - -inline kdlib::CPUType getProcessorMode() { - return kdlib::loadCPUCurrentContext()->getCPUMode(); -} - -inline kdlib::CPUType getProcessorType() { - return kdlib::loadCPUCurrentContext()->getCPUType(); -} - -inline void setProcessorMode( kdlib::CPUType mode ) { - kdlib::loadCPUCurrentContext()->setCPUMode(mode); -} - -inline void switchProcessorMode() { - kdlib::loadCPUCurrentContext()->switchCPUMode(); -} - -inline python::list getCurrentStack() { - return CPUContextAdaptor::getStack( kdlib::loadCPUCurrentContext() ); -} - -inline kdlib::StackFramePtr getCurrentFrame() { - return kdlib::getStack()->getFrame(0); -} - -/////////////////////////////////////////////////////////////////////////////// - -} //end namespace pykd diff --git a/pykd/dbgengine.cpp b/pykd/dbgengine.cpp deleted file mode 100644 index 9a6c073..0000000 --- a/pykd/dbgengine.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "stdafx.h" - -#include "kdlib/dbgengine.h" -#include "kdlib/typeinfo.h" - -#include "dbgengine.h" -#include "variant.h" -#include "pystate.h" - -namespace pykd { - - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::ExecutionStatus targetGo() -{ - kdlib::ExecutionStatus status; - - AutoRestorePyState pystate; - - status = kdlib::targetGo(); - - return status; -} - -/////////////////////////////////////////////////////////////////////////////// - -void targetBreak() -{ - AutoRestorePyState pystate; - - kdlib::targetBreak(); -} - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::ExecutionStatus targetStep() -{ - kdlib::ExecutionStatus status; - - AutoRestorePyState pystate; - - status = kdlib::targetStep(); - - return status; -} - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::ExecutionStatus targetStepIn() -{ - kdlib::ExecutionStatus status; - - AutoRestorePyState pystate; - - status = kdlib::targetStepIn(); - - return status; -} - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::PROCESS_DEBUG_ID startProcess( const std::wstring &processName, bool debugChildren ) -{ - kdlib::PROCESS_DEBUG_ID id; - - AutoRestorePyState pystate; - - id = kdlib::startProcess(processName, debugChildren); - - return id; -} - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::PROCESS_DEBUG_ID attachProcess( kdlib::PROCESS_ID pid ) -{ - kdlib::PROCESS_DEBUG_ID id; - - AutoRestorePyState pystate; - - id = kdlib::attachProcess(pid); - - return id; -} - -/////////////////////////////////////////////////////////////////////////////// - -void loadDump( const std::wstring &fileName ) -{ - AutoRestorePyState pystate; - - kdlib::loadDump(fileName); -} - -/////////////////////////////////////////////////////////////////////////////// - -void attachKernel( const std::wstring &connectOptions ) -{ - AutoRestorePyState pystate; - - kdlib::attachKernel(connectOptions); -} - -/////////////////////////////////////////////////////////////////////////////// - -std::wstring debugCommand( const std::wstring &command ) -{ - AutoRestorePyState pystate; - - std::wstring outstr = kdlib::debugCommand(command); - - return outstr; -} - -/////////////////////////////////////////////////////////////////////////////// - -python::object evaluate( const std::wstring &expression, bool cplusplus ) -{ - AutoRestorePyState pystate; - - kdlib::NumVariant var = kdlib::evaluate(expression, cplusplus ); - - return pykd::NumVariantAdaptor::convertToPython( var ); -} - -/////////////////////////////////////////////////////////////////////////////// - -python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset ) -{ - std::wstring fileName; - unsigned long lineno; - long displacement; - - kdlib::getSourceLine( fileName, lineno, displacement, offset ); - - return python::make_tuple( fileName, lineno, displacement ); -} - -/////////////////////////////////////////////////////////////////////////////// - -python::tuple findSymbolAndDisp( ULONG64 offset ) -{ - kdlib::MEMDISPLACEMENT displacement = 0; - std::wstring symbolName = kdlib::findSymbol( offset, displacement ); - std::wstring moduleName = kdlib::getModuleName( kdlib::findModuleBase( offset ) ); - return python::make_tuple(moduleName,symbolName,displacement); -} - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::SystemInfo getSystemVersion() -{ - kdlib::SystemInfo sysInfo; - kdlib::getSystemInfo( sysInfo ); - return sysInfo; -} - -/////////////////////////////////////////////////////////////////////////////// - -std::wstring printSystemVersion( kdlib::SystemInfo& sysInfo ) -{ - std::wstringstream sstr; - - sstr << L"Major Version: " << sysInfo.majorVersion << std::endl; - sstr << L"Minor Version: " << sysInfo.minorVersion << std::endl;; - sstr << L"Description: " << sysInfo.buildDescription << std::endl; - - return sstr.str(); -} - -/////////////////////////////////////////////////////////////////////////////// - -python::list getExceptionInfoParameters( kdlib::ExceptionInfo& exceptionInfo ) -{ - python::list lst; - for ( unsigned long i = 0; i < exceptionInfo.parameterCount; ++i ) - lst.append( exceptionInfo.parameters[i] ); - return lst; -} - -/////////////////////////////////////////////////////////////////////////////// - -std::wstring printExceptionInfo( kdlib::ExceptionInfo& exceptionInfo ) -{ - std::wstringstream sstream; - - sstream << L"FirstChance= " << (exceptionInfo.firstChance ? "True" : "False") << std::endl; - - sstream << L"ExceptionCode= 0x" << std::hex << exceptionInfo.exceptionCode << std::endl; - sstream << L"ExceptionFlags= 0x" << std::hex << exceptionInfo.exceptionFlags << std::endl; - sstream << L"ExceptionRecord= 0x" << std::hex << exceptionInfo.exceptionRecord << std::endl; - sstream << L"ExceptionAddress= 0x" << std::hex << exceptionInfo.exceptionAddress << std::endl; - - for (ULONG i = 0; i < exceptionInfo.parameterCount; ++i) - { - sstream << L"Param[" << std::dec << i << L"]= 0x"; - sstream << std::hex << exceptionInfo.parameters[i] << std::endl; - } - - return sstream.str(); -} - -/////////////////////////////////////////////////////////////////////////////// - -} //end namespace pykd diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h deleted file mode 100644 index e4d29a0..0000000 --- a/pykd/dbgengine.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -namespace python = boost::python; - -#include "kdlib/dbgengine.h" - -namespace pykd { - -/////////////////////////////////////////////////////////////////////////////// - -kdlib::ExecutionStatus targetGo(); -void targetBreak(); -kdlib::ExecutionStatus targetStep(); -kdlib::ExecutionStatus targetStepIn(); - -kdlib::PROCESS_DEBUG_ID startProcess( const std::wstring &processName, bool debugChildren = false ); -kdlib::PROCESS_DEBUG_ID attachProcess( kdlib::PROCESS_ID pid ); -void loadDump( const std::wstring &fileName ); - -void attachKernel( const std::wstring &connectOptions = L"" ); - -std::wstring debugCommand( const std::wstring &command ); -python::object evaluate( const std::wstring &expression, bool cplusplus = false ); - -python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 ); - -python::tuple findSymbolAndDisp( ULONG64 offset ); - -kdlib::SystemInfo getSystemVersion(); - -std::wstring printSystemVersion( kdlib::SystemInfo& sysInfo ); - -python::list getExceptionInfoParameters( kdlib::ExceptionInfo& exceptionInfo ); - -std::wstring printExceptionInfo( kdlib::ExceptionInfo& exceptionInfo ); - -/////////////////////////////////////////////////////////////////////////////// - -} //end namespace pykd \ No newline at end of file diff --git a/pykd/memaccess.cpp b/pykd/memaccess.cpp deleted file mode 100644 index 02f3753..0000000 --- a/pykd/memaccess.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "stdafx.h" - -#include "kdlib\exceptions.h" - -#include "memaccess.h" - -namespace pykd { - -/////////////////////////////////////////////////////////////////////////////// - -std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset) -{ - unsigned short length = kdlib::ptrWord( offset ); - unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); - kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); - - if ( maximumLength < length ) - throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); - - if ( length == 0 ) - return std::wstring(); - - return kdlib::loadWChars( buffer, length/2 ); -} - -/////////////////////////////////////////////////////////////////////////////// - -std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset) -{ - unsigned short length = kdlib::ptrWord( offset ); - unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); - kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); - - if ( maximumLength < length ) - throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); - - if ( length == 0 ) - return std::string(); - - return kdlib::loadChars( buffer, length ); -} - -/////////////////////////////////////////////////////////////////////////////// - -}; // end pykd namespace diff --git a/pykd/memaccess.h b/pykd/memaccess.h deleted file mode 100644 index e6a4ea0..0000000 --- a/pykd/memaccess.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include -namespace python = boost::python; - -#include "kdlib/memaccess.h" - -#include "stladaptor.h" - -namespace pykd { - -inline int ptrSignByte( kdlib::MEMOFFSET_64 offset ) -{ - return kdlib::ptrSignByte(offset); -} - -inline python::list loadBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadBytes( offset, count, phyAddr ) ); -} - -inline python::list loadWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadWords( offset, count, phyAddr ) ); -} - -inline python::list loadDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadDWords( offset, count, phyAddr ) ); -} - -inline python::list loadQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadQWords( offset, count, phyAddr ) ); -} - -inline python::list loadSignBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadSignBytes( offset, count, phyAddr ) ); -} - -inline python::list loadSignWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadSignWords( offset, count, phyAddr ) ); -} - -inline python::list loadSignDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadSignDWords( offset, count, phyAddr ) ); -} - -inline python::list loadSignQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadSignQWords( offset, count, phyAddr ) ); -} - -inline python::list loadFloats( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadFloats( offset, count, phyAddr ) ); -} - -inline python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) -{ - return vectorToList( kdlib::loadDoubles( offset, count, phyAddr ) ); -} - -inline kdlib::MEMOFFSET_64 ptrPtr( kdlib::MEMOFFSET_64 offset ) -{ - return kdlib::ptrPtr( offset ); -} - -inline python::list loadPtrList( kdlib::MEMOFFSET_64 offset ) -{ - return vectorToList( kdlib::loadPtrList(offset) ); -} - -inline python::list loadPtrArray( kdlib::MEMOFFSET_64 offset, unsigned long count ) -{ - return vectorToList( kdlib::loadPtrs(offset, count) ); -} - -std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset); - -std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset); - -inline kdlib::MEMOFFSET_64 searchMemoryLst( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const python::list &pattern ) -{ - return kdlib::searchMemory( beginOffset, length, listToVector(pattern) ); -} - -inline kdlib::MEMOFFSET_64 searchMemoryStr( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const std::string &pattern ) -{ - const char* p = pattern.c_str(); - return kdlib::searchMemory( beginOffset, length, std::vector( p, p + pattern.length() ) ); -} - - -} // end namespace pykd - diff --git a/pykd/module.h b/pykd/module.h deleted file mode 100644 index 82f221d..0000000 --- a/pykd/module.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -#include - -#include "kdlib/module.h" - -#include "stladaptor.h" - -namespace pykd { - - -struct ModuleAdapter : public kdlib::Module -{ - - static kdlib::ModulePtr loadModuleByName( const std::wstring &name ) - { - return kdlib::loadModule( name ); - } - - static kdlib::ModulePtr loadModuleByOffset( kdlib::MEMOFFSET_64 offset ) - { - return kdlib::loadModule( offset); - } - - static std::wstring print( kdlib::Module& module ) - { - std::wstringstream sstr; - - //prepareSymbolFile(); - - sstr << L"Module: " << module.getName() << std::endl; - sstr << L"Start: " << std::hex << module.getBase() << L" End: " << module.getEnd() << L" Size: " << module.getSize() << std::endl; - //sstr << (m_unloaded ? ", UNLOADED!" : "") << std::endl; - sstr << L"Image: " << module.getImageName() << std::endl; - sstr << L"Symbols: " << module.getSymFile() << std::endl; - - - //if ( m_symSession ) - //{ - // sstr << "Symbols: " << m_symSession->getSymbolFileName() << std::endl; - // std::string buildDesc = m_symSession->getBuildDescription(); - // if (!buildDesc.empty()) - // sstr << "\t" << buildDesc << std::endl; - //} - //else - //{ - // sstr << "Symbols: not found" << std::endl; - //} - - sstr << L"Timestamp: " << module.getTimeDataStamp() << std::endl; - sstr << L"Check Sum: " << module.getCheckSum() << std::endl; - - return sstr.str(); - } - - static python::list enumSymbols( kdlib::Module& module, const std::wstring &mask = L"*" ) - { - kdlib::SymbolOffsetList offsetLst = module.enumSymbols( mask ); - python::list pyLst; - for ( kdlib::SymbolOffsetList::const_iterator it = offsetLst.begin(); it != offsetLst.end(); ++it ) - pyLst.append( python::make_tuple( it->first, it->second ) ); - return pyLst; - } - - static std::wstring findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement = true ) - { - kdlib::MEMDISPLACEMENT displacement = 0; - std::wstring symbolName = module.findSymbol( offset, displacement ); - if ( !showDisplacement || displacement == 0 ) - return symbolName; - - std::wstringstream wsstr; - - wsstr << symbolName; - - if ( displacement > 0 ) - wsstr << L'+' << std::hex << displacement; - else - wsstr << L'-' << std::hex << -displacement; - - return wsstr.str(); - } - - static python::tuple findSymbolAndDisp( kdlib::Module& module, kdlib::MEMOFFSET_64 offset ) - { - kdlib::MEMDISPLACEMENT displacement = 0; - std::wstring symbolName = module.findSymbol( offset, displacement ); - return python::make_tuple( symbolName, displacement ); - } - - - static python::list getTypedVarListByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) - { - kdlib::TypedVarList lst = module.loadTypedVarList( offset, typeName, fieldName ); - return vectorToList( lst ); - } - - static python::list getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) - { - kdlib::TypedVarList lst = module.loadTypedVarArray( offset, typeName, number ); - return vectorToList( lst ); - } - -}; - -} // end namespace pykd diff --git a/pykd/pycpucontext.cpp b/pykd/pycpucontext.cpp new file mode 100644 index 0000000..e1256f3 --- /dev/null +++ b/pykd/pycpucontext.cpp @@ -0,0 +1,78 @@ + +#include "stdafx.h" + +#include "pycpucontext.h" +#include "variant.h" + + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +python::object CPUContextAdapter::getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name ) +{ + kdlib::NumVariant var; + + do { + AutoRestorePyState pystate; + var = cpu->getRegisterByName(name); + } while(false); + + return NumVariantAdaptor::convertToPython( var ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::object CPUContextAdapter::getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long index ) +{ + kdlib::NumVariant var; + std::wstring name; + + do { + AutoRestorePyState pystate; + var = cpu->getRegisterByIndex(index); + name = cpu->getRegisterName(index); + }while(false); + + return python::make_tuple( name, NumVariantAdaptor::convertToPython( var ) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list CPUContextAdapter::getStack( kdlib::CPUContextPtr& cpu ) +{ + kdlib::StackPtr stack; + unsigned long numberFrames; + + do { + AutoRestorePyState pystate; + stack = kdlib::getStack(cpu); + numberFrames = stack->getFrameCount(); + } while(false); + + python::list lst; + for ( unsigned long i = 0; i < numberFrames; ++i ) + lst.append( stack->getFrame(i) ); + + return lst; +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring StackFrameAdapter::print( kdlib::StackFrame& frame ) +{ + AutoRestorePyState pystate; + + std::wstringstream sstr; + sstr << L"Frame: "; + sstr << L"IP=" << std::hex << frame.getIP() << L" "; + sstr << L"Return=" << std::hex << frame.getRET() << L" "; + sstr << L"Frame Offset=" << std::hex << frame.getFP() << L" "; + sstr << L"Stack Offset=" << std::hex << frame.getSP(); + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////// + +} // end namespace pykd diff --git a/pykd/pycpucontext.h b/pykd/pycpucontext.h new file mode 100644 index 0000000..ca16084 --- /dev/null +++ b/pykd/pycpucontext.h @@ -0,0 +1,159 @@ +#pragma once + +#include +namespace python = boost::python; + +#include "kdlib/dbgengine.h" +#include "kdlib/cpucontext.h" +#include "kdlib/stack.h" + +#include "pythreadstate.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +class StackFrameAdapter { + +public: + + static kdlib::MEMOFFSET_64 getIP( kdlib::StackFrame& frame ) + { + AutoRestorePyState pystate; + return frame.getIP(); + } + + static kdlib::MEMOFFSET_64 getRET( kdlib::StackFrame& frame ) + { + AutoRestorePyState pystate; + return frame.getRET(); + } + + static kdlib::MEMOFFSET_64 getFP( kdlib::StackFrame& frame ) + { + AutoRestorePyState pystate; + return frame.getFP(); + } + + static kdlib::MEMOFFSET_64 getSP( kdlib::StackFrame& frame ) + { + AutoRestorePyState pystate; + return frame.getSP(); + } + + static std::wstring print( kdlib::StackFrame& frame ); +}; + +/////////////////////////////////////////////////////////////////////////////// + + +inline kdlib::CPUContextPtr loadCPUCurrentContext() { + AutoRestorePyState pystate; + return kdlib::loadCPUCurrentContext(); +} + +inline kdlib::CPUContextPtr loadCPUContextByIndex( unsigned long index ) { + AutoRestorePyState pystate; + return kdlib::loadCPUContextByIndex(index); +} + +inline unsigned long long loadMSR( unsigned long msrIndex ) +{ + AutoRestorePyState pystate; + return kdlib::loadCPUCurrentContext()->loadMSR( msrIndex ); +} + +inline void setMSR( unsigned long msrIndex, unsigned long long value ) +{ + AutoRestorePyState pystate; + return kdlib::loadCPUCurrentContext()->setMSR( msrIndex, value ); +} + +inline kdlib::CPUType getProcessorMode() { + AutoRestorePyState pystate; + return kdlib::loadCPUCurrentContext()->getCPUMode(); +} + +inline kdlib::CPUType getProcessorType() { + AutoRestorePyState pystate; + return kdlib::loadCPUCurrentContext()->getCPUType(); +} + +inline void setProcessorMode( kdlib::CPUType mode ) { + AutoRestorePyState pystate; + kdlib::loadCPUCurrentContext()->setCPUMode(mode); +} + +inline void switchProcessorMode() { + AutoRestorePyState pystate; + kdlib::loadCPUCurrentContext()->switchCPUMode(); +} + +inline kdlib::StackFramePtr getCurrentFrame() { + AutoRestorePyState pystate; + return kdlib::getStack()->getFrame(0); +} + + +class CPUContextAdapter +{ +public: + static python::object getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name ); + static python::object getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long index ); + static python::list getStack( kdlib::CPUContextPtr& cpu ); + + static kdlib::MEMOFFSET_64 getIP( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + return cpu->getIP(); + } + + static kdlib::MEMOFFSET_64 getSP( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + return cpu->getSP(); + } + + static kdlib::MEMOFFSET_64 getFP( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + return cpu->getFP(); + } + + static kdlib::CPUType getCPUType( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + return cpu->getCPUType(); + } + + static kdlib::CPUType getCPUMode( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + return cpu->getCPUMode(); + } + + static void setCPUMode( kdlib::CPUContextPtr& cpu, kdlib::CPUType mode ) + { + AutoRestorePyState pystate; + cpu->setCPUMode(mode); + } + + static void switchCPUMode( kdlib::CPUContextPtr& cpu ) + { + AutoRestorePyState pystate; + cpu->switchCPUMode(); + } +}; + +inline python::object getRegisterByName( const std::wstring &name ) +{ + return CPUContextAdapter::getRegisterByName( kdlib::loadCPUCurrentContext(), name ); +} + +inline python::list getCurrentStack() { + return CPUContextAdapter::getStack( kdlib::loadCPUCurrentContext() ); +} + +/////////////////////////////////////////////////////////////////////////////// + +} //end namespace pykd diff --git a/pykd/pydbgeng.cpp b/pykd/pydbgeng.cpp new file mode 100644 index 0000000..6eafc0f --- /dev/null +++ b/pykd/pydbgeng.cpp @@ -0,0 +1,99 @@ +#include "stdafx.h" + +#include "kdlib/dbgengine.h" +#include "kdlib/typeinfo.h" + +#include "pydbgeng.h" +#include "variant.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +python::object evaluate( const std::wstring &expression, bool cplusplus ) +{ + kdlib::NumVariant var; + + do { + AutoRestorePyState pystate; + var = kdlib::evaluate(expression, cplusplus ); + } while(false); + + return pykd::NumVariantAdaptor::convertToPython( var ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset ) +{ + std::wstring fileName; + unsigned long lineno; + long displacement; + + do { + AutoRestorePyState pystate; + kdlib::getSourceLine( fileName, lineno, displacement, offset ); + } while(false); + + return python::make_tuple( fileName, lineno, displacement ); +} + +/////////////////////////////////////////////////////////////////////////////// + +kdlib::SystemInfo getSystemVersion() +{ + AutoRestorePyState pystate; + + kdlib::SystemInfo sysInfo; + kdlib::getSystemInfo( sysInfo ); + return sysInfo; +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring printSystemVersion( kdlib::SystemInfo& sysInfo ) +{ + std::wstringstream sstr; + + sstr << L"Major Version: " << sysInfo.majorVersion << std::endl; + sstr << L"Minor Version: " << sysInfo.minorVersion << std::endl;; + sstr << L"Description: " << sysInfo.buildDescription << std::endl; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list getExceptionInfoParameters( kdlib::ExceptionInfo& exceptionInfo ) +{ + python::list lst; + for ( unsigned long i = 0; i < exceptionInfo.parameterCount; ++i ) + lst.append( exceptionInfo.parameters[i] ); + return lst; +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring printExceptionInfo( kdlib::ExceptionInfo& exceptionInfo ) +{ + std::wstringstream sstream; + + sstream << L"FirstChance= " << (exceptionInfo.firstChance ? "True" : "False") << std::endl; + + sstream << L"ExceptionCode= 0x" << std::hex << exceptionInfo.exceptionCode << std::endl; + sstream << L"ExceptionFlags= 0x" << std::hex << exceptionInfo.exceptionFlags << std::endl; + sstream << L"ExceptionRecord= 0x" << std::hex << exceptionInfo.exceptionRecord << std::endl; + sstream << L"ExceptionAddress= 0x" << std::hex << exceptionInfo.exceptionAddress << std::endl; + + for (ULONG i = 0; i < exceptionInfo.parameterCount; ++i) + { + sstream << L"Param[" << std::dec << i << L"]= 0x"; + sstream << std::hex << exceptionInfo.parameters[i] << std::endl; + } + + return sstream.str(); +} + +/////////////////////////////////////////////////////////////////////////////// + +} //end namespace pykd diff --git a/pykd/pydbgeng.h b/pykd/pydbgeng.h new file mode 100644 index 0000000..cf007d0 --- /dev/null +++ b/pykd/pydbgeng.h @@ -0,0 +1,338 @@ +#pragma once + +#include +namespace python = boost::python; + +#include "kdlib/dbgengine.h" + +#include "pythreadstate.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +inline +kdlib::PROCESS_DEBUG_ID startProcess( const std::wstring &processName, bool debugChildren = false ) +{ + AutoRestorePyState pystate; + return kdlib::startProcess(processName, debugChildren); +} + +inline +kdlib::PROCESS_DEBUG_ID attachProcess( kdlib::PROCESS_ID pid ) +{ + AutoRestorePyState pystate; + return kdlib::attachProcess(pid); +} + +inline +void detachProcess( kdlib::PROCESS_DEBUG_ID processId = -1 ) +{ + AutoRestorePyState pystate; + kdlib::detachProcess(processId); +} + +inline +void detachAllProcesses() +{ + AutoRestorePyState pystate; + kdlib::detachAllProcesses(); +} + +inline +void terminateProcess( kdlib::PROCESS_DEBUG_ID processId = -1) +{ + AutoRestorePyState pystate; + kdlib::terminateProcess(processId); +} + +inline +void terminateAllProcesses() +{ + AutoRestorePyState pystate; + kdlib::terminateAllProcesses(); +} + +inline +void loadDump( const std::wstring &fileName ) +{ + AutoRestorePyState pystate; + kdlib::loadDump(fileName); +} + +inline +void writeDump( const std::wstring &fileName, bool smallDump ) +{ + AutoRestorePyState pystate; + kdlib::writeDump(fileName, smallDump); +} + +inline +void attachKernel( const std::wstring &connectOptions = L"" ) +{ + AutoRestorePyState pystate; + kdlib::attachKernel(connectOptions); +} + +inline +bool isLocalKernelDebuggerEnabled() +{ + AutoRestorePyState pystate; + return kdlib::isLocalKernelDebuggerEnabled(); +} + +inline +bool isDumpAnalyzing() +{ + AutoRestorePyState pystate; + return kdlib::isDumpAnalyzing(); +} + +inline +bool isKernelDebugging() +{ + AutoRestorePyState pystate; + return kdlib::isKernelDebugging(); +} + +inline +std::wstring debugCommand( const std::wstring &command ) +{ + AutoRestorePyState pystate; + return kdlib::debugCommand(command); +} + +/////////////////////////////////////////////////////////////////////////////// + +// processes end threads +inline unsigned long getNumberThreads() +{ + AutoRestorePyState pystate; + return kdlib::getNumberThreads(); +} + +inline kdlib::THREAD_DEBUG_ID getCurrentThreadId() +{ + AutoRestorePyState pystate; + return kdlib::getCurrentThreadId(); +} + +inline kdlib::THREAD_DEBUG_ID getThreadIdByOffset(kdlib::MEMOFFSET_64 offset) +{ + AutoRestorePyState pystate; + return kdlib::getThreadIdByOffset(offset); +} + +inline kdlib::THREAD_DEBUG_ID getThreadIdBySystemId(kdlib::THREAD_ID tid) +{ + AutoRestorePyState pystate; + return kdlib::getThreadIdBySystemId(tid); +} + +inline kdlib::THREAD_ID getThreadSystemId(kdlib::THREAD_DEBUG_ID id = -1) +{ + AutoRestorePyState pystate; + return kdlib::getThreadSystemId(id); +} + +inline kdlib::MEMOFFSET_64 getThreadOffset(kdlib::THREAD_DEBUG_ID id = -1) +{ + AutoRestorePyState pystate; + return kdlib::getThreadOffset(id); +} + +inline void setCurrentThread(kdlib::THREAD_DEBUG_ID id) +{ + AutoRestorePyState pystate; + kdlib::setCurrentThread(id); +} + +inline void setImplicitThread(kdlib::MEMOFFSET_64 offset) +{ + AutoRestorePyState pystate; + kdlib::setImplicitThread(offset); +} + +inline kdlib::MEMOFFSET_64 getImplicitThreadOffset() +{ + AutoRestorePyState pystate; + return kdlib::getImplicitThreadOffset(); +} + +inline unsigned long getNumberProcesses() +{ + AutoRestorePyState pystate; + return kdlib::getNumberProcesses(); +} + +inline kdlib::PROCESS_DEBUG_ID getCurrentProcessId() +{ + AutoRestorePyState pystate; + return kdlib::getCurrentProcessId(); +} + +inline kdlib::PROCESS_DEBUG_ID getProcessIdByOffset( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::getProcessIdByOffset(offset); +} + +inline kdlib::PROCESS_DEBUG_ID getProcessIdBySystemId( kdlib::PROCESS_ID pid ) +{ + AutoRestorePyState pystate; + return kdlib::getProcessIdBySystemId(pid); +} + +inline kdlib::PROCESS_ID getProcessSystemId( kdlib::PROCESS_DEBUG_ID id = -1) +{ + AutoRestorePyState pystate; + return kdlib::getProcessSystemId(id); +} + +inline kdlib::MEMOFFSET_64 getProcessOffset( kdlib::PROCESS_DEBUG_ID id = -1) +{ + AutoRestorePyState pystate; + return kdlib::getProcessOffset(id); +} + +inline void setCurrentProcess(kdlib::PROCESS_DEBUG_ID id) +{ + AutoRestorePyState pystate; + kdlib::setCurrentProcess(id); +} + +inline void setImplicitProcess(kdlib::MEMOFFSET_64 offset) +{ + AutoRestorePyState pystate; + kdlib::setImplicitProcess(offset); +} + +inline kdlib::MEMOFFSET_64 getImplicitProcessOffset() +{ + AutoRestorePyState pystate; + return kdlib::getImplicitProcessOffset(); +} + +/////////////////////////////////////////////////////////////////////////////// + +inline +void targetBreak() +{ + AutoRestorePyState pystate; + kdlib::targetBreak(); +} + +inline +kdlib::ExecutionStatus targetGo() +{ + AutoRestorePyState pystate; + return kdlib::targetGo(); +} + +inline +kdlib::ExecutionStatus targetStep() +{ + AutoRestorePyState pystate; + return kdlib::targetStep(); +} + +inline +kdlib::ExecutionStatus targetStepIn() +{ + AutoRestorePyState pystate; + return kdlib::targetStepIn(); +} + +inline +kdlib::ExecutionStatus targetExecutionStatus() +{ + AutoRestorePyState pystate; + return kdlib::targetExecutionStatus(); +} + +/////////////////////////////////////////////////////////////////////////////// +// system properties + +inline +size_t ptrSize() +{ + AutoRestorePyState pystate; + return kdlib::ptrSize(); +} + +inline +bool is64bitSystem() +{ + AutoRestorePyState pystate; + return kdlib::is64bitSystem(); +} + +inline +size_t getPageSize() +{ + AutoRestorePyState pystate; + return kdlib::getPageSize(); +} + +inline +unsigned long getSystemUptime() +{ + AutoRestorePyState pystate; + return kdlib::getSystemUptime(); +} + +inline +unsigned long getCurrentTime() +{ + AutoRestorePyState pystate; + return kdlib::getCurrentTime(); +} + +/////////////////////////////////////////////////////////////////////////////// + +inline +kdlib::EXTENSION_ID loadExtension(const std::wstring &extPath ) +{ + AutoRestorePyState pystate; + return kdlib::loadExtension(extPath); +} + +inline +void removeExtension( kdlib::EXTENSION_ID extId ) +{ + AutoRestorePyState pystate; + kdlib::removeExtension(extId); +} + +inline +std::wstring callExtension( kdlib::EXTENSION_ID extId, const std::wstring command, const std::wstring ¶ms ) +{ + AutoRestorePyState pystate; + return kdlib::callExtension(extId, command, params); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring debugCommand( const std::wstring &command ); + +python::object evaluate( const std::wstring &expression, bool cplusplus = false ); + +python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 ); + +inline std::wstring getSourceFile(kdlib::MEMOFFSET_64 offset = 0) +{ + AutoRestorePyState pystate; + return kdlib::getSourceFile(offset); +} + +kdlib::SystemInfo getSystemVersion(); + +std::wstring printSystemVersion( kdlib::SystemInfo& sysInfo ); + +python::list getExceptionInfoParameters( kdlib::ExceptionInfo& exceptionInfo ); + +std::wstring printExceptionInfo( kdlib::ExceptionInfo& exceptionInfo ); + +/////////////////////////////////////////////////////////////////////////////// + +} //end namespace pykd \ No newline at end of file diff --git a/pykd/pydbgio.h b/pykd/pydbgio.h index 0d7abaf..4d33379 100644 --- a/pykd/pydbgio.h +++ b/pykd/pydbgio.h @@ -2,7 +2,7 @@ #include "kdlib/windbg.h" -#include "pystate.h" +#include "pythreadstate.h" namespace pykd { diff --git a/pykd/pydisasm.h b/pykd/pydisasm.h new file mode 100644 index 0000000..c91f9e9 --- /dev/null +++ b/pykd/pydisasm.h @@ -0,0 +1,95 @@ +#pragma once + +#include "kdlib/disasm.h" + +#include "pythreadstate.h" + +namespace pykd { + +inline kdlib::Disasm* loadDisasm() +{ + AutoRestorePyState pystate; + return new kdlib::Disasm(); +} + + +inline kdlib::Disasm* loadDisasmWithOffset(kdlib::MEMOFFSET_64 offset) +{ + AutoRestorePyState pystate; + return new kdlib::Disasm(offset); +} + +class DisasmAdapter { + +public: + + static std::wstring disassemble(kdlib::Disasm& disasm) + { + AutoRestorePyState pystate; + return disasm.disassemble(); + } + + static std::wstring jump(kdlib::Disasm& disasm, kdlib::MEMOFFSET_64 offset) + { + AutoRestorePyState pystate; + return disasm.jump(offset); + } + + static std::wstring jumprel( kdlib::Disasm& disasm, kdlib::MEMDISPLACEMENT delta) + { + AutoRestorePyState pystate; + return disasm.jumprel(delta); + } + + static kdlib::MEMOFFSET_64 getNearInstruction( kdlib::Disasm& disasm, kdlib::MEMDISPLACEMENT delta ) + { + AutoRestorePyState pystate; + return disasm.getNearInstruction(delta); + } + + static std::wstring reset( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.reset(); + } + + static std::wstring assembly( kdlib::Disasm& disasm, const std::wstring &instr ) + { + AutoRestorePyState pystate; + return disasm.assembly(instr); + } + + static std::wstring instruction( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.instruction(); + } + + static kdlib::MEMOFFSET_64 begin( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.begin(); + } + + static kdlib::MEMOFFSET_64 current( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.current(); + } + + static size_t length( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.length(); + } + + static kdlib::MEMOFFSET_64 ea( kdlib::Disasm& disasm ) + { + AutoRestorePyState pystate; + return disasm.ea(); + } +}; + + +} // namespace pykd + diff --git a/pykd/eventhandler.cpp b/pykd/pyeventhandler.cpp similarity index 92% rename from pykd/eventhandler.cpp rename to pykd/pyeventhandler.cpp index 123b8d2..781fbb1 100644 --- a/pykd/eventhandler.cpp +++ b/pykd/pyeventhandler.cpp @@ -2,7 +2,7 @@ #include "kdlib\eventhandler.h" -#include "eventhandler.h" +#include "pyeventhandler.h" #include "dbgexcept.h" namespace pykd { @@ -14,11 +14,11 @@ class SoftwareBreakpoint : public Breakpoint public: SoftwareBreakpoint( kdlib::MEMOFFSET_64 offset ) { - m_id = kdlib::softwareBreakPointSet( offset ); + m_id = pykd::softwareBreakPointSet( offset ); } ~SoftwareBreakpoint() { - kdlib::breakPointRemove( m_id ); + pykd::breakPointRemove( m_id ); } private: @@ -37,13 +37,13 @@ public: { m_pystate = PyThreadState_Get(); m_callback = callback; - m_id = kdlib::softwareBreakPointSet( offset ); + m_id = pykd::softwareBreakPointSet( offset ); } ~SoftwareBreakpointWithCallback() { try { - kdlib::breakPointRemove( m_id ); + pykd::breakPointRemove( m_id ); } catch( kdlib::DbgException& ) { } } diff --git a/pykd/eventhandler.h b/pykd/pyeventhandler.h similarity index 61% rename from pykd/eventhandler.h rename to pykd/pyeventhandler.h index 54a8e1e..a34a37c 100644 --- a/pykd/eventhandler.h +++ b/pykd/pyeventhandler.h @@ -8,12 +8,42 @@ #include "boost/python/object.hpp" #include "boost/python/wrapper.hpp" +#include "pythreadstate.h" + namespace python = boost::python; namespace pykd { /////////////////////////////////////////////////////////////////////////////// +inline kdlib::BREAKPOINT_ID softwareBreakPointSet( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::softwareBreakPointSet(offset); +} + +inline kdlib::BREAKPOINT_ID hardwareBreakPointSet( kdlib::MEMOFFSET_64 offset, size_t size = 0, kdlib::ACCESS_TYPE accessType = 0 ) +{ + AutoRestorePyState pystate; + return kdlib::hardwareBreakPointSet(offset, size, accessType); +} + + +inline void breakPointRemove( kdlib::BREAKPOINT_ID id ) +{ + AutoRestorePyState pystate; + kdlib::breakPointRemove(id); +} + +inline void breakPointRemoveAll() +{ + AutoRestorePyState pystate; + kdlib::breakPointRemoveAll(); +} + + +/////////////////////////////////////////////////////////////////////////////// + class Breakpoint; typedef boost::shared_ptr BreakpointPtr; diff --git a/pykd/pykd.vcxproj b/pykd/pykd.vcxproj index 18b6a4d..9d8a7aa 100644 --- a/pykd/pykd.vcxproj +++ b/pykd/pykd.vcxproj @@ -233,27 +233,27 @@ - - - - - + + + + - + + + + + + - - - - false @@ -275,9 +275,14 @@ - - + + + + + + + Create Create diff --git a/pykd/pykd.vcxproj.filters b/pykd/pykd.vcxproj.filters index 888901c..8bb920b 100644 --- a/pykd/pykd.vcxproj.filters +++ b/pykd/pykd.vcxproj.filters @@ -27,45 +27,51 @@ Header Files - - Header Files - Header Files Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - Header Files - - Header Files - Header Files Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -83,16 +89,25 @@ Source Files - + Source Files - + Source Files - + Source Files - + + Source Files + + + Source Files + + + Source Files + + Source Files diff --git a/pykd/pymemaccess.cpp b/pykd/pymemaccess.cpp new file mode 100644 index 0000000..d61cf97 --- /dev/null +++ b/pykd/pymemaccess.cpp @@ -0,0 +1,236 @@ +#include "stdafx.h" + +#include "kdlib\exceptions.h" + +#include "pymemaccess.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +kdlib::MEMOFFSET_64 searchMemoryLst( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const python::list &pattern ) +{ + std::vector p = listToVector(pattern); + do { + AutoRestorePyState pystate; + return kdlib::searchMemory( beginOffset, length, p ); + } while(false); +} + +/////////////////////////////////////////////////////////////////////////////// + +kdlib::MEMOFFSET_64 searchMemoryStr( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const std::string &pattern ) +{ + std::vector p( pattern.begin(), pattern.end() ); + do { + AutoRestorePyState pystate; + return kdlib::searchMemory( beginOffset, length, p ); + } while(false); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadBytes(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadDWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadQWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadSignBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadSignBytes(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadSignWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadSignWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadSignDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadSignDWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadSignQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadSignQWords(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadFloats( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadFloats(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadDoubles(offset, count, phyAddr); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadPtrList( kdlib::MEMOFFSET_64 offset ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadPtrList(offset); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list loadPtrArray( kdlib::MEMOFFSET_64 offset, unsigned long count ) +{ + std::vector lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadPtrs(offset, count); + } while(false); + + return vectorToList(lst); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset) +{ + unsigned short length = kdlib::ptrWord( offset ); + unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); + kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); + + if ( maximumLength < length ) + throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); + + if ( length == 0 ) + return std::wstring(); + + return kdlib::loadWChars( buffer, length/2 ); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset) +{ + unsigned short length = kdlib::ptrWord( offset ); + unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); + kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); + + if ( maximumLength < length ) + throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); + + if ( length == 0 ) + return std::string(); + + return kdlib::loadChars( buffer, length ); +} + +/////////////////////////////////////////////////////////////////////////////// + + +}; // end pykd namespace diff --git a/pykd/pymemaccess.h b/pykd/pymemaccess.h new file mode 100644 index 0000000..494c8f3 --- /dev/null +++ b/pykd/pymemaccess.h @@ -0,0 +1,241 @@ +#pragma once + +#include +namespace python = boost::python; + +#include "kdlib/memaccess.h" + +#include "stladaptor.h" +#include "pythreadstate.h" + +namespace pykd { + +inline unsigned char ptrByte( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrByte(offset); +} + +inline unsigned short ptrWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrWord(offset); +} + +inline unsigned long ptrDWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrDWord(offset); +} + +inline unsigned long long ptrQWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrQWord(offset); +} + +inline unsigned long long ptrMWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrMWord(offset); +} + +inline int ptrSignByte( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSignByte(offset); +} + +inline short ptrSignWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSignWord(offset); +} + +inline long ptrSignDWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSignDWord(offset); +} + +inline long long ptrSignQWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSignQWord(offset); +} + +inline long long ptrSignMWord( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSignMWord(offset); +} + +inline float ptrSingleFloat( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrSingleFloat(offset); +} + +inline double ptrDoubleFloat( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrDoubleFloat(offset); +} + +python::list loadBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadSignBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadSignWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadSignDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadSignQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadFloats( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); +python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ); + + +inline std::string loadChars( kdlib::MEMOFFSET_64 offset, unsigned long number, bool phyAddr = false ) +{ + AutoRestorePyState pystate; + return kdlib::loadChars(offset,number, phyAddr); +} + +inline std::wstring loadWChars( kdlib::MEMOFFSET_64 offset, unsigned long number, bool phyAddr = false ) +{ + AutoRestorePyState pystate; + return kdlib::loadWChars(offset,number,phyAddr); +} + +inline std::string loadCStr( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::loadCStr(offset); +} + +inline std::wstring loadWStr( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::loadWStr(offset); +} + +std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset); +std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset); + +inline kdlib::MEMOFFSET_64 ptrPtr( kdlib::MEMOFFSET_64 offset ) +{ + AutoRestorePyState pystate; + return kdlib::ptrPtr(offset); +} + +python::list loadPtrList( kdlib::MEMOFFSET_64 offset ); +python::list loadPtrArray( kdlib::MEMOFFSET_64 offset, unsigned long count ); + +kdlib::MEMOFFSET_64 searchMemoryLst( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const python::list &pattern ); +kdlib::MEMOFFSET_64 searchMemoryStr( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const std::string &pattern ); + +inline bool compareMemory( kdlib::MEMOFFSET_64 addr1, kdlib::MEMOFFSET_64 addr2, size_t length, bool phyAddr = false ) +{ + AutoRestorePyState pystate; + return kdlib::compareMemory(addr1, addr2, length, phyAddr); +} + + + + +//inline int ptrSignByte( kdlib::MEMOFFSET_64 offset ) +//{ +// AutoRestorePyState pystate; +// return kdlib::ptrSignByte(offset); +//} +// +//inline python::list loadBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// +// do +// AutoRestorePyState pystate; +// kdlib::loadBytes( offset, count, phyAddr ) +// return vectorToList( ); +//} +// +//inline python::list loadWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadDWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// AutoRestorePyState pystate; +// return vectorToList( kdlib::loadQWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadSignBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// AutoRestorePyState pystate; +// return vectorToList( kdlib::loadSignBytes( offset, count, phyAddr ) ); +//} +// +//inline python::list loadSignWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadSignWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadSignDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadSignDWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadSignQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadSignQWords( offset, count, phyAddr ) ); +//} +// +//inline python::list loadFloats( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadFloats( offset, count, phyAddr ) ); +//} +// +//inline python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +//{ +// return vectorToList( kdlib::loadDoubles( offset, count, phyAddr ) ); +//} +// +// +// +//inline kdlib::MEMOFFSET_64 ptrPtr( kdlib::MEMOFFSET_64 offset ) +//{ +// return kdlib::ptrPtr( offset ); +//} +// +//inline python::list loadPtrList( kdlib::MEMOFFSET_64 offset ) +//{ +// return vectorToList( kdlib::loadPtrList(offset) ); +//} +// +//inline python::list loadPtrArray( kdlib::MEMOFFSET_64 offset, unsigned long count ) +//{ +// return vectorToList( kdlib::loadPtrs(offset, count) ); +//} +// +//std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset); +// +//std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset); +// +//inline kdlib::MEMOFFSET_64 searchMemoryLst( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const python::list &pattern ) +//{ +// return kdlib::searchMemory( beginOffset, length, listToVector(pattern) ); +//} +// +//inline kdlib::MEMOFFSET_64 searchMemoryStr( kdlib::MEMOFFSET_64 beginOffset, unsigned long length, const std::string &pattern ) +//{ +// const char* p = pattern.c_str(); +// return kdlib::searchMemory( beginOffset, length, std::vector( p, p + pattern.length() ) ); +//} + + +} // end namespace pykd + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index a71b0cb..bc077a6 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -6,17 +6,21 @@ #include "kdlib/kdlib.h" #include "pykdver.h" + #include "variant.h" -#include "module.h" -#include "dbgengine.h" #include "dbgexcept.h" -#include "memaccess.h" -#include "typeinfo.h" -#include "typedvar.h" #include "windbgext.h" -#include "eventhandler.h" -#include "cpucontext.h" + +#include "pydbgeng.h" #include "pydbgio.h" +#include "pydisasm.h" +#include "pyeventhandler.h" +#include "pymemaccess.h" +#include "pymodule.h" +#include "pysymengine.h" +#include "pytypedvar.h" +#include "pytypeinfo.h" +#include "pycpucontext.h" using namespace pykd; @@ -31,34 +35,34 @@ static const std::string pykdVersion = PYKD_VERSION_BUILD_STR /////////////////////////////////////////////////////////////////////////////// -BOOST_PYTHON_FUNCTION_OVERLOADS( startProcess_, startProcess, 1, 2 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_, kdlib::detachProcess, 0, 1 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_, kdlib::terminateProcess, 0, 1 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( attachKernel_, attachKernel, 0, 1 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( evaluate_, evaluate, 1, 2 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( startProcess_, pykd::startProcess, 1, 2 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_, pykd::detachProcess, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_, pykd::terminateProcess, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( attachKernel_, pykd::attachKernel, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( evaluate_, pykd::evaluate, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, kdlib::dprint, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, kdlib::dprintln, 1, 2 ); //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadChars_, kdlib::loadChars, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadWChars_, kdlib::loadWChars, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadBytes_, loadBytes, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadWords_, loadWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadDWords_, loadDWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadQWords_, loadQWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes_, loadSignBytes, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadFloats_, loadFloats, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( loadDoubles_, loadDoubles, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, kdlib::compareMemory, 3, 4 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadChars_, pykd::loadChars, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadWChars_, pykd::loadWChars, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadBytes_, pykd::loadBytes, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadWords_, pykd::loadWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadDWords_, pykd::loadDWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadQWords_, pykd::loadQWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes_, pykd::loadSignBytes, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, pykd::loadSignWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, pykd::loadSignDWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, pykd::loadSignQWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadFloats_, pykd::loadFloats, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadDoubles_, pykd::loadDoubles, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, pykd::compareMemory, 3, 4 ); - -BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, getSourceLine, 0, 1 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, kdlib::getSourceFile, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, pykd::getSourceFile, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, pykd::getSourceLine, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, pykd::findSymbol, 1, 2 ); //BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 ); // @@ -67,7 +71,6 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( createStruct_, kdlib::defineStruct, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( Module_enumSymbols, ModuleAdapter::enumSymbols, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( Module_findSymbol, ModuleAdapter::findSymbol, 2, 3 ); -BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfoAdapter::findSymbol, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 ); @@ -77,6 +80,7 @@ pykd::SysDbgOut sysPykdOut; pykd::SysDbgOut sysPykdErr; pykd::SysDbgIn sysPykdIn; + BOOST_PYTHON_MODULE( pykd ) { // èñïîëüçîâàòü âìåñòî êîíñîëè ïîòîêè èç sys @@ -92,59 +96,58 @@ BOOST_PYTHON_MODULE( pykd ) "Deintialize debug engine, only for console mode" ); // DbgEng services - python::def( "setSymSrvDir", &kdlib::setSymSrvDir, + python::def( "setSymSrvDir", pykd::setSymSrvDir, "Set directory of SYMSRV.dll library.\nUsually this is a directory of WinDbg"); - python::def( "loadExt", &kdlib::loadExtension, + python::def( "loadExt", pykd::loadExtension, "Load a WinDBG extension. Return handle of the loaded extension" ); - python::def( "removeExt", &kdlib::removeExtension, + python::def( "removeExt", pykd::removeExtension, "Unload a WinDBG extension. Parameters: handle returned by loadExt" ); - python::def( "callExt", &kdlib::callExtension, + python::def( "callExt", pykd::callExtension, "Call a WinDBG extension's routine. Parameters: handle returned by loadExt; string command line" ); - // Manage debug target - python::def( "startProcess", &startProcess, startProcess_( boost::python::args( "commandline", "debugChildren" ), + python::def( "startProcess", pykd::startProcess, startProcess_( boost::python::args( "commandline", "debugChildren" ), "Start process for debugging" ) ); - python::def( "attachProcess", &attachProcess, + python::def( "attachProcess", pykd::attachProcess, "Attach debugger to a exsisting process" ); - python::def( "detachProcess", &kdlib::detachProcess, detachProcess_( boost::python::args( "pid" ), + python::def( "detachProcess", pykd::detachProcess, detachProcess_( boost::python::args( "pid" ), "Stop process debugging") ); - python::def( "detachAllProcesses", &kdlib::detachAllProcesses, + python::def( "detachAllProcesses", pykd::detachAllProcesses, "Detach from all process and resume all their threads" ); - python::def( "killProcess", &kdlib::terminateProcess, terminateProcess_( boost::python::args( "pid" ), + python::def( "killProcess", pykd::terminateProcess, terminateProcess_( boost::python::args( "pid" ), "Stop debugging and terminate current process" ) ); - python::def( "killAllProcesses", &kdlib::terminateAllProcesses, + python::def( "killAllProcesses", pykd::terminateAllProcesses, "Detach from all process then terminate them"); - python::def( "loadDump", &loadDump, + python::def( "loadDump", pykd::loadDump, "Load crash dump"); - python::def( "isLocalKernelDebuggerEnabled", &kdlib::isLocalKernelDebuggerEnabled, + python::def( "isLocalKernelDebuggerEnabled", pykd::isLocalKernelDebuggerEnabled, "Check whether kernel debugging is enabled for the local kernel"); - python::def( "attachKernel", &attachKernel, attachKernel_( boost::python::args( "connectOptions" ), + python::def( "attachKernel", pykd::attachKernel, attachKernel_( boost::python::args( "connectOptions" ), "Connect the debugger engine to a kernel target.\n" "If connectOptions is not specified - attach to the local kernel") ); - python::def( "isDumpAnalyzing", &kdlib::isDumpAnalyzing, + python::def( "isDumpAnalyzing", pykd::isDumpAnalyzing, "Check if it is a dump analyzing ( not living debuggee )" ); - python::def( "isKernelDebugging", &kdlib::isKernelDebugging, + python::def( "isKernelDebugging", pykd::isKernelDebugging, "Check if kernel dubugging is running" ); - python::def( "isWindbgExt", &PykdExt::isInit, + python::def( "isWindbgExt", PykdExt::isInit, "Check if script works in windbg context" ); - python::def( "writeDump", &kdlib::writeDump, + python::def( "writeDump", pykd::writeDump, "Create memory dump file" ); - python::def( "breakin", &targetBreak, + python::def( "breakin", pykd::targetBreak, "Break into debugger" ); - python::def( "expr", &evaluate, evaluate_( boost::python::args( "expression", "cplusplus" ), + python::def( "expr", pykd::evaluate, evaluate_( boost::python::args( "expression", "cplusplus" ), "Evaluate windbg expression" ) ); - python::def( "dbgCommand", &debugCommand, + python::def( "dbgCommand", pykd::debugCommand, "Run a debugger's command and return it's result as a string" ); - python::def( "go", &targetGo, + python::def( "go", pykd::targetGo, "Go debugging" ); - python::def( "step", &targetStep, + python::def( "step", pykd::targetStep, "The target is executing a single instruction or--if that instruction is a subroutine call--subroutine" ); - python::def( "trace", &targetStepIn, + python::def( "trace", pykd::targetStepIn, "The target is executing a single instruction" ); - python::def( "getExecutionStatus", &kdlib::targetExecutionStatus, + python::def( "getExecutionStatus", pykd::targetExecutionStatus, "Return current execution status" ); // Debug output @@ -164,17 +167,17 @@ BOOST_PYTHON_MODULE( pykd ) .add_property( "encoding", &DbgIn::encoding ); // system properties - python::def( "ptrSize", &kdlib::ptrSize, + python::def( "ptrSize", pykd::ptrSize, "Return effective pointer size" ); - python::def( "is64bitSystem", &kdlib::is64bitSystem, + python::def( "is64bitSystem", pykd::is64bitSystem, "Check if target system has 64 address space" ); - python::def( "pageSize", &kdlib::getPageSize, + python::def( "pageSize", pykd::getPageSize, "Get the page size for the currently executing processor context" ); - python::def( "systemUptime", &kdlib::getSystemUptime, + python::def( "systemUptime", pykd::getSystemUptime, "Return the number of seconds the computer has been running" ); - python::def( "currentTime", &kdlib::getCurrentTime, + python::def( "currentTime", pykd::getCurrentTime, "Return the number of seconds since the beginning of 1970" ); - python::def("getSystemVersion", &getSystemVersion, + python::def("getSystemVersion", pykd::getSystemVersion, "Return systemVersion"); // Manage target memory access @@ -193,125 +196,125 @@ BOOST_PYTHON_MODULE( pykd ) //python::def( "getVaProtect", &kdlib::getVaProtect, // "Return memory attributes" ); - python::def( "ptrByte", &kdlib::ptrByte, + python::def( "ptrByte", pykd::ptrByte, "Read an unsigned 1-byte integer from the target memory" ); - python::def( "ptrWord", &kdlib::ptrWord, + python::def( "ptrWord", pykd::ptrWord, "Read an unsigned 2-byte integer from the target memory" ); - python::def( "ptrDWord", &kdlib::ptrDWord, + python::def( "ptrDWord", pykd::ptrDWord, "Read an unsigned 4-byte integer from the target memory" ); - python::def( "ptrQWord", &kdlib::ptrQWord, + python::def( "ptrQWord", pykd::ptrQWord, "Read an unsigned 8-byte integer from the target memory" ); - python::def( "ptrMWord", &kdlib::ptrMWord, + python::def( "ptrMWord", pykd::ptrMWord, "Read an unsigned mashine's word wide integer from the target memory" ); - python::def( "ptrSignByte", &ptrSignByte, + python::def( "ptrSignByte", pykd::ptrSignByte, "Read an signed 1-byte integer from the target memory" ); - python::def( "ptrSignWord", &kdlib::ptrSignWord, + python::def( "ptrSignWord", pykd::ptrSignWord, "Read an signed 2-byte integer from the target memory" ); - python::def( "ptrSignDWord", &kdlib::ptrSignDWord, + python::def( "ptrSignDWord", pykd::ptrSignDWord, "Read an signed 4-byte integer from the target memory" ); - python::def( "ptrSignQWord", &kdlib::ptrSignQWord, + python::def( "ptrSignQWord", pykd::ptrSignQWord, "Read an signed 8-byte integer from the target memory" ); - python::def( "ptrSignMWord", &kdlib::ptrSignMWord, + python::def( "ptrSignMWord", pykd::ptrSignMWord, "Read an signed mashine's word wide integer from the target memory" ); - python::def( "ptrFloat", &kdlib::ptrSingleFloat, + python::def( "ptrFloat", pykd::ptrSingleFloat, "Read a float with single precision from the target memory" ); - python::def( "ptrDouble", &kdlib::ptrDoubleFloat, + python::def( "ptrDouble", pykd::ptrDoubleFloat, "Read a float with single precision from the target memory" ); - python::def( "loadBytes", &loadBytes, loadBytes_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadBytes", pykd::loadBytes, loadBytes_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of unsigned bytes" ) ); - python::def( "loadWords", &loadWords, loadWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadWords", pykd::loadWords, loadWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of unsigned shorts" ) ); - python::def( "loadDWords", &loadDWords, loadDWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadDWords", pykd::loadDWords, loadDWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of unsigned long ( double word )" ) ); - python::def( "loadQWords", &loadQWords, loadQWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadQWords", pykd::loadQWords, loadQWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of unsigned long long ( quad word )" ) ); - python::def( "loadSignBytes", &loadSignBytes, loadSignBytes_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadSignBytes", pykd::loadSignBytes, loadSignBytes_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of signed bytes" ) ); - python::def( "loadSignWords", &loadSignWords, loadSignWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadSignWords", pykd::loadSignWords, loadSignWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of signed words" ) ); - python::def( "loadSignDWords", &loadSignDWords, loadSignDWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadSignDWords", pykd::loadSignDWords, loadSignDWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of signed longs" ) ); - python::def( "loadSignQWords", &loadSignQWords, loadSignQWords_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadSignQWords", pykd::loadSignQWords, loadSignQWords_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of signed long longs" ) ); - python::def( "loadChars", &kdlib::loadChars, loadChars_( python::args( "address", "count", "phyAddr" ), + python::def( "loadChars", pykd::loadChars, loadChars_( python::args( "address", "count", "phyAddr" ), "Load string from target memory" ) ); - python::def( "loadWChars", &kdlib::loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ), + python::def( "loadWChars", pykd::loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ), "Load string from target memory" ) ); - python::def( "loadCStr", &kdlib::loadCStr, + python::def( "loadCStr", pykd::loadCStr, "Load string from the target buffer containing 0-terminated ansi-string" ); - python::def( "loadWStr", &kdlib::loadWStr, + python::def( "loadWStr", pykd::loadWStr, "Load string from the target buffer containing 0-terminated unicode-string" ); - python::def( "loadUnicodeString", &loadUnicodeStr, + python::def( "loadUnicodeString", pykd::loadUnicodeStr, "Return string represention of windows UNICODE_STRING type" ); - python::def( "loadAnsiString", &loadAnsiStr, + python::def( "loadAnsiString", pykd::loadAnsiStr, "Return string represention of windows ANSI_STRING type" ); - python::def( "loadFloats", &loadFloats, loadFloats_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadFloats", pykd::loadFloats, loadFloats_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of floats" ) ); - python::def( "loadDoubles", &loadDoubles, loadDoubles_( python::args( "offset", "count", "phyAddr" ), + python::def( "loadDoubles", pykd::loadDoubles, loadDoubles_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of doubles" ) ); - python::def( "ptrPtr", &ptrPtr, + python::def( "ptrPtr", pykd::ptrPtr, "Read an pointer value from the target memory" ); - python::def( "loadPtrList", &loadPtrList, + python::def( "loadPtrList", pykd::loadPtrList, "Return list of pointers, each points to next" ); - python::def( "loadPtrs", &loadPtrArray, + python::def( "loadPtrs", pykd::loadPtrArray, "Read the block of the target's memory and return it as a list of pointers" ); // types and vaiables - python::def( "getSourceFile", &kdlib::getSourceFile, getSourceFile_( python::args( "offset"), + python::def( "getSourceFile", pykd::getSourceFile, getSourceFile_( python::args( "offset"), "Return source file by the specified offset" ) ); - python::def( "getSourceLine", &getSourceLine, getSourceLine_( python::args( "offset"), + python::def( "getSourceLine", pykd::getSourceLine, getSourceLine_( python::args( "offset"), "Return source file name, line and displacement by the specified offset" ) ); - python::def( "getOffset", &kdlib::getSymbolOffset, + python::def( "getOffset", pykd::getSymbolOffset, "Return traget virtual address for specified symbol" ); - python::def( "findSymbol", &TypeInfoAdapter::findSymbol, findSymbol_( python::args( "offset", "showDisplacement"), + python::def( "findSymbol", pykd::findSymbol, findSymbol_( python::args( "offset", "showDisplacement"), "Find symbol by the target virtual memory offset" ) ); - python::def("findSymbolAndDisp", &findSymbolAndDisp, + python::def("findSymbolAndDisp", pykd::findSymbolAndDisp, "Return tuple(symbol_name, displacement) by virtual address" ); - python::def( "sizeof", &kdlib::getSymbolSize, + python::def( "sizeof", pykd::getSymbolSize, "Return a size of the type or variable" ); - python::def("typedVarList", &TypedVarAdapter::getTypedVarListByTypeName, + python::def("typedVarList", pykd::getTypedVarListByTypeName, "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ); - python::def("typedVarList", &TypedVarAdapter::getTypedVarListByType, + python::def("typedVarList", pykd::getTypedVarListByType, "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ); - python::def("typedVarArray", &TypedVarAdapter::getTypedVarArrayByTypeName, + python::def("typedVarArray", pykd::getTypedVarArrayByTypeName, "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" ); - python::def("typedVarArray", &TypedVarAdapter::getTypedVarArrayByType, + python::def("typedVarArray", pykd::getTypedVarArrayByType, "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" ); - python::def("containingRecord", &TypedVarAdapter::containingRecordByName, + python::def("containingRecord", pykd::containingRecordByName, "Return instance of the typedVar class. It's value are loaded from the target memory." "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" ); - python::def("containingRecord", &TypedVarAdapter::containingRecordByType, + python::def("containingRecord", pykd::containingRecordByType, "Return instance of the typedVar class. It's value are loaded from the target memory." "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" ); - python::def("createStruct", &kdlib::defineStruct, - "return custom defined struct" ); - python::def( "createStruct", &kdlib::defineStruct, createStruct_( python::args( "name", "align" ), - "Create custom struct" ) ); - python::def( "createUnion", &kdlib::defineUnion, - "Create custom union" ); + //python::def("createStruct", &kdlib::defineStruct, + // "Return custom defined struct" ); + python::def( "createStruct", &pykd::defineStruct, createStruct_( python::args( "name", "align" ), + "Create custom struct" ) ); + python::def( "createUnion", &pykd::defineUnion, + "Create custom union" ); // CPU registers - python::def( "reg", &getRegisterByName, + python::def( "reg", pykd::getRegisterByName, "Return a CPU regsiter value by the register's name" ); - python::def ( "rdmsr", &loadMSR, + python::def ( "rdmsr", pykd::loadMSR, "Return MSR value" ); - python::def( "wrmsr", &setMSR, + python::def( "wrmsr", pykd::setMSR, "Set MSR value" ); - python::def( "getProcessorMode", &getProcessorMode, + python::def( "getProcessorMode", pykd::getProcessorMode, "Return current processor mode as string: X86, ARM, IA64 or X64" ); - python::def( "getProcessorType", &getProcessorType, + python::def( "getProcessorType", pykd::getProcessorType, "Return type of physical processor: X86, ARM, IA64 or X64" ); - python::def( "setProcessorMode", &setProcessorMode, + python::def( "setProcessorMode",pykd::setProcessorMode, "Set current processor mode (X86, ARM, IA64 or X64)" ); - python::def( "switchProcessorMode", &switchProcessorMode, + python::def( "switchProcessorMode", pykd::switchProcessorMode, "Switch processor mode ( X86 <-> X64 )" ); // stack and local variables - python::def( "getStack", &getCurrentStack, + python::def( "getStack", pykd::getCurrentStack, "Return a current stack as a list of stackFrame objects" ); - python::def( "getFrame", &getCurrentFrame, + python::def( "getFrame", pykd::getCurrentFrame, "Return a current stack frame" ); @@ -325,9 +328,9 @@ BOOST_PYTHON_MODULE( pykd ) // "Get list of function arguments" ); // breakpoints - python::def( "setBp", &kdlib::softwareBreakPointSet, + python::def( "setBp", pykd::softwareBreakPointSet, "Set software breakpoint on executiont" ); - python::def( "removeBp", &kdlib::breakPointRemove, + python::def( "removeBp", pykd::breakPointRemove, "Remove breapoint by IDs" ); //python::def( "setBp", &setHardwareBp, setHardwareBp_( python::args( "offset", "size", "accsessType", "callback" ) , @@ -336,34 +339,46 @@ BOOST_PYTHON_MODULE( pykd ) // // "Remove all breapoints" ); // processes and threads - python::def ( "getNumberProcesses", kdlib::getNumberProcesses, + python::def ( "getNumberProcesses", pykd::getNumberProcesses, "Return number of processes on the target system" ); - python::def( "getCurrentProcess", kdlib::getCurrentProcessId, + python::def( "getCurrentProcess", pykd::getCurrentProcessId, "Return ID of the current process. This ID can be used with terminateProcess" ); - python::def( "getProcessOffset", kdlib::getProcessOffset, + python::def( "getProcessOffset", pykd::getProcessOffset, "Return the location in the target's memory of the process structure ( PEB )" ); - python::def( "getProcessSystemID", kdlib::getProcessSystemId, + python::def( "getProcessSystemID", pykd::getProcessSystemId, "Return system process ID ( PID )" ); - python::def( "getProcessId", kdlib::getProcessIdByOffset, + python::def( "getProcessId", pykd::getProcessIdByOffset, "Return process ID by the location in the target's memory of the process structure" ); - python::def( "getProcessId", kdlib::getProcessIdBySystemId, + python::def( "getProcessId", pykd::getProcessIdBySystemId, "Return process ID by the system's process ID ( PID )" ); + python::def( "setCurrentProcess", pykd::setCurrentProcess, + "Set current process by ID" ); + python::def( "getImplicitProcess", pykd::getImplicitProcessOffset, + "Return implicit process" ); + python::def( "setImplicitProcess", pykd::setImplicitProcess, + "Set implicit process" ); // python::def( "getCurrentProcessExeName", &getCurrentProcessExecutableName, // "Return name of executable file loaded in the current process"); - python::def ( "getNumberThreads", kdlib::getNumberThreads, + python::def ( "getNumberThreads", pykd::getNumberThreads, "Return number of threads on the target system" ); - python::def( "getCurrentThread", kdlib::getCurrentThreadId, + python::def( "getCurrentThread", pykd::getCurrentThreadId, "Return ID of the current thread" ); - python::def( "getThreadOffset", kdlib::getThreadOffset, + python::def( "getThreadOffset", pykd::getThreadOffset, "Return the location in the target's memory of the thread structure ( TEB )" ); - python::def( "getThreadSystemID", kdlib::getThreadSystemId, + python::def( "getThreadSystemID", pykd::getThreadSystemId, "Return system thread ID ( TID )" ); - python::def( "getThreadId", kdlib::getThreadIdByOffset, + python::def( "getThreadId", pykd::getThreadIdByOffset, "Return thread ID by the location in the target's memory of the thread structure" ); - python::def( "getThreadId", kdlib::getThreadIdBySystemId, + python::def( "getThreadId", pykd::getThreadIdBySystemId, "Return thread ID by the system's thread ID ( PID )" ); + python::def("setCurrentThread", pykd::setCurrentThread, + "Set current thread" ); + python::def( "getImplicitThread", pykd::getImplicitThreadOffset, + "Return implicit thread" ); + python::def( "setImplicitThread", pykd::setImplicitThread, + "Set implicit thread" ); // // symbol path // python::def( "getSymbolPath", &getSymbolPath, "Returns current symbol path"); @@ -415,50 +430,50 @@ BOOST_PYTHON_MODULE( pykd ) 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) ) - .def("begin", &kdlib::Module::getBase, + .def("begin", ModuleAdapter::getBase, "Return start address of the module" ) - .def("end", &kdlib::Module::getEnd, + .def("end", ModuleAdapter::getEnd, "Return end address of the module" ) - .def("size", &kdlib::Module::getSize, + .def("size", ModuleAdapter::getSize, "Return size of the module" ) - .def("name", &kdlib::Module::getName, + .def("name", ModuleAdapter::getName, "Return name of the module" ) - .def("reload", &kdlib::Module::reloadSymbols, + .def("reload", ModuleAdapter::reloadSymbols, "(Re)load symbols for the module" ) - .def("image", &kdlib::Module::getImageName, + .def("image", ModuleAdapter::getImageName, "Return name of the image of the module" ) - .def("symfile", &kdlib::Module::getSymFile, + .def("symfile", ModuleAdapter::getSymFile, "Return the full path to the module's symbol information" ) - .def("offset", &kdlib::Module::getSymbolVa, + .def("offset", ModuleAdapter::getSymbolVa, "Return offset of the symbol" ) .def("findSymbol", ModuleAdapter::findSymbol, Module_findSymbol( python::args("offset", "showDisplacement"), "Return symbol name by virtual address" ) ) .def("findSymbolAndDisp", ModuleAdapter::findSymbolAndDisp, "Return tuple(symbol_name, displacement) by virtual address" ) - .def("rva", &kdlib::Module::getSymbolRva, + .def("rva", ModuleAdapter::getSymbolRva, "Return rva of the symbol" ) - .def("sizeof", &kdlib::Module::getSymbolSize, + .def("sizeof", ModuleAdapter::getSymbolSize, "Return a size of the type or variable" ) - .def("type", &kdlib::Module::getTypeByName, + .def("type", ModuleAdapter::getTypeByName, "Return typeInfo class by type name" ) - .def("typedVar", &kdlib::Module::getTypedVarByAddr, + .def("typedVar", ModuleAdapter::getTypedVarByAddr, "Return a typedVar class instance" ) - .def("typedVar",&kdlib::Module::getTypedVarByName, + .def("typedVar",ModuleAdapter::getTypedVarByName, "Return a typedVar class instance" ) - .def("typedVar",&kdlib::Module::getTypedVarByTypeName, + .def("typedVar", ModuleAdapter::getTypedVarByTypeName, "Return a typedVar class instance" ) - .def("typedVarList", &ModuleAdapter::getTypedVarListByTypeName, + .def("typedVarList", ModuleAdapter::getTypedVarListByTypeName, "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) - .def("typedVarArray", &ModuleAdapter::getTypedVarArrayByTypeName, + .def("typedVarArray", ModuleAdapter::getTypedVarArrayByTypeName, "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" ) - .def("containingRecord", &kdlib::Module::containingRecord, + .def("containingRecord", ModuleAdapter::containingRecord, "Return instance of the typedVar class. It's value are loaded from the target memory." "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" ) .def("enumSymbols", ModuleAdapter::enumSymbols, Module_enumSymbols( python::args("mask"), "Return list of tuple ( symbolname, offset )" ) ) - .def("checksum", &kdlib::Module::getCheckSum, + .def("checksum", ModuleAdapter::getCheckSum, "Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" ) - .def("timestamp", &kdlib::Module::getTimeDataStamp, + .def("timestamp", ModuleAdapter::getTimeDataStamp, "Return a low 32 bits of the time stamp of the image: IMAGE_FILE_HEADER.TimeDateStamp" ) //.def("unloaded", &Module::isUnloaded, // "Returns a flag that the module was unloaded") @@ -468,76 +483,74 @@ BOOST_PYTHON_MODULE( pykd ) // "Return string from the module's version resources" ) //.def("getVersion", &Module::getVersion, // "Return tuple of the module's file version" ) - .def("__getattr__", &kdlib::Module::getSymbolVa, + .def("__getattr__", ModuleAdapter::getSymbolVa, "Return address of the symbol" ) .def( "__str__", &ModuleAdapter::print ); python::class_, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init ) - .def("__init__", python::make_constructor( TypeInfoAdapter::getTypeInfoByName ) ) - .def( "name", &kdlib::TypeInfo::getName, + .def("__init__", python::make_constructor( pykd::getTypeInfoByName ) ) + .def( "name", TypeInfoAdapter::getName, "Return type name" ) - .def( "size", &kdlib::TypeInfo::getSize, + .def( "size", TypeInfoAdapter::getSize, "Return type size" ) .def( "staticOffset", TypeInfoAdapter::getStaticOffset, "Return offset of the static field" ) .def( "fieldOffset", TypeInfoAdapter::getElementOffset, "Return offset of the nonstatic field" ) - .def( "bitOffset", &kdlib::TypeInfo::getBitOffset, + .def( "bitOffset", TypeInfoAdapter::getBitOffset, "Return bit field's offset" ) - .def( "bitWidth", &kdlib::TypeInfo::getBitWidth, + .def( "bitWidth", TypeInfoAdapter::getBitWidth, "Return bit field's length" ) .def( "field", TypeInfoAdapter::getElementByName, "Return field's type" ) - .def( "fieldName", &kdlib::TypeInfo::getElementName, + .def( "fieldName", TypeInfoAdapter::getElementName, "Return name of struct field by index" ) - //.def( "asMap", &kdlib::TypeInfo::asMap, - // "Return type as python dict ( for enum types )" ) - .def( "deref", &kdlib::TypeInfo::deref, + .def( "deref", TypeInfoAdapter::deref, "Return type of pointer" ) - .def( "append", &kdlib::TypeInfo::appendField, + .def( "append", TypeInfoAdapter::appendField, "Add a new field to custom defined struct" ) - .def( "ptrTo", &TypeInfoAdapter::ptrTo, TypeInfo_ptrTo( python::args( "ptrSize" ), + .def( "ptrTo", TypeInfoAdapter::ptrTo, TypeInfo_ptrTo( python::args( "ptrSize" ), "Return pointer to the type" ) ) - .def( "arrayOf", &kdlib::TypeInfo::arrayOf, + .def( "arrayOf", TypeInfoAdapter::arrayOf, "Return array of the type" ) - .def( "isArray", &kdlib::TypeInfo::isArray, + .def( "isArray", TypeInfoAdapter::isArray, "Return flag: type is array" ) - .def( "isPointer", &kdlib::TypeInfo::isPointer, + .def( "isPointer", TypeInfoAdapter::isPointer, "Return flag: type is pointer" ) - .def( "isVoid", &kdlib::TypeInfo::isVoid, + .def( "isVoid", TypeInfoAdapter::isVoid, "Return flag: type is void" ) - .def( "isBase", &kdlib::TypeInfo::isBase, + .def( "isBase", TypeInfoAdapter::isBase, "Return flag: type is base" ) - .def( "isUserDefined", &kdlib::TypeInfo::isUserDefined, + .def( "isUserDefined", TypeInfoAdapter::isUserDefined, "Return flag: type is UDT" ) - .def( "isEnum", &kdlib::TypeInfo::isEnum, + .def( "isEnum", TypeInfoAdapter::isEnum, "Return flag: type is enum" ) - .def( "isBitField", &kdlib::TypeInfo::isBitField, + .def( "isBitField", TypeInfoAdapter::isBitField, "Return flag: type is bit field" ) - .def( "isFunction", &kdlib::TypeInfo::isFunction, + .def( "isFunction", TypeInfoAdapter::isFunction, "Return flag: type is function" ) - .def( "isConstant", &kdlib::TypeInfo::isConstant, + .def( "isConstant", TypeInfoAdapter::isConstant, "Return flag: type is constant" ) - .def( "getCallingConvention", &kdlib::TypeInfo::getCallingConvention, + .def( "getCallingConvention", TypeInfoAdapter::getCallingConvention, "Returns an indicator of a methods calling convention: callingConvention" ) - .def( "getClassParent", &kdlib::TypeInfo::getClassParent, + .def( "getClassParent", TypeInfoAdapter::getClassParent, "Return class parent" ) - .def( "__str__", &kdlib::TypeInfo::str, + .def( "__str__", TypeInfoAdapter::str, "Return type as a printable string" ) .def( "__getattr__", TypeInfoAdapter::getElementByName ) - .def("__len__", &kdlib::TypeInfo::getElementCount ) + .def("__len__", TypeInfoAdapter::getElementCount ) .def("__getitem__", TypeInfoAdapter::getElementByIndex ) ; python::class_, boost::noncopyable >("typedVar", "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init ) - .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByName) ) - .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByTypeName) ) - .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByTypeInfo) ) - .def("getAddress", &kdlib::TypedVar::getAddress, + .def("__init__", python::make_constructor(pykd::getTypedVarByName) ) + .def("__init__", python::make_constructor(pykd::getTypedVarByTypeName) ) + .def("__init__", python::make_constructor(pykd::getTypedVarByTypeInfo) ) + .def("getAddress", TypedVarAdapter::getAddress, "Return virtual address" ) - .def("sizeof", &kdlib::TypedVar::getSize, + .def("sizeof", TypedVarAdapter::getSize, "Return size of a variable in the target memory" ) .def("fieldOffset", TypedVarAdapter::getFieldOffsetByName, "Return target field offset" ) @@ -547,17 +560,17 @@ BOOST_PYTHON_MODULE( pykd ) "Return field of structure as an object attribute" ) .add_property( "fields", TypedVarAdapter::getFields, "Return list of tuple ( filedName, fieldOffset, fieldValue )" ) - .def( "fieldName", &kdlib::TypedVar::getElementName, + .def( "fieldName", TypedVarAdapter::getElementName, "Return name of struct field by index" ) - .def("deref", &kdlib::TypedVar::deref, + .def("deref",TypedVarAdapter::deref, "Return value by pointer" ) - .def("type", &kdlib::TypedVar::getType, + .def("type", TypedVarAdapter::getType, "Return typeInfo instance" ) .def("__getattr__", TypedVarAdapter::getField, "Return field of structure as an object attribute" ) - .def( "__str__", &TypedVarAdapter::print ) - .def("__len__", &kdlib::TypedVar::getElementCount ) - .def("__getitem__", &TypedVarAdapter::getElementByIndex ) + .def( "__str__", TypedVarAdapter::print ) + .def("__len__", TypedVarAdapter::getElementCount ) + .def("__getitem__", TypedVarAdapter::getElementByIndex ) //.def("__getitem__", &kdlib::TypedVar::getElementByIndexPtr ) ; @@ -585,26 +598,30 @@ BOOST_PYTHON_MODULE( pykd ) python::class_( "stackFrame", "class for stack's frame representation", python::no_init ) - .def_readonly( "ip", &kdlib::StackFrame::getIP, "instruction pointer" ) - .def_readonly( "ret", &kdlib::StackFrame::getRET, "return pointer" ) - .def_readonly( "fp", &kdlib::StackFrame::getFP, "frame pointer" ) - .def_readonly( "sp", &kdlib::StackFrame::getSP, "stack pointer" ) - .def( "__str__", &printStackFrame ); + .add_property( "ip", StackFrameAdapter::getIP, "instruction pointer" ) + .add_property( "instructionOffset", StackFrameAdapter::getIP, "Return a frame's instruction offset" ) + .add_property( "ret",StackFrameAdapter::getRET, "return pointer" ) + .add_property( "returnOffset",StackFrameAdapter::getRET, "Return a frame's return offset" ) + .add_property( "fp", StackFrameAdapter::getFP, "frame pointer" ) + .add_property( "frameOffset",StackFrameAdapter::getFP, "Return a frame's offset" ) + .add_property( "sp", StackFrameAdapter::getSP, "stack pointer" ) + .add_property( "stackOffset", StackFrameAdapter::getSP, "Return a frame's stack offset" ) + .def( "__str__", StackFrameAdapter::print ); python::class_( "cpu", "class for CPU context representation", python::no_init ) - .def("__init__", python::make_constructor(&kdlib::loadCPUCurrentContext) ) - .def("__init__", python::make_constructor(&kdlib::loadCPUContextByIndex) ) - .add_property("ip", &kdlib::CPUContext::getIP ) - .add_property("sp", &kdlib::CPUContext::getSP ) - .add_property("fp", &kdlib::CPUContext::getSP ) - .def("getCPUType", &kdlib::CPUContext::getCPUType ) - .def("getCPUMode", &kdlib::CPUContext::getCPUMode ) - .def("setCPUMode", &kdlib::CPUContext::setCPUMode ) - .def("switchCPUMode", &kdlib::CPUContext::switchCPUMode ) - .def("getStack", &CPUContextAdaptor::getStack ) - .def("__getattr__", &CPUContextAdaptor::getRegisterByName ) - .def("__getitem__", &CPUContextAdaptor::getRegisterByIndex ); + .def("__init__", python::make_constructor(pykd::loadCPUCurrentContext) ) + .def("__init__", python::make_constructor(pykd::loadCPUContextByIndex) ) + .add_property("ip", CPUContextAdapter::getIP ) + .add_property("sp", CPUContextAdapter::getSP ) + .add_property("fp", CPUContextAdapter::getSP ) + .def("getCPUType", CPUContextAdapter::getCPUType ) + .def("getCPUMode", CPUContextAdapter::getCPUMode ) + .def("setCPUMode", CPUContextAdapter::setCPUMode ) + .def("switchCPUMode", CPUContextAdapter::switchCPUMode ) + .def("getStack", CPUContextAdapter::getStack ) + .def("__getattr__", CPUContextAdapter::getRegisterByName ) + .def("__getitem__", CPUContextAdapter::getRegisterByIndex ); python::class_( "systemVersion", "Operation system version", python::no_init) @@ -622,7 +639,7 @@ BOOST_PYTHON_MODULE( pykd ) // "String for the service pack level of the target computer") //.def_readonly( "isCheckedBuild", &SystemVersion::isCheckedBuild, // "Checked build flag") - .def("__str__", &printSystemVersion, + .def("__str__", pykd::printSystemVersion, "Return object as a string"); @@ -640,7 +657,7 @@ BOOST_PYTHON_MODULE( pykd ) "The address where the exception occurred") .add_property( "parameters", &getExceptionInfoParameters, "An array of additional arguments that describe the exception") - .def( "__str__", &printExceptionInfo, + .def( "__str__", pykd::printExceptionInfo, "Return object as a string"); // python::enum_("eventType", "Type of debug event") @@ -667,22 +684,22 @@ BOOST_PYTHON_MODULE( pykd ) // "Function reads the kernel bug check code and related parameters\n" // "And return tuple: (code, arg1, arg2, arg3, arg4)" ); - python::class_("disasm", "Class disassemble a processor instructions" ) - .def( python::init<>( "constructor" ) ) - .def( python::init( boost::python::args("offset"), "constructor" ) ) - .def( "disasm", &kdlib::Disasm::disassemble, "Disassemble next instruction" ) - .def( "disasm", &kdlib::Disasm::jump, "Disassemble from the specified offset" ) - .def( "asm", &kdlib::Disasm::assembly, "Insert assemblied instuction to current offset" ) - .def( "begin", &kdlib::Disasm::begin, "Return begin offset" ) - .def( "current", &kdlib::Disasm::current, "Return current offset" ) - .def( "length", &kdlib::Disasm::length, "Return current instruction length" ) - .def( "instruction", &kdlib::Disasm::instruction, "Returm current disassembled instruction" ) - .def( "ea", &kdlib::Disasm::ea, "Return effective address for last disassembled instruction or 0" ) - .def( "reset", &kdlib::Disasm::reset, "Reset current offset to begin" ) - .def( "findOffset", &kdlib::Disasm::getNearInstruction, "Return the location of a processor instruction relative to a given location" ) - .def( "jump", &kdlib::Disasm::jump, "Change the current instruction" ) - .def( "jumprel", &kdlib::Disasm::jumprel, "Change the current instruction" ) - .def( "__str__", &kdlib::Disasm::instruction ); + python::class_("disasm", "Class disassemble a processor instructions",python::no_init) + .def( "__init__", python::make_constructor(pykd::loadDisasm ) ) + .def( "__init__", python::make_constructor(pykd::loadDisasmWithOffset ) ) + .def( "disasm", DisasmAdapter::disassemble, "Disassemble next instruction" ) + .def( "disasm", DisasmAdapter::jump, "Disassemble from the specified offset" ) + .def( "asm", DisasmAdapter::assembly, "Insert assemblied instuction to current offset" ) + .def( "begin", DisasmAdapter::begin, "Return begin offset" ) + .def( "current", DisasmAdapter::current, "Return current offset" ) + .def( "length", DisasmAdapter::length, "Return current instruction length" ) + .def( "instruction", DisasmAdapter::instruction, "Returm current disassembled instruction" ) + .def( "ea", DisasmAdapter::ea, "Return effective address for last disassembled instruction or 0" ) + .def( "reset", DisasmAdapter::reset, "Reset current offset to begin" ) + .def( "findOffset", DisasmAdapter::getNearInstruction, "Return the location of a processor instruction relative to a given location" ) + .def( "jump",DisasmAdapter::jump, "Change the current instruction" ) + .def( "jumprel", DisasmAdapter::jumprel, "Change the current instruction" ) + .def( "__str__", DisasmAdapter::instruction ); python::enum_("eventResult", "Return value of event handler") diff --git a/pykd/pymodule.cpp b/pykd/pymodule.cpp new file mode 100644 index 0000000..e9c3e62 --- /dev/null +++ b/pykd/pymodule.cpp @@ -0,0 +1,129 @@ +#include "stdafx.h" + +#include "pymodule.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring ModuleAdapter::print( kdlib::Module& module ) +{ + AutoRestorePyState pystate; + + std::wstringstream sstr; + + //prepareSymbolFile(); + + sstr << L"Module: " << module.getName() << std::endl; + sstr << L"Start: " << std::hex << module.getBase() << L" End: " << module.getEnd() << L" Size: " << module.getSize() << std::endl; + //sstr << (m_unloaded ? ", UNLOADED!" : "") << std::endl; + sstr << L"Image: " << module.getImageName() << std::endl; + sstr << L"Symbols: " << module.getSymFile() << std::endl; + + + //if ( m_symSession ) + //{ + // sstr << "Symbols: " << m_symSession->getSymbolFileName() << std::endl; + // std::string buildDesc = m_symSession->getBuildDescription(); + // if (!buildDesc.empty()) + // sstr << "\t" << buildDesc << std::endl; + //} + //else + //{ + // sstr << "Symbols: not found" << std::endl; + //} + + sstr << L"Timestamp: " << module.getTimeDataStamp() << std::endl; + sstr << L"Check Sum: " << module.getCheckSum() << std::endl; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list ModuleAdapter::enumSymbols( kdlib::Module& module, const std::wstring &mask ) +{ + kdlib::SymbolOffsetList offsetLst; + + do { + AutoRestorePyState pystate; + offsetLst = module.enumSymbols( mask ); + } while(false); + + python::list pyLst; + for ( kdlib::SymbolOffsetList::const_iterator it = offsetLst.begin(); it != offsetLst.end(); ++it ) + pyLst.append( python::make_tuple( it->first, it->second ) ); + return pyLst; +} + +/////////////////////////////////////////////////////////////////////////////// + + +std::wstring ModuleAdapter::findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement ) +{ + AutoRestorePyState pystate; + + kdlib::MEMDISPLACEMENT displacement = 0; + + std::wstring symbolName = module.findSymbol( offset, displacement ); + if ( !showDisplacement || displacement == 0 ) + return symbolName; + + std::wstringstream wsstr; + + wsstr << symbolName; + + if ( displacement > 0 ) + wsstr << L'+' << std::hex << displacement; + else + wsstr << L'-' << std::hex << -displacement; + + return wsstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::tuple ModuleAdapter::findSymbolAndDisp( kdlib::Module& module, kdlib::MEMOFFSET_64 offset ) +{ + kdlib::MEMDISPLACEMENT displacement = 0; + std::wstring symbolName; + + do { + AutoRestorePyState pystate; + symbolName = module.findSymbol( offset, displacement ); + } while(false); + + return python::make_tuple( symbolName, displacement ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list ModuleAdapter::getTypedVarListByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = module.loadTypedVarList( offset, typeName, fieldName ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list ModuleAdapter::getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = module.loadTypedVarArray( offset, typeName, number ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace pykd diff --git a/pykd/pymodule.h b/pykd/pymodule.h new file mode 100644 index 0000000..a8766dc --- /dev/null +++ b/pykd/pymodule.h @@ -0,0 +1,145 @@ +#pragma once + +#include + +#include "kdlib/module.h" + +#include "stladaptor.h" +#include "pythreadstate.h" + +namespace pykd { + + +struct ModuleAdapter : public kdlib::Module +{ + + static kdlib::ModulePtr loadModuleByName( const std::wstring &name ) + { + AutoRestorePyState pystate; + return kdlib::loadModule( name ); + } + + static kdlib::ModulePtr loadModuleByOffset( kdlib::MEMOFFSET_64 offset ) + { + AutoRestorePyState pystate; + return kdlib::loadModule( offset); + } + + static std::wstring getName( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getName(); + } + + static kdlib::MEMOFFSET_64 getBase( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getBase(); + } + + static kdlib::MEMOFFSET_64 getEnd( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getEnd(); + } + + static size_t getSize( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getSize(); + } + + static void reloadSymbols(kdlib::Module& module) + { + AutoRestorePyState pystate; + module.reloadSymbols(); + } + + static std::wstring getImageName( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getImageName(); + } + + static std::wstring getSymFile( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getSymFile(); + } + + static kdlib::MEMOFFSET_64 getSymbolVa( kdlib::Module& module, const std::wstring &symbolName ) + { + AutoRestorePyState pystate; + return module.getSymbolVa(symbolName); + } + + static kdlib::MEMOFFSET_32 getSymbolRva( kdlib::Module& module, const std::wstring &symbolName ) + { + AutoRestorePyState pystate; + return module.getSymbolRva(symbolName); + } + + static size_t getSymbolSize( kdlib::Module& module, const std::wstring &symbolName ) + { + AutoRestorePyState pystate; + return module.getSymbolSize(symbolName); + } + + static kdlib::TypeInfoPtr getTypeByName( kdlib::Module& module, const std::wstring &typeName ) + { + AutoRestorePyState pystate; + return module.getTypeByName(typeName); + } + + static kdlib::TypedVarPtr getTypedVarByAddr( kdlib::Module& module, kdlib::MEMOFFSET_64 offset ) + { + AutoRestorePyState pystate; + return module.getTypedVarByAddr(offset); + } + + static kdlib::TypedVarPtr getTypedVarByName( kdlib::Module& module, const std::wstring &symbolName ) + { + AutoRestorePyState pystate; + return module.getTypedVarByName(symbolName); + } + + static kdlib::TypedVarPtr getTypedVarByTypeName( kdlib::Module& module, const std::wstring &typeName, kdlib::MEMOFFSET_64 offset ) + { + AutoRestorePyState pystate; + return module.getTypedVarByTypeName(typeName, offset); + } + + static kdlib::TypedVarPtr containingRecord(kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) + { + AutoRestorePyState pystate; + return module.containingRecord(offset, typeName, fieldName); + } + + + static unsigned long getCheckSum( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getCheckSum(); + } + + static unsigned long getTimeDataStamp( kdlib::Module& module ) + { + AutoRestorePyState pystate; + return module.getTimeDataStamp(); + } + + static std::wstring print( kdlib::Module& module ); + + static python::list enumSymbols( kdlib::Module& module, const std::wstring &mask = L"*" ); + + static std::wstring findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement = true ); + + static python::tuple findSymbolAndDisp( kdlib::Module& module, kdlib::MEMOFFSET_64 offset ); + + static python::list getTypedVarListByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ); + + static python::list getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ); + +}; + +} // end namespace pykd diff --git a/pykd/pysymengine.h b/pykd/pysymengine.h new file mode 100644 index 0000000..647e309 --- /dev/null +++ b/pykd/pysymengine.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "pythreadstate.h" + +namespace pykd { + +inline +void setSymSrvDir(const std::wstring &symSrvDirectory) +{ + AutoRestorePyState pystate; + kdlib::setSymSrvDir(symSrvDirectory); +} + + +} // namespace pykd diff --git a/pykd/pystate.h b/pykd/pythreadstate.h similarity index 100% rename from pykd/pystate.h rename to pykd/pythreadstate.h diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp new file mode 100644 index 0000000..6cc3f70 --- /dev/null +++ b/pykd/pytypedvar.cpp @@ -0,0 +1,97 @@ +#include "stdafx.h" + +#include "pytypedvar.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadTypedVarList( offset, typeName, fieldName ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list getTypedVarListByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadTypedVarList( offset, typeInfo, fieldName ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list getTypedVarArrayByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadTypedVarArray( offset, typeName, number ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list getTypedVarArrayByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, size_t number ) +{ + kdlib::TypedVarList lst; + + do { + AutoRestorePyState pystate; + lst = kdlib::loadTypedVarArray( offset, typeInfo, number ); + } while(false); + + return vectorToList( lst ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::list TypedVarAdapter::getFields( kdlib::TypedVar& typedVar ) +{ + typedef boost::tuple FieldTuple; + + std::list lst; + + do { + + AutoRestorePyState pystate; + + for ( size_t i = 0; i < typedVar.getElementCount(); ++i ) + { + std::wstring name = typedVar.getElementName(i); + kdlib::MEMOFFSET_32 offset = typedVar.getElementOffset(i); + kdlib::TypedVarPtr val = typedVar.getElement(i); + + lst.push_back( FieldTuple( name, offset, val ) ); + } + + } while(false); + + python::list pylst; + + for ( std::list::const_iterator it = lst.begin(); it != lst.end(); ++it) + pylst.append( python::make_tuple( it->get<0>(), it->get<1>(), it->get<2>() ) ); + + return pylst; +} + +/////////////////////////////////////////////////////////////////////////////// + +} // namesapce pykd + diff --git a/pykd/pytypedvar.h b/pykd/pytypedvar.h new file mode 100644 index 0000000..79d9d4e --- /dev/null +++ b/pykd/pytypedvar.h @@ -0,0 +1,117 @@ +#pragma once + +#include +#include +namespace python = boost::python; + +#include "kdlib/typedvar.h" + +#include "stladaptor.h" +#include "pythreadstate.h" + +namespace pykd { + +inline kdlib::TypedVarPtr getTypedVarByTypeName( const std::wstring &name, kdlib::MEMOFFSET_64 addr ) +{ + AutoRestorePyState pystate; + return kdlib::loadTypedVar( name, addr ); +} + +inline kdlib::TypedVarPtr getTypedVarByName( const std::wstring &name ) +{ + AutoRestorePyState pystate; + return kdlib::loadTypedVar( name ); +} + +inline kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, kdlib::MEMOFFSET_64 addr ) +{ + AutoRestorePyState pystate; + return kdlib::loadTypedVar( typeInfo, addr ); +} + +python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ); +python::list getTypedVarListByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ); +python::list getTypedVarArrayByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ); +python::list getTypedVarArrayByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, size_t number ); + +inline kdlib::TypedVarPtr containingRecordByName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) +{ + AutoRestorePyState pystate; + return kdlib::containingRecord( offset, typeName, fieldName ); +} + +inline kdlib::TypedVarPtr containingRecordByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ) +{ + AutoRestorePyState pystate; + return kdlib::containingRecord( offset, typeInfo, fieldName ); +} + + +struct TypedVarAdapter { + + + static kdlib::MEMOFFSET_64 getAddress( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.getAddress(); + } + + static size_t getSize( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.getSize(); + } + + static kdlib::MEMOFFSET_32 getFieldOffsetByName( kdlib::TypedVar& typedVar, const std::wstring &name ) + { + AutoRestorePyState pystate; + return typedVar.getElementOffset( name ); + } + + static kdlib::TypedVarPtr getField( kdlib::TypedVar& typedVar, const std::wstring &name ) + { + AutoRestorePyState pystate; + return typedVar.getElement( name ); + } + + static size_t getElementCount( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.getElementCount(); + } + + static std::wstring getElementName( kdlib::TypedVar& typedVar, long index ) + { + AutoRestorePyState pystate; + return typedVar.getElementName( index ); + } + + static kdlib::TypedVarPtr getElementByIndex( kdlib::TypedVar& typedVar, long index ) + { + AutoRestorePyState pystate; + return typedVar.getElement( index ); + } + + static std::wstring print( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.str(); + } + + static python::list getFields( kdlib::TypedVar& typedVar ); + + static kdlib::TypeInfoPtr getType( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.getType(); + } + + static kdlib::TypedVarPtr deref( kdlib::TypedVar& typedVar ) + { + AutoRestorePyState pystate; + return typedVar.deref(); + } + +}; + +} // end namespace pykd diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp new file mode 100644 index 0000000..5c992a1 --- /dev/null +++ b/pykd/pytypeinfo.cpp @@ -0,0 +1,75 @@ +#include "stdafx.h" + +#include "kdlib/module.h" +#include "kdlib/exceptions.h" + +#include "pytypeinfo.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring findSymbol( kdlib::MEMOFFSET_64 offset, bool showDisplacement ) +{ + AutoRestorePyState pystate; + + kdlib::MEMDISPLACEMENT displacement = 0; + std::wstring symbolName; + + try { + + kdlib::ModulePtr mod = kdlib::loadModule( offset ); + + try { + + symbolName = mod->findSymbol( offset, displacement ); + + std::wstringstream sstr; + + sstr << mod->getName() << L'!' << symbolName; + + if ( !showDisplacement || displacement == 0 ) + return sstr.str(); + + if ( displacement > 0 ) + sstr << L'+' << std::hex << displacement; + else + sstr << L'-' << std::hex << -displacement; + + return sstr.str(); + + } catch( kdlib::DbgException& ) + { + std::wstringstream sstr; + sstr << mod->getName() << '+' << std::hex << ( offset - mod->getBase() ); + return sstr.str(); + } + + } catch( kdlib::DbgException& ) + { + std::wstringstream sstr; + sstr << std::hex << offset; + return sstr.str(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +python::tuple findSymbolAndDisp( ULONG64 offset ) +{ + kdlib::MEMDISPLACEMENT displacement = 0; + std::wstring symbolName; + std::wstring moduleName; + + do { + AutoRestorePyState pystate; + symbolName = kdlib::findSymbol( offset, displacement ); + moduleName = kdlib::getModuleName( kdlib::findModuleBase( offset ) ); + } while(false); + + return python::make_tuple(moduleName,symbolName,displacement); +} + +/////////////////////////////////////////////////////////////////////////////// + +} // pykd namespace diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h new file mode 100644 index 0000000..3730a20 --- /dev/null +++ b/pykd/pytypeinfo.h @@ -0,0 +1,228 @@ +#pragma once + +#include "kdlib/typeinfo.h" +#include "pythreadstate.h" + +namespace pykd { + +inline kdlib::MEMOFFSET_64 getSymbolOffset( const std::wstring &name ) +{ + AutoRestorePyState pystate; + return kdlib::getSymbolOffset(name); +} + +std::wstring findSymbol( kdlib::MEMOFFSET_64 offset, bool showDisplacement = true ); + +python::tuple findSymbolAndDisp( ULONG64 offset ); + +inline size_t getSymbolSize( const std::wstring &name ) +{ + AutoRestorePyState pystate; + return kdlib::getSymbolSize(name); +} + +inline kdlib::TypeInfoPtr defineStruct( const std::wstring &structName, size_t align = 0 ) +{ + AutoRestorePyState pystate; + return kdlib::defineStruct(structName, align); +} + +inline kdlib::TypeInfoPtr defineUnion( const std::wstring& unionName ) +{ + AutoRestorePyState pystate; + return kdlib::defineUnion(unionName); +} + + +inline kdlib::TypeInfoPtr getTypeInfoByName( const std::wstring &name ) +{ + AutoRestorePyState pystate; + return kdlib::loadType( name ); +} + +struct TypeInfoAdapter : public kdlib::TypeInfo { + + static std::wstring getName( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getName(); + } + + static size_t getSize( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getSize(); + } + + static kdlib::BITOFFSET getBitOffset( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getBitOffset(); + } + + static kdlib::BITOFFSET getBitWidth( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getBitWidth(); + } + + static kdlib::TypeInfoPtr getBitType( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getBitType(); + } + + static size_t getElementCount( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getElementCount(); + } + + static kdlib::MEMOFFSET_32 getElementOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) + { + AutoRestorePyState pystate; + return typeInfo.getElementOffset( name ); + } + + static std::wstring getElementName( kdlib::TypeInfo &typeInfo, size_t index ) + { + AutoRestorePyState pystate; + return typeInfo.getElementName(index); + } + + static kdlib::MEMOFFSET_64 getStaticOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) + { + AutoRestorePyState pystate; + return typeInfo.getElementVa( name ); + } + + + static kdlib::TypeInfoPtr getElementByName( kdlib::TypeInfo &typeInfo, const std::wstring &name ) + { + AutoRestorePyState pystate; + return typeInfo.getElement(name); + } + + + static kdlib::TypeInfoPtr getElementByIndex( kdlib::TypeInfo &typeInfo, size_t index ) + { + AutoRestorePyState pystate; + return typeInfo.getElement(index); + } + + static kdlib::TypeInfoPtr ptrTo( kdlib::TypeInfo &typeInfo, size_t ptrSize = 0 ) + { + AutoRestorePyState pystate; + return typeInfo.ptrTo(ptrSize); + } + + static kdlib::TypeInfoPtr deref( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.deref(); + } + + static kdlib::TypeInfoPtr arrayOf( kdlib::TypeInfo &typeInfo, size_t size ) + { + AutoRestorePyState pystate; + return typeInfo.arrayOf(size); + } + + static bool isArray( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isArray(); + } + + static bool isPointer( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isPointer(); + } + + static bool isVoid( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isVoid(); + } + + static bool isBase( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isBase(); + } + + static bool isUserDefined( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isUserDefined(); + } + + static bool isConstant( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isConstant(); + } + + static bool isEnum( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isEnum(); + } + + static bool isBitField( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isBitField(); + } + + static bool isFunction( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.isFunction(); + } + + static void appendField( kdlib::TypeInfo &typeInfo, const std::wstring &fieldName, kdlib::TypeInfoPtr &fieldType ) + { + AutoRestorePyState pystate; + typeInfo.appendField( fieldName, fieldType ); + } + + static kdlib::CallingConventionType getCallingConvention( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getCallingConvention(); + } + + static kdlib::TypeInfoPtr getClassParent( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getClassParent(); + } + + static std::wstring str( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.str(); + } + +}; + +struct BaseTypesEnum { + static kdlib::TypeInfoPtr getUInt1B() { return pykd::getTypeInfoByName(L"UInt1B"); } + static kdlib::TypeInfoPtr getUInt2B() { return pykd::getTypeInfoByName(L"UInt2B"); } + static kdlib::TypeInfoPtr getUInt4B() { return pykd::getTypeInfoByName(L"UInt4B"); } + static kdlib::TypeInfoPtr getUInt8B() { return pykd::getTypeInfoByName(L"UInt8B"); } + static kdlib::TypeInfoPtr getInt1B() { return pykd::getTypeInfoByName(L"Int1B"); } + static kdlib::TypeInfoPtr getInt2B() { return pykd::getTypeInfoByName(L"Int2B"); } + static kdlib::TypeInfoPtr getInt4B() { return pykd::getTypeInfoByName(L"Int4B"); } + static kdlib::TypeInfoPtr getInt8B() { return pykd::getTypeInfoByName(L"Int8B"); } + static kdlib::TypeInfoPtr getLong() { return pykd::getTypeInfoByName(L"Long"); } + static kdlib::TypeInfoPtr getULong() { return pykd::getTypeInfoByName(L"ULong"); } + static kdlib::TypeInfoPtr getBool() { return pykd::getTypeInfoByName(L"Bool"); } + static kdlib::TypeInfoPtr getChar() { return pykd::getTypeInfoByName(L"Char"); } + static kdlib::TypeInfoPtr getWChar() { return pykd::getTypeInfoByName(L"WChar"); } + static kdlib::TypeInfoPtr getVoidPtr() { return pykd::getTypeInfoByName(L"Void*"); } +}; + +} // end namespace pykd diff --git a/pykd/typedvar.h b/pykd/typedvar.h deleted file mode 100644 index d0daa50..0000000 --- a/pykd/typedvar.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include -#include -namespace python = boost::python; - -#include "kdlib/typedvar.h" - -#include "stladaptor.h" - -namespace pykd { - -struct TypedVarAdapter { - - static kdlib::TypedVarPtr getTypedVarByName( const std::wstring &name ) { - return kdlib::loadTypedVar( name ); - } - - static kdlib::TypedVarPtr getTypedVarByTypeName( const std::wstring &name, kdlib::MEMOFFSET_64 addr ) { - return kdlib::loadTypedVar( name, addr ); - } - - static kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, kdlib::MEMOFFSET_64 addr ) - { - return kdlib::loadTypedVar( typeInfo, addr ); - } - - static kdlib::MEMOFFSET_32 getFieldOffsetByName( kdlib::TypedVar& typedVar, const std::wstring &name ) { - return typedVar.getElementOffset( name ); - } - - static kdlib::TypedVarPtr getField( kdlib::TypedVar& typedVar, const std::wstring &name ) { - return typedVar.getElement( name ); - } - - - static kdlib::TypedVarPtr getElementByIndex( kdlib::TypedVar& typedVar, long index ) { - return typedVar.getElement( index ); - } - - static std::wstring print( kdlib::TypedVar& typedVar ) { - return typedVar.str(); - } - - - static kdlib::TypedVarPtr containingRecordByName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) { - return kdlib::containingRecord( offset, typeName, fieldName ); - } - - static kdlib::TypedVarPtr containingRecordByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ) { - return kdlib::containingRecord( offset, typeInfo, fieldName ); - } - - static python::list getFields( kdlib::TypedVar& typedVar ) - { - python::list lst; - for ( size_t i = 0; i < typedVar.getElementCount(); ++i ) - { - std::wstring name = typedVar.getElementName(i); - kdlib::MEMOFFSET_32 offset = typedVar.getElementOffset(i); - kdlib::TypedVarPtr val = typedVar.getElement(i); - lst.append( python::make_tuple( name, offset, val ) ); - } - - return lst; - } - - static python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) - { - kdlib::TypedVarList lst = kdlib::loadTypedVarList( offset, typeName, fieldName ); - return vectorToList( lst ); - } - - static python::list getTypedVarListByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ) - { - kdlib::TypedVarList lst = kdlib::loadTypedVarList( offset, typeInfo, fieldName ); - return vectorToList( lst ); - } - - static python::list getTypedVarArrayByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) - { - kdlib::TypedVarList lst = kdlib::loadTypedVarArray( offset, typeName, number ); - return vectorToList( lst ); - } - - static python::list getTypedVarArrayByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, size_t number ) - { - kdlib::TypedVarList lst = kdlib::loadTypedVarArray( offset, typeInfo, number ); - return vectorToList( lst ); - } - - -}; - -} // end namespace pykd diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h deleted file mode 100644 index 81dd195..0000000 --- a/pykd/typeinfo.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include "kdlib/typeinfo.h" - -namespace pykd { - -struct TypeInfoAdapter : public kdlib::TypeInfo { - - static kdlib::TypeInfoPtr getTypeInfoByName( const std::wstring &name ) - { - return kdlib::loadType( name ); - } - - static std::wstring findSymbol( kdlib::MEMOFFSET_64 offset, bool showDisplacement = true ) - { - kdlib::MEMDISPLACEMENT displacement = 0; - std::wstring symbolName; - - try { - - kdlib::ModulePtr mod = kdlib::loadModule( offset ); - - try { - - symbolName = mod->findSymbol( offset, displacement ); - - std::wstringstream sstr; - - sstr << mod->getName() << L'!' << symbolName; - - if ( !showDisplacement || displacement == 0 ) - return sstr.str(); - - if ( displacement > 0 ) - sstr << L'+' << std::hex << displacement; - else - sstr << L'-' << std::hex << -displacement; - - return sstr.str(); - - } catch( kdlib::DbgException& ) - { - std::wstringstream sstr; - sstr << mod->getName() << '+' << std::hex << ( offset - mod->getBase() ); - return sstr.str(); - } - - } catch( kdlib::DbgException& ) - { - std::wstringstream sstr; - sstr << std::hex << offset; - return sstr.str(); - } - - } - - static kdlib::MEMOFFSET_32 getElementOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { - return typeInfo.getElementOffset( name ); - } - - - static kdlib::MEMOFFSET_64 getStaticOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { - return typeInfo.getElementVa( name ); - } - - - static kdlib::TypeInfoPtr getElementByName( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { - return typeInfo.getElement(name); - } - - - static kdlib::TypeInfoPtr getElementByIndex( kdlib::TypeInfo &typeInfo, size_t index ) { - return typeInfo.getElement(index); - } - - static kdlib::TypeInfoPtr ptrTo( kdlib::TypeInfo &typeInfo, size_t ptrSize = 0 ) { - return typeInfo.ptrTo(ptrSize); - } - -}; - -struct BaseTypesEnum { - static kdlib::TypeInfoPtr getUInt1B() { return kdlib::loadType(L"UInt1B"); } - static kdlib::TypeInfoPtr getUInt2B() { return kdlib::loadType(L"UInt2B"); } - static kdlib::TypeInfoPtr getUInt4B() { return kdlib::loadType(L"UInt4B"); } - static kdlib::TypeInfoPtr getUInt8B() { return kdlib::loadType(L"UInt8B"); } - static kdlib::TypeInfoPtr getInt1B() { return kdlib::loadType(L"Int1B"); } - static kdlib::TypeInfoPtr getInt2B() { return kdlib::loadType(L"Int2B"); } - static kdlib::TypeInfoPtr getInt4B() { return kdlib::loadType(L"Int4B"); } - static kdlib::TypeInfoPtr getInt8B() { return kdlib::loadType(L"Int8B"); } - static kdlib::TypeInfoPtr getLong() { return kdlib::loadType(L"Long"); } - static kdlib::TypeInfoPtr getULong() { return kdlib::loadType(L"ULong"); } - static kdlib::TypeInfoPtr getBool() { return kdlib::loadType(L"Bool"); } - static kdlib::TypeInfoPtr getChar() { return kdlib::loadType(L"Char"); } - static kdlib::TypeInfoPtr getWChar() { return kdlib::loadType(L"WChar"); } - static kdlib::TypeInfoPtr getVoidPtr() { return kdlib::loadType(L"Void*"); } -}; - -} // end namespace pykd diff --git a/snippets/stkdelta.py b/snippets/stkdelta.py index e2fbf2b..d652ff0 100644 --- a/snippets/stkdelta.py +++ b/snippets/stkdelta.py @@ -30,11 +30,11 @@ def printDeltaStat(): for i in range( 0, len(stk) -1 ): try: - mod = module( stk[i].returnOffset ) + mod = module( stk[i].ret ) except BaseException: continue - delta = stk[i+1].frameOffset - stk[i].frameOffset + delta = stk[i+1].fp - stk[i].fp if delta > 0: moduleName = mod.name() @@ -44,7 +44,7 @@ def printDeltaStat(): else: moduleLst[moduleName] = delta - func = moduleName + "!" + mod.findSymbol( stk[i].returnOffset, showDisplacement = False ) + func = moduleName + "!" + mod.findSymbol( stk[i].ret, showDisplacement = False ) if func in funcLst: funcLst[func] = funcLst[func] + delta @@ -53,9 +53,9 @@ def printDeltaStat(): nt = module("nt") - thread = nt.typedVar( "_KTHREAD", getImplicitThread() ) + thread = nt.typedVar( "_KTHREAD", getThreadOffset( getCurrentThread() ) ) - stackSize = thread.InitialStack - thread.StackLimit + stackSize = thread.InitialStack - thread.StackLimit dprintln("") dprintln( "%12s\t%s" % ("Stack usage:", "Module:" ) ) @@ -80,12 +80,12 @@ def printDeltaStack(): dprintln( "Stack Delta:\tFunction:") for i in range( 0, len(stk) -1 ): - dprint( "%12s\t" % long( stk[i+1].frameOffset - stk[i].frameOffset) ) + dprint( "%12s\t" % long( stk[i+1].fp - stk[i].fp) ) try: - mod = module( stk[i].returnOffset ) - dprintln( "%s!%s"% ( mod.name(), mod.findSymbol( stk[i].returnOffset, showDisplacement = False ) ) ) + mod = module( stk[i].ret ) + dprintln( "%s!%s"% ( mod.name(), mod.findSymbol( stk[i].ret, showDisplacement = False ) ) ) except BaseException: - dprintln( findSymbol( stk[i].returnOffset ) ) + dprintln( findSymbol( stk[i].ret ) ) def main(): diff --git a/test/scripts/customtypestest.py b/test/scripts/customtypestest.py index d92e0c3..0ca5abf 100644 --- a/test/scripts/customtypestest.py +++ b/test/scripts/customtypestest.py @@ -97,3 +97,20 @@ class CustomTypesTest(unittest.TestCase): self.assertEqual( pykd.ptrSize(), mySubStructPtr.size() ) + def testAlign(self): + struct = pykd.createStruct(name ="MyAlignStruct", align=4) + struct.append( "m_field1", baseTypes.UInt1B ) + self.assertEqual( 1, struct.size() ) + struct.append( "m_field2", baseTypes.UInt1B ) + self.assertEqual( 2, struct.size() ) + struct.append( "m_field3", baseTypes.UInt1B ) + struct.append( "m_field4", baseTypes.UInt2B ) + self.assertEqual( 6, struct.size() ) + struct.append( "m_field5", baseTypes.UInt4B ) + self.assertEqual( 12, struct.size() ) + struct.append( "m_field6", baseTypes.UInt1B ) + self.assertEqual( 16, struct.size() ) + struct.append( "m_field7", baseTypes.UInt1B.arrayOf(5) ) + self.assertEqual( 20, struct.size() ) + +