From 17dbcecbe9fa0685a6020a68162d7e1102b0eb37 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 9 Jul 2013 08:12:26 +0000 Subject: [PATCH] [0.3.x] added : cpu context class git-svn-id: https://pykd.svn.codeplex.com/svn@84225 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/cpucontext.cpp | 29 +++++++++++++++++++++ pykd/cpucontext.h | 22 ++++++++++++++++ pykd/eventhandler.cpp | 18 ++++++++++++- pykd/pykd.vcxproj | 2 ++ pykd/pykd.vcxproj.filters | 6 +++++ pykd/pymod.cpp | 21 ++++++++++++--- pykd/variant.h | 11 +++++--- test/scripts/breakpoint.py | 4 +-- test/scripts/pykdtest.py | 7 ++--- test/scripts/regtest.py | 52 ++++++++------------------------------ 10 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 pykd/cpucontext.cpp create mode 100644 pykd/cpucontext.h diff --git a/pykd/cpucontext.cpp b/pykd/cpucontext.cpp new file mode 100644 index 0000000..d900ca4 --- /dev/null +++ b/pykd/cpucontext.cpp @@ -0,0 +1,29 @@ + +#include "stdafx.h" + +#include "cpucontext.h" +#include "variant.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +python::object CPUContextAdaptor::getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name ) +{ + kdlib::NumVariant var = cpu.getRegisterByName(name); + return NumVariantAdaptor::convertToPython( var ); +} + +/////////////////////////////////////////////////////////////////////////////// + +python::object CPUContextAdaptor::getRegisterByIndex( kdlib::CPUContext& cpu, size_t index ) +{ + kdlib::NumVariant var = cpu.getRegisterByIndex(index); + std::wstring name = cpu.getRegisterName(index); + + return python::make_tuple( name, NumVariantAdaptor::convertToPython( var ) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +} // end namespace pykd diff --git a/pykd/cpucontext.h b/pykd/cpucontext.h new file mode 100644 index 0000000..9eb4e6c --- /dev/null +++ b/pykd/cpucontext.h @@ -0,0 +1,22 @@ +#pragma once + +#include +namespace python = boost::python; + +#include "kdlib/dbgengine.h" +#include "kdlib/cpucontext.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +class CPUContextAdaptor +{ +public: + static python::object getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name ); + static python::object getRegisterByIndex( kdlib::CPUContext& cpu, size_t index ); +}; + +/////////////////////////////////////////////////////////////////////////////// + +} //end namespace pykd diff --git a/pykd/eventhandler.cpp b/pykd/eventhandler.cpp index 4e6da05..4aee170 100644 --- a/pykd/eventhandler.cpp +++ b/pykd/eventhandler.cpp @@ -142,7 +142,23 @@ kdlib::DebugCallbackResult EventHandler::onBreakpoint( kdlib::BREAKPOINT_ID bpId break; } - return pythonHandler(bpId ); + python::object resObj = pythonHandler( bpId ); + + if ( resObj.is_none() ) + { + result = kdlib::DebugCallbackNoChange; + break; + } + + int retVal = python::extract( resObj ); + + if ( retVal >= kdlib::DebugCallbackMax ) + { + result = kdlib::DebugCallbackBreak; + break; + } + + result = kdlib::DebugCallbackResult(retVal); } while( FALSE ); diff --git a/pykd/pykd.vcxproj b/pykd/pykd.vcxproj index 550e378..4eca006 100644 --- a/pykd/pykd.vcxproj +++ b/pykd/pykd.vcxproj @@ -123,6 +123,7 @@ + @@ -137,6 +138,7 @@ + diff --git a/pykd/pykd.vcxproj.filters b/pykd/pykd.vcxproj.filters index bdaccbc..8d44606 100644 --- a/pykd/pykd.vcxproj.filters +++ b/pykd/pykd.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files + @@ -74,6 +77,9 @@ Source Files + + Source Files + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 5beb526..f863722 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" +#include #include "kdlib/kdlib.h" @@ -13,6 +14,7 @@ #include "typedvar.h" #include "windbgext.h" #include "eventhandler.h" +#include "cpucontext.h" using namespace pykd; @@ -244,6 +246,7 @@ BOOST_PYTHON_MODULE( pykd ) "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" ); + // // CPU registers // python::def( "reg", &getRegByName, // "Return a CPU regsiter value by the register's name" ); @@ -294,10 +297,10 @@ BOOST_PYTHON_MODULE( pykd ) // "Set implicit thread for current process" ); // python::def( "getProcessThreads", &pysupport::getProcessThreads, // "Get all process's threads ( user mode only )" ); - python::def( "getCurrentProcessId", &kdlib::getCurrentProcessId, - "Return PID of the current process ( user mode only )" ); - python::def( "getCurrentThreadId", &kdlib::getCurrentThreadId, - "Return TID of the current thread ( user mode only )" ); + //python::def( "getCurrentProcessId", &kdlib::getCurrentProcessId, + // "Return PID of the current process ( user mode only )" ); + //python::def( "getCurrentThreadId", &kdlib::getCurrentThreadId, + // "Return TID of the current thread ( user mode only )" ); // python::def( "getCurrentProcessExeName", &getCurrentProcessExecutableName, // "Return name of executable file loaded in the current process"); @@ -510,6 +513,16 @@ BOOST_PYTHON_MODULE( pykd ) ; + 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("__getattr__", &CPUContextAdaptor::getRegisterByName ) + .def("__getitem__", &CPUContextAdaptor::getRegisterByIndex ); + // python::class_ >( // "cpuReg", "CPU regsiter class", boost::python::no_init ) diff --git a/pykd/variant.h b/pykd/variant.h index cf5ea8b..c6b188b 100644 --- a/pykd/variant.h +++ b/pykd/variant.h @@ -37,10 +37,8 @@ public: return var; } - static python::object NumVariantAdaptor::convertToPython( kdlib::NumBehavior& num ) + static python::object NumVariantAdaptor::convertToPython( kdlib::NumVariant& var ) { - kdlib::NumVariant var = kdlib::NumVariant( num ); - if ( var.isChar() ) return python::object( var.asInt() ); @@ -80,6 +78,13 @@ public: return python::object( var.asInt() ); } + static python::object NumVariantAdaptor::convertToPython( kdlib::NumBehavior& num ) + { + kdlib::NumVariant var = kdlib::NumVariant( num ); + + return convertToPython( var ); + } + public: static python::object eq( kdlib::NumBehavior& var, python::object& obj ) { diff --git a/test/scripts/breakpoint.py b/test/scripts/breakpoint.py index 0346306..7944c22 100644 --- a/test/scripts/breakpoint.py +++ b/test/scripts/breakpoint.py @@ -14,10 +14,10 @@ class callCounter: return self.func(val) def stopOnBreak(id): - return pykd.Break + return pykd.eventResult.Break def continueOnBreak(id): - return pykd.NoChange + return pykd.eventResult.Proceed class BreakpointTest( unittest.TestCase ): diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index fc8fdb5..a29ec89 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -19,9 +19,8 @@ import moduletest import typeinfo import typedvar import breakpoint +import regtest - -#import regtest #import mspdbtest #import localstest #import customtypestest @@ -54,13 +53,15 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), - #unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), + unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), #unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ), # ^^^ unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ), unittest.TestLoader().loadTestsFromTestCase( breakpoint.BreakpointTest ), + + #unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ), #unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ), #unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionTest ), diff --git a/test/scripts/regtest.py b/test/scripts/regtest.py index 0398598..2db26f6 100644 --- a/test/scripts/regtest.py +++ b/test/scripts/regtest.py @@ -4,47 +4,17 @@ import target import pykd class CpuRegTest( unittest.TestCase ): - - def testCtor(self): - if pykd.is64bitSystem(): - pykd.reg("rax") - else: - pykd.reg("eax") - - pykd.reg( 0 ) - - def testFormat(self): - self.assertEqual( "%d" % int(pykd.reg(0)), "%d" % pykd.reg(0) ) - self.assertEqual( "%x" % int(pykd.reg(0)), "%x" % pykd.reg(0) ) - - def testGpr(self): - if pykd.is64bitSystem(): - pykd.reg("rax") - pykd.reg("rbx") - pykd.reg("rcx") - pykd.reg("rdx") - pykd.reg("rdi") - pykd.reg("rsi") - pykd.reg("rbp") - pykd.reg("rsp") - pykd.reg("rip") - else: - pykd.reg("eax") - pykd.reg("ebx") - pykd.reg("ecx") - pykd.reg("edx") - pykd.reg("edi") - pykd.reg("esi") - pykd.reg("ebp") - pykd.reg("esp") - pykd.reg("eip") + def testCtor(self): + currentcpu = pykd.cpu() + cpu0 = pykd.cpu(0) - def testFloatRegister(self): - "TODO: support float point regsiters" - self.assertRaises( pykd.BaseException, pykd.reg, "st0" ) - - def testMmxRegister(self): - "TODO: support MMX regsiters" - self.assertRaises( pykd.BaseException, pykd.reg, "mmx0" ) + def testIp(self): + currentcpu = pykd.cpu() + self.assertNotEqual( 0, currentcpu.ip ) + self.assertNotEqual( 0, currentcpu.sp ) + self.assertNotEqual( 0, currentcpu.fp ) + def testRegEnum(self): + for r in pykd.cpu(): + pass