[0.1.x] added : MemoryException class

[0.1.x] added : loadChars
[0.1.x] added : loadWChars

git-svn-id: https://pykd.svn.codeplex.com/svn@70662 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-21 07:13:31 +00:00 committed by Mikhail I. Izmestev
parent 4e072f3ef5
commit dd5ebf105a
10 changed files with 239 additions and 18 deletions

View File

@ -41,9 +41,17 @@ public:
public: public:
ULONG64 addr64( ULONG64 addr );
DbgOut dout() {
return DbgOut( m_client );
}
DbgIn din() {
return DbgIn( m_client );
}
std::string dbgCommand( const std::wstring &command ); std::string dbgCommand( const std::wstring &command );
void loadDump( const std::wstring &fileName );
void startProcess( const std::wstring &processName ); void startProcess( const std::wstring &processName );
@ -64,6 +72,8 @@ public:
bool isDumpAnalyzing(); bool isDumpAnalyzing();
void loadDump( const std::wstring &fileName );
Module loadModule( const std::string &moduleName ) { Module loadModule( const std::string &moduleName ) {
return Module( m_client, moduleName ); return Module( m_client, moduleName );
} }
@ -76,15 +86,9 @@ public:
return DbgExtensionPtr( new DbgExtension( m_client, extPath ) ); return DbgExtensionPtr( new DbgExtension( m_client, extPath ) );
} }
ULONG64 addr64( ULONG64 addr ); std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
DbgOut dout() { std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
return DbgOut( m_client );
}
DbgIn din() {
return DbgIn( m_client );
}
void dprint( const std::wstring &str, bool dml = false ); void dprint( const std::wstring &str, bool dml = false );
@ -94,10 +98,14 @@ public:
void eprintln( const std::wstring &str ); void eprintln( const std::wstring &str );
void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
void setExecutionStatus( ULONG status ); void setExecutionStatus( ULONG status );
void waitForEvent(); void waitForEvent();
void writeMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
public: public:
CComPtr<IDebugClient4>& CComPtr<IDebugClient4>&
@ -115,6 +123,12 @@ public:
return m_control; return m_control;
} }
PyThreadStateSaver&
getThreadState() {
return m_pyThreadState;
}
private: private:
DebugClient( IDebugClient4 *client ) : DbgObject( client ) {} DebugClient( IDebugClient4 *client ) : DbgObject( client ) {}

View File

@ -1,24 +1,34 @@
#include "stdafx.h" #include "stdafx.h"
#include "dbgexcept.h" #include "dbgexcept.h"
using namespace pykd; namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
PyObject *DbgException::baseExceptTypeObject = NULL; PyObject *DbgException::baseExceptTypeObject = NULL;
PyObject *MemoryException::memoryExceptionTypeObject = NULL;
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void DbgException::exceptionTranslate( const DbgException &e ) void DbgException::exceptionTranslate( const DbgException &e )
{ {
boost::python::object pyExcept(e); python::object pyExcept(e);
PyErr_SetObject( baseExceptTypeObject, pyExcept.ptr() ); PyErr_SetObject( baseExceptTypeObject, pyExcept.ptr() );
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void MemoryException::exceptionTranslate( const MemoryException &e )
{
python::object pyExcept(e);
PyErr_SetObject( memoryExceptionTypeObject, pyExcept.ptr() );
}
/////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd

View File

@ -35,6 +35,59 @@ private:
static PyObject *baseExceptTypeObject; static PyObject *baseExceptTypeObject;
}; };
///////////////////////////////////////////////////////////////////////////////////
class MemoryException : public DbgException
{
public:
MemoryException( ULONG64 targetAddr, bool phyAddr = false ) :
m_targetAddress( targetAddr ),
DbgException( MemoryException::DescMaker( targetAddr, phyAddr ).desc() )
{}
static
void
exceptionTranslate( const MemoryException &e );
static void setTypeObject(PyObject *p) {
memoryExceptionTypeObject = p;
}
ULONG64
getAddress() const {
return m_targetAddress;
}
private:
ULONG64 m_targetAddress;
static PyObject *memoryExceptionTypeObject;
class DescMaker {
public:
DescMaker( ULONG64 addr, bool phyAddr )
{
std::stringstream sstr;
if ( phyAddr )
sstr << "Memory exception at 0x" << std::hex << addr << " target physical address";
else
sstr << "Memory exception at 0x" << std::hex << addr << " target virtual address";
m_desc = sstr.str();
}
const std::string&
desc() const {
return m_desc;
}
private:
std::string m_desc;
};
};
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd }; // namespace pykd

View File

@ -15,6 +15,7 @@
#include "dbgevent.h" #include "dbgevent.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h" #include "typedvar.h"
#include "dbgmem.h"
using namespace pykd; using namespace pykd;
@ -51,8 +52,15 @@ static python::dict genDict(const pyDia::Symbol::ValueNameEntry srcValues[], siz
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, dprint, 1, 2 ) BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, dprint, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 ) BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadChars_, loadChars, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadWChars_, loadWChars, 2, 3 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
#define DEF_PY_CONST_ULONG(x) \ #define DEF_PY_CONST_ULONG(x) \
python::scope().attr(#x) = ULONG(##x) python::scope().attr(#x) = ULONG(##x)
@ -80,6 +88,10 @@ BOOST_PYTHON_MODULE( pykd )
"Check if it is a dump analyzing ( not living debuggee )" ) "Check if it is a dump analyzing ( not living debuggee )" )
.def( "isKernelDebugging", &pykd::DebugClient::isKernelDebugging, .def( "isKernelDebugging", &pykd::DebugClient::isKernelDebugging,
"Check if kernel dubugging is running" ) "Check if kernel dubugging is running" )
.def( "loadChars", &pykd::DebugClient::loadChars, DebugClient_loadChars( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) )
.def( "loadWChars", &pykd::DebugClient::loadWChars, DebugClient_loadWChars( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) )
.def ( "loadExt", &pykd::DebugClient::loadExtension, .def ( "loadExt", &pykd::DebugClient::loadExtension,
"Load a debuger extension" ) "Load a debuger extension" )
.def( "loadModule", &pykd::DebugClient::loadModule, .def( "loadModule", &pykd::DebugClient::loadModule,
@ -123,6 +135,10 @@ BOOST_PYTHON_MODULE( pykd )
"Check if it is a dump analyzing ( not living debuggee )" ); "Check if it is a dump analyzing ( not living debuggee )" );
python::def( "isKernelDebugging", &pykd::isKernelDebugging, python::def( "isKernelDebugging", &pykd::isKernelDebugging,
"Check if kernel dubugging is running" ); "Check if kernel dubugging is running" );
python::def( "loadChars", &loadChars, loadChars_( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) );
python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) );
python::def( "loadExt", &pykd::loadExtension, python::def( "loadExt", &pykd::loadExtension,
"Load a debuger extension" ); "Load a debuger extension" );
python::def( "loadModule", &pykd::loadModule, python::def( "loadModule", &pykd::loadModule,
@ -205,7 +221,7 @@ BOOST_PYTHON_MODULE( pykd )
python::class_<EventHandlerWrap, boost::noncopyable>( python::class_<EventHandlerWrap, boost::noncopyable>(
"eventHandler", "Base class for overriding and handling debug notifications" ) "eventHandler", "Base class for overriding and handling debug notifications" )
.def( python::init<>() ) .def( python::init<>() )
.def( python::init<DebugClient&>() ) .def( python::init<DebugClientPtr&>() )
.def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint, .def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint,
"Triggered breakpoint event. Parameter is dict:\n" "Triggered breakpoint event. Parameter is dict:\n"
"{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int," "{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int,"
@ -396,7 +412,7 @@ BOOST_PYTHON_MODULE( pykd )
"Get exception description" ) "Get exception description" )
.def( "__str__", &pykd::DbgException::print); .def( "__str__", &pykd::DbgException::print);
pykd::DbgException::setTypeObject( dbgExceptionClass.ptr() ); pykd::DbgException::setTypeObject( dbgExceptionClass.ptr() );
boost::python::register_exception_translator<pykd::DbgException>( python::register_exception_translator<pykd::DbgException>(
&pykd::DbgException::exceptionTranslate ); &pykd::DbgException::exceptionTranslate );
// DIA exceptions // DIA exceptions
@ -406,9 +422,18 @@ BOOST_PYTHON_MODULE( pykd )
diaException diaException
.def( "hres", &pyDia::Exception::getRes ); .def( "hres", &pyDia::Exception::getRes );
pyDia::Exception::setTypeObject( diaException.ptr() ); pyDia::Exception::setTypeObject( diaException.ptr() );
boost::python::register_exception_translator<pyDia::Exception>( python::register_exception_translator<pyDia::Exception>(
&pyDia::Exception::exceptionTranslate ); &pyDia::Exception::exceptionTranslate );
// Memory exception
python::class_<pykd::MemoryException, python::bases<DbgException> > memException(
"MemoryException", "Target memory access exception class",
python::no_init );
memException.def( "getAddress", &pykd::MemoryException::getAddress, "Return a target address where the exception occurs" );
pykd::MemoryException::setTypeObject( memException.ptr() );
python::register_exception_translator<pykd::MemoryException>(
&pykd::MemoryException::exceptionTranslate );
DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED ); DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED );
DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL ); DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL );
DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS ); DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS );

View File

@ -42,6 +42,68 @@ addr64( ULONG64 addr)
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
void DebugClient::readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
{
HRESULT hres;
if ( phyAddr == false )
{
hres = m_dataSpaces->ReadVirtual( address, buffer, length, NULL );
}
else
{
hres = m_dataSpaces->ReadPhysical( address, buffer, length, NULL );
}
if ( FAILED( hres ) )
throw MemoryException( address, phyAddr );
}
void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
{
return g_dbgClient->readMemory( address, buffer, length, phyAddr );
}
/////////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::loadChars( ULONG64 address, ULONG number, bool phyAddr )
{
std::vector<char> buffer(number);
ULONG bufferSize = sizeof(std::vector<char>::value_type)*buffer.size();
if (number)
readMemory( address, &buffer[0], bufferSize, phyAddr );
return std::string( buffer.begin(), buffer.end() );
}
std::string loadChars( ULONG64 address, ULONG number, bool phyAddr )
{
return g_dbgClient->loadChars( address, number, phyAddr );
}
/////////////////////////////////////////////////////////////////////////////////////
std::wstring DebugClient::loadWChars( ULONG64 address, ULONG number, bool phyAddr )
{
std::vector<wchar_t> buffer(number);
ULONG bufferSize = sizeof(std::vector<wchar_t>::value_type)*buffer.size();
if (number)
readMemory( address, &buffer[0], bufferSize, phyAddr );
return std::wstring( buffer.begin(), buffer.end() );
}
std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr )
{
return g_dbgClient->loadWChars( address, number, phyAddr );
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end of pykd }; // end of pykd
@ -49,6 +111,28 @@ addr64( ULONG64 addr)
//#include <boost/scoped_array.hpp> //#include <boost/scoped_array.hpp>
// //
//#include "dbgext.h" //#include "dbgext.h"

View File

@ -9,6 +9,20 @@ addr64( ULONG64 addr );
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void
readMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE );
void
writeMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE );
///////////////////////////////////////////////////////////////////////////////////
std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
///////////////////////////////////////////////////////////////////////////////////
}; };
@ -16,6 +30,9 @@ addr64( ULONG64 addr );
//#include <boost/scoped_array.hpp> //#include <boost/scoped_array.hpp>
// //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,10 @@ protected:
hres = client->QueryInterface( __uuidof(IDebugAdvanced2), (void**)&m_advanced ); hres = client->QueryInterface( __uuidof(IDebugAdvanced2), (void**)&m_advanced );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException("QueryInterface IDebugAdvanced2 failed"); throw DbgException("QueryInterface IDebugAdvanced2 failed");
hres = client->QueryInterface( __uuidof(IDebugDataSpaces), (void**)&m_dataSpaces );
if ( FAILED( hres ) )
throw DbgException("QueryInterface IDebugDataSpaces failed");
} }
virtual ~DbgObject() {}; virtual ~DbgObject() {};
@ -40,6 +44,8 @@ protected:
CComPtr<IDebugControl4> m_control; CComPtr<IDebugControl4> m_control;
CComPtr<IDebugSymbols3> m_symbols; CComPtr<IDebugSymbols3> m_symbols;
CComPtr<IDebugAdvanced2> m_advanced; CComPtr<IDebugAdvanced2> m_advanced;
CComPtr<IDebugDataSpaces> m_dataSpaces;
}; };

View File

@ -20,6 +20,7 @@ import dbgcmd
import clienttest import clienttest
import eventtest import eventtest
import typedvar import typedvar
import memtest
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -31,7 +32,8 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ), unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ),
unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ), unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ),
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ) unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ),
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest )
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )

View File

@ -53,6 +53,9 @@ structTest g_testArray[2] = { { 0, 500, true, 1 }, { 2, 1500, false, 1 } };
structTest *g_structTestPtr = &g_structTest; structTest *g_structTestPtr = &g_structTest;
structTest **g_structTestPtrPtr = &g_structTestPtr; structTest **g_structTestPtrPtr = &g_structTestPtr;
char helloStr[] = "Hello";
wchar_t helloWStr[] = L"Hello";
class classChild : public classBase { class classChild : public classBase {
public: public:
int m_childField; int m_childField;
@ -87,6 +90,9 @@ void FuncWithName0()
std::cout << g_testArray[1].m_field3; std::cout << g_testArray[1].m_field3;
std::cout << g_structTestPtr->m_field3; std::cout << g_structTestPtr->m_field3;
std::cout << (*g_structTestPtrPtr)->m_field3; std::cout << (*g_structTestPtrPtr)->m_field3;
std::cout << helloStr;
std::wcout << helloWStr;
} }
void FuncWithName1(int a) void FuncWithName1(int a)

View File

@ -420,6 +420,10 @@
RelativePath="..\scripts\eventtest.py" RelativePath="..\scripts\eventtest.py"
> >
</File> </File>
<File
RelativePath="..\scripts\memtest.py"
>
</File>
<File <File
RelativePath="..\scripts\moduletest.py" RelativePath="..\scripts\moduletest.py"
> >