mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[pykd] added: typeInfo class
[pykd] added: typeException, memoryException and their translation into python git-svn-id: https://pykd.svn.codeplex.com/svn@65714 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
6e2d161966
commit
9a0d80eb23
135
pykd/dbgcmd.cpp
135
pykd/dbgcmd.cpp
@ -122,141 +122,6 @@ dbgExtensionClass::print() const
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
dbgBreakpointClass::breakpointMap dbgBreakpointClass::m_breakMap;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
|
|
||||||
breakpointMap::iterator it = m_breakMap.find( bp );
|
|
||||||
if ( it != m_breakMap.end() )
|
|
||||||
return boost::python::extract<HRESULT>( it->second->m_callback() );
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset, boost::python::object &callback )
|
|
||||||
{
|
|
||||||
m_offset = offset;
|
|
||||||
m_breakpoint = NULL;
|
|
||||||
m_callback = callback;
|
|
||||||
|
|
||||||
set();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
dbgBreakpointClass::~dbgBreakpointClass()
|
|
||||||
{
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool
|
|
||||||
dbgBreakpointClass::set()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if ( m_breakpoint )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
hres = dbgExt->control->AddBreakpoint( DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &m_breakpoint );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::AddBreakpoint failed" );
|
|
||||||
|
|
||||||
hres = m_breakpoint->SetOffset( m_offset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugBreakpoint::SetOffset failed" );
|
|
||||||
|
|
||||||
hres = m_breakpoint->SetFlags( DEBUG_BREAKPOINT_ENABLED );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugBreakpoint::SetFlags failed" );
|
|
||||||
|
|
||||||
m_breakMap.insert( std::make_pair( m_breakpoint, this ) );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
remove();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void
|
|
||||||
dbgBreakpointClass::remove()
|
|
||||||
{
|
|
||||||
if ( m_breakpoint )
|
|
||||||
{
|
|
||||||
dbgExt->control->RemoveBreakpoint( m_breakpoint );
|
|
||||||
|
|
||||||
breakpointMap::iterator bp = m_breakMap.find( m_breakpoint );
|
|
||||||
if ( bp != m_breakMap.end() )
|
|
||||||
m_breakMap.erase( bp );
|
|
||||||
|
|
||||||
m_breakpoint = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string
|
|
||||||
dbgBreakpointClass::print() const
|
|
||||||
{
|
|
||||||
HRESULT status = S_OK;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!m_breakpoint)
|
|
||||||
return "not set";
|
|
||||||
|
|
||||||
DEBUG_BREAKPOINT_PARAMETERS params;
|
|
||||||
status = m_breakpoint->GetParameters(¶ms);
|
|
||||||
if (FAILED(status))
|
|
||||||
throw DbgException("IDebugBreakpoint::GetParameters failed");
|
|
||||||
|
|
||||||
boost::format fmt("%1$2d %2%%3% %4%:*** ");
|
|
||||||
fmt % params.Id
|
|
||||||
% (params.Flags & DEBUG_BREAKPOINT_ENABLED ? 'e' : 'd')
|
|
||||||
% 'u'
|
|
||||||
% params.CurrentPassCount;
|
|
||||||
|
|
||||||
return fmt.str();
|
|
||||||
}
|
|
||||||
catch (std::exception & e)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
evaluate( const std::string &expression )
|
evaluate( const std::string &expression )
|
||||||
{
|
{
|
||||||
|
@ -79,43 +79,6 @@ private:
|
|||||||
std::string m_path;
|
std::string m_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class dbgBreakpointClass {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
|
||||||
|
|
||||||
~dbgBreakpointClass();
|
|
||||||
|
|
||||||
bool
|
|
||||||
set();
|
|
||||||
|
|
||||||
void
|
|
||||||
remove();
|
|
||||||
|
|
||||||
std::string
|
|
||||||
print() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
ULONG64 m_offset;
|
|
||||||
|
|
||||||
IDebugBreakpoint *m_breakpoint;
|
|
||||||
|
|
||||||
boost::python::object m_callback;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef std::map<IDebugBreakpoint*, dbgBreakpointClass*> breakpointMap;
|
|
||||||
static breakpointMap m_breakMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static HRESULT onBreakpointEvnet( IDebugBreakpoint* bp );
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "dbgmodule.h"
|
#include "dbgmodule.h"
|
||||||
#include "dbgsynsym.h"
|
#include "dbgsynsym.h"
|
||||||
#include "dbgcmd.h"
|
#include "dbgbreak.h"
|
||||||
#include "dbgmodevent.h"
|
#include "dbgmodevent.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
108
pykd/dbgexcept.h
108
pykd/dbgexcept.h
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -8,9 +9,112 @@ class DbgException : public std::exception
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DbgException( const char* desc ) :
|
DbgException( const std::string &desc ) :
|
||||||
std::exception( desc )
|
std::exception( desc.c_str() )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
const char* getDesc() const {
|
||||||
|
return what();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
exceptionTranslate(const DbgException &e );
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TypeException : public DbgException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeException() :
|
||||||
|
DbgException( "type operation invalid" )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypeException( const std::string &desc ) :
|
||||||
|
DbgException( desc )
|
||||||
|
{}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
exceptionTranslate(const TypeException &e );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class IndexException : public DbgException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
IndexException() :
|
||||||
|
DbgException( "Index out of range" )
|
||||||
|
{}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
translate(const IndexException &e ) {
|
||||||
|
PyErr_SetString(PyExc_IndexError, "Index out of range");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class MemoryException : public DbgException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MemoryException( ULONG64 targetAddr ) :
|
||||||
|
m_targetAddress( targetAddr ),
|
||||||
|
DbgException( MemoryException::DescMaker( targetAddr, false ).desc() )
|
||||||
|
{}
|
||||||
|
|
||||||
|
MemoryException( ULONG64 targetAddr, bool phyAddr ) :
|
||||||
|
m_targetAddress( targetAddr ),
|
||||||
|
DbgException( MemoryException::DescMaker( targetAddr, phyAddr ).desc() )
|
||||||
|
{}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
translate( const MemoryException &e );
|
||||||
|
|
||||||
|
ULONG64
|
||||||
|
getAddress() const {
|
||||||
|
return m_targetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ULONG64 m_targetAddress;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
extern PyObject *baseExceptionType;
|
||||||
|
extern PyObject *typeExceptionType;
|
||||||
|
extern PyObject *memoryExceptionType;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
218
pykd/dbgext.cpp
218
pykd/dbgext.cpp
@ -29,6 +29,7 @@
|
|||||||
#include "dbgsynsym.h"
|
#include "dbgsynsym.h"
|
||||||
#include "dbgclient.h"
|
#include "dbgclient.h"
|
||||||
#include "dbgmodevent.h"
|
#include "dbgmodevent.h"
|
||||||
|
#include "dbgbreak.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -56,9 +57,17 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords, loadArray<__int64>, 2, 3 )
|
|||||||
|
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemoryOver, compareMemory, 3, 4 )
|
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemoryOver, compareMemory, 3, 4 )
|
||||||
|
|
||||||
#define _DEF_PY_CONST(x) \
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( appendOver, TypeInfo::appendField, 2, 3 )
|
||||||
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( loadOver, TypeInfo::loadVar, 1, 2 )
|
||||||
|
|
||||||
|
|
||||||
|
#define DEF_PY_CONST(x) \
|
||||||
boost::python::scope().attr(#x) = ##x
|
boost::python::scope().attr(#x) = ##x
|
||||||
|
|
||||||
|
#define DEF_PY_GLOBAL(x,y) \
|
||||||
|
boost::python::scope().attr(x) = ##y
|
||||||
|
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE( pykd )
|
BOOST_PYTHON_MODULE( pykd )
|
||||||
{
|
{
|
||||||
boost::python::def( "go", &setExecutionStatus<DEBUG_STATUS_GO>,
|
boost::python::def( "go", &setExecutionStatus<DEBUG_STATUS_GO>,
|
||||||
@ -80,7 +89,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
boost::python::def( "loadDump", &dbgLoadDump,
|
boost::python::def( "loadDump", &dbgLoadDump,
|
||||||
"Load crash dump (only for console)");
|
"Load crash dump (only for console)");
|
||||||
boost::python::def( "startProcess", &startProcess,
|
boost::python::def( "startProcess", &startProcess,
|
||||||
"Start process for debugging(only for console)");
|
"Start process for debugging (only for console)");
|
||||||
boost::python::def( "dbgCommand", &dbgCommand,
|
boost::python::def( "dbgCommand", &dbgCommand,
|
||||||
"Execute debugger command. For example: dbgCommand( \"lmvm nt\" )" );
|
"Execute debugger command. For example: dbgCommand( \"lmvm nt\" )" );
|
||||||
boost::python::def( "isValid", &isOffsetValid,
|
boost::python::def( "isValid", &isOffsetValid,
|
||||||
@ -95,8 +104,6 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Return pointer size ( in bytes )" );
|
"Return pointer size ( in bytes )" );
|
||||||
boost::python::def( "reg", &loadRegister,
|
boost::python::def( "reg", &loadRegister,
|
||||||
"Return CPU's register value" );
|
"Return CPU's register value" );
|
||||||
boost::python::def( "typedVar", &loadTypedVar,
|
|
||||||
"Return instance of the typedVarClass. It's values are loaded from the target memory" );
|
|
||||||
boost::python::def( "typedVarList", &loadTypedVarList,
|
boost::python::def( "typedVarList", &loadTypedVarList,
|
||||||
"Return list of typedVarClass instances. Each item represents one item of the linked list in the target memory" );
|
"Return list of typedVarClass instances. Each item represents one item of the linked list in the target memory" );
|
||||||
boost::python::def( "typedVarArray", &loadTypedVarArray,
|
boost::python::def( "typedVarArray", &loadTypedVarArray,
|
||||||
@ -104,8 +111,6 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
boost::python::def( "containingRecord", &containingRecord,
|
boost::python::def( "containingRecord", &containingRecord,
|
||||||
"Return instance of the typedVarClass. It's value are loaded from the target memory."
|
"Return instance of the typedVarClass. It's value are loaded from the target memory."
|
||||||
"The start address is calculated by the same method as standard macro CONTAINING_RECORD" );
|
"The start address is calculated by the same method as standard macro CONTAINING_RECORD" );
|
||||||
boost::python::def( "getTypeClass", &getTypeClass,
|
|
||||||
"Return instance of the typeClass with information about type" );
|
|
||||||
boost::python::def( "sizeof", &sizeofType,
|
boost::python::def( "sizeof", &sizeofType,
|
||||||
"Return size of type" );
|
"Return size of type" );
|
||||||
boost::python::def( "loadModule", &loadModule,
|
boost::python::def( "loadModule", &loadModule,
|
||||||
@ -205,19 +210,54 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
boost::python::def( "delSynSymbolsMask", &delSyntheticSymbolsMask,
|
boost::python::def( "delSynSymbolsMask", &delSyntheticSymbolsMask,
|
||||||
"Delete synthetic symbols by mask of module and symbol name");
|
"Delete synthetic symbols by mask of module and symbol name");
|
||||||
|
|
||||||
boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass",
|
boost::python::class_<TypeInfo>( "typeInfo",
|
||||||
"Class representing non-primitive type info: structure, union, etc. attributes is a fields of non-primitive type" )
|
"Class representing non-primitive type info: structure, union, etc. attributes is a fields of non-primitive type" )
|
||||||
.def("sizeof", &typeClass::size,
|
.def(boost::python::init<std::string,std::string>( boost::python::args("module", "type"), "constructor" ) )
|
||||||
|
.def(boost::python::init<std::string>( boost::python::args("typeName"), "constructor" ) )
|
||||||
|
.def(boost::python::init<std::string,ULONG>( boost::python::args("typeName", "align"), "constructor" ) )
|
||||||
|
.def("size", &TypeInfo::size,
|
||||||
"Return full size of non-primitive type" )
|
"Return full size of non-primitive type" )
|
||||||
.def("offset", &typeClass::getOffset,
|
.def("name", &TypeInfo::name,
|
||||||
"Return offset as field of parent" )
|
"Return type's name" )
|
||||||
.def("__str__", &typeClass::print,
|
.def("__str__", &TypeInfo::print,
|
||||||
"Return a nice string represention: print names and offsets of fields");
|
"Return a nice string represention: print names and offsets of fields" )
|
||||||
|
.def("__getattr__", &TypeInfo::getField )
|
||||||
|
.def("__len__", &TypeInfo::getFieldCount )
|
||||||
|
.def("__getitem__", &TypeInfo::getFieldByIndex )
|
||||||
|
.def("append", &TypeInfo::appendField, appendOver( boost::python::args("type", "fieldName", "count"),
|
||||||
|
"add new field for typeInfo" ) )
|
||||||
|
.def("offset", &TypeInfo::getFieldOffset,
|
||||||
|
"Return offset while type is part of the more complex type" )
|
||||||
|
.def("load", &TypeInfo::loadVar, loadOver( boost::python::args( "offset", "count"),
|
||||||
|
"Create instance of the typedVar class with this typeInfo" ) );
|
||||||
|
|
||||||
boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass",
|
DEF_PY_GLOBAL( "char_t", TypeInfo("", "char") );
|
||||||
|
DEF_PY_GLOBAL( "uchar_t", TypeInfo("", "unsigned char") );
|
||||||
|
DEF_PY_GLOBAL( "short_t", TypeInfo("", "short") );
|
||||||
|
DEF_PY_GLOBAL( "ushort_t", TypeInfo("", "unsigned short") );
|
||||||
|
DEF_PY_GLOBAL( "long_t", TypeInfo("", "long") );
|
||||||
|
DEF_PY_GLOBAL( "ulong_t", TypeInfo("", "unsigned long") );
|
||||||
|
DEF_PY_GLOBAL( "int_t", TypeInfo("", "int") );
|
||||||
|
DEF_PY_GLOBAL( "uint_t", TypeInfo("", "unsigned int") );
|
||||||
|
DEF_PY_GLOBAL( "ptr_t", TypeInfo("", "viod*") );
|
||||||
|
DEF_PY_GLOBAL( "double_t", TypeInfo("", "double") );
|
||||||
|
DEF_PY_GLOBAL( "longlong_t", TypeInfo("", "int64") );
|
||||||
|
DEF_PY_GLOBAL( "ulonglong_t", TypeInfo("", "unsigned int64") );
|
||||||
|
|
||||||
|
boost::python::class_<TypedVar>( "typedVar",
|
||||||
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance" )
|
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance" )
|
||||||
.def("getAddress", &typedVarClass::getAddress,
|
.def(boost::python::init<TypeInfo,ULONG64>(boost::python::args("typeInfo", "address"),
|
||||||
"Return virtual address" );
|
"constructor" ) )
|
||||||
|
.def(boost::python::init<std::string,std::string,ULONG64>(boost::python::args("moduleName", "typeName", "address"),
|
||||||
|
"constructor" ) )
|
||||||
|
.def("getAddress", &TypedVar::getAddress,
|
||||||
|
"Return virtual address" )
|
||||||
|
.def("sizeof", &TypedVar::getSize,
|
||||||
|
"Return size of a variable in the target memory" )
|
||||||
|
.def("__getattr__", &TypedVar::getFieldWrap,
|
||||||
|
"Return field of structure as a object attribute" )
|
||||||
|
.def("__str__", &TypedVar::print,
|
||||||
|
"Return a nice string represention: print names and offsets of fields" );
|
||||||
|
|
||||||
boost::python::class_<dbgModuleClass>( "dbgModuleClass",
|
boost::python::class_<dbgModuleClass>( "dbgModuleClass",
|
||||||
"Class representing module in the target memory" )
|
"Class representing module in the target memory" )
|
||||||
@ -259,6 +299,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Call extension command" )
|
"Call extension command" )
|
||||||
.def("__str__", &dbgExtensionClass::print,
|
.def("__str__", &dbgExtensionClass::print,
|
||||||
"Return a nice string represention of the dbgExtensionClass" );
|
"Return a nice string represention of the dbgExtensionClass" );
|
||||||
|
|
||||||
boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass",
|
boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass",
|
||||||
"Class representing a frame of the call satck" )
|
"Class representing a frame of the call satck" )
|
||||||
.def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset,
|
.def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset,
|
||||||
@ -273,10 +314,13 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Return a frame's number" )
|
"Return a frame's number" )
|
||||||
.def( "__str__", &dbgStackFrameClass::print,
|
.def( "__str__", &dbgStackFrameClass::print,
|
||||||
"Return a nice string represention of the dbgStackFrameClass" );
|
"Return a nice string represention of the dbgStackFrameClass" );
|
||||||
|
|
||||||
boost::python::class_<dbgOut>( "windbgOut", "windbgOut" )
|
boost::python::class_<dbgOut>( "windbgOut", "windbgOut" )
|
||||||
.def( "write", &dbgOut::write );
|
.def( "write", &dbgOut::write );
|
||||||
|
|
||||||
boost::python::class_<dbgIn>( "windbgIn", "windbgIn" )
|
boost::python::class_<dbgIn>( "windbgIn", "windbgIn" )
|
||||||
.def( "readline", &dbgIn::readline );
|
.def( "readline", &dbgIn::readline );
|
||||||
|
|
||||||
boost::python::class_<dbgBreakpointClass>( "bp",
|
boost::python::class_<dbgBreakpointClass>( "bp",
|
||||||
"Class representing breakpoint",
|
"Class representing breakpoint",
|
||||||
boost::python::init<ULONG64,boost::python::object&>( boost::python::args("offset", "callback"),
|
boost::python::init<ULONG64,boost::python::object&>( boost::python::args("offset", "callback"),
|
||||||
@ -297,62 +341,96 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Unload module event. Parameter is instance of dbgModuleClass. "
|
"Unload module event. Parameter is instance of dbgModuleClass. "
|
||||||
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
|
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
|
||||||
|
|
||||||
|
// èñêëþ÷åíèÿ
|
||||||
|
boost::python::class_<DbgException> dbgExceptionClass( "BaseException",
|
||||||
|
"Pykd base exception class",
|
||||||
|
boost::python::no_init );
|
||||||
|
//boost::python::init<std::string>() );
|
||||||
|
|
||||||
|
dbgExceptionClass
|
||||||
|
.def( boost::python::init<std::string>( boost::python::args("desc"), "constructor" ) )
|
||||||
|
.def( "desc", &DbgException::getDesc,
|
||||||
|
"Get exception description" );
|
||||||
|
|
||||||
|
boost::python::class_<TypeException, boost::python::bases<DbgException> > typeExceptionClass( "TypeException",
|
||||||
|
"Type exception class",
|
||||||
|
boost::python::no_init );
|
||||||
|
|
||||||
|
boost::python::class_<MemoryException, boost::python::bases<DbgException> > memoryExceptionClass( "MemoryException",
|
||||||
|
"Memory exception class",
|
||||||
|
boost::python::no_init );
|
||||||
|
|
||||||
|
memoryExceptionClass
|
||||||
|
.def( boost::python::init<ULONG64>( boost::python::args("targetAddress"), "constructor" ) )
|
||||||
|
.def( "getAddress", &MemoryException::getAddress,
|
||||||
|
"Return target address" );
|
||||||
|
|
||||||
|
baseExceptionType = dbgExceptionClass.ptr();
|
||||||
|
typeExceptionType = typeExceptionClass.ptr();
|
||||||
|
memoryExceptionType = memoryExceptionClass.ptr();
|
||||||
|
|
||||||
|
boost::python::register_exception_translator<DbgException>( &DbgException::exceptionTranslate );
|
||||||
|
boost::python::register_exception_translator<TypeException>( &TypeException::exceptionTranslate );
|
||||||
|
boost::python::register_exception_translator<IndexException>( &IndexException::translate);
|
||||||
|
boost::python::register_exception_translator<MemoryException>( &MemoryException::translate );
|
||||||
|
|
||||||
|
|
||||||
// debug status
|
// debug status
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_NO_CHANGE);
|
DEF_PY_CONST(DEBUG_STATUS_NO_CHANGE);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_GO);
|
DEF_PY_CONST(DEBUG_STATUS_GO);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_GO_HANDLED);
|
DEF_PY_CONST(DEBUG_STATUS_GO_HANDLED);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_GO_NOT_HANDLED);
|
DEF_PY_CONST(DEBUG_STATUS_GO_NOT_HANDLED);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_STEP_OVER);
|
DEF_PY_CONST(DEBUG_STATUS_STEP_OVER);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_STEP_INTO);
|
DEF_PY_CONST(DEBUG_STATUS_STEP_INTO);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_BREAK);
|
DEF_PY_CONST(DEBUG_STATUS_BREAK);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_NO_DEBUGGEE);
|
DEF_PY_CONST(DEBUG_STATUS_NO_DEBUGGEE);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_STEP_BRANCH);
|
DEF_PY_CONST(DEBUG_STATUS_STEP_BRANCH);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_IGNORE_EVENT);
|
DEF_PY_CONST(DEBUG_STATUS_IGNORE_EVENT);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_RESTART_REQUESTED);
|
DEF_PY_CONST(DEBUG_STATUS_RESTART_REQUESTED);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_REVERSE_GO);
|
DEF_PY_CONST(DEBUG_STATUS_REVERSE_GO);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_BRANCH);
|
DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_BRANCH);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_OVER);
|
DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_OVER);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_INTO);
|
DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_INTO);
|
||||||
|
|
||||||
// debug status additional mask
|
// debug status additional mask
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_INSIDE_WAIT);
|
DEF_PY_CONST(DEBUG_STATUS_INSIDE_WAIT);
|
||||||
_DEF_PY_CONST(DEBUG_STATUS_WAIT_TIMEOUT);
|
DEF_PY_CONST(DEBUG_STATUS_WAIT_TIMEOUT);
|
||||||
|
|
||||||
// break point type
|
// break point type
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_CODE);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_CODE);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_DATA);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_DATA);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_TIME);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_TIME);
|
||||||
|
|
||||||
// break point flag
|
// break point flag
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_GO_ONLY);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_GO_ONLY);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_DEFERRED);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_DEFERRED);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_ENABLED);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_ENABLED);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_ADDER_ONLY);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_ADDER_ONLY);
|
||||||
_DEF_PY_CONST(DEBUG_BREAKPOINT_ONE_SHOT);
|
DEF_PY_CONST(DEBUG_BREAKPOINT_ONE_SHOT);
|
||||||
|
|
||||||
// break point access type
|
// break point access type
|
||||||
_DEF_PY_CONST(DEBUG_BREAK_READ);
|
DEF_PY_CONST(DEBUG_BREAK_READ);
|
||||||
_DEF_PY_CONST(DEBUG_BREAK_WRITE);
|
DEF_PY_CONST(DEBUG_BREAK_WRITE);
|
||||||
_DEF_PY_CONST(DEBUG_BREAK_EXECUTE);
|
DEF_PY_CONST(DEBUG_BREAK_EXECUTE);
|
||||||
_DEF_PY_CONST(DEBUG_BREAK_IO);
|
DEF_PY_CONST(DEBUG_BREAK_IO);
|
||||||
|
|
||||||
// exception flags
|
// exception flags
|
||||||
_DEF_PY_CONST(EXCEPTION_NONCONTINUABLE);
|
DEF_PY_CONST(EXCEPTION_NONCONTINUABLE);
|
||||||
|
|
||||||
// debug events
|
// debug events
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_BREAKPOINT);
|
DEF_PY_CONST(DEBUG_EVENT_BREAKPOINT);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_EXCEPTION);
|
DEF_PY_CONST(DEBUG_EVENT_EXCEPTION);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_CREATE_THREAD);
|
DEF_PY_CONST(DEBUG_EVENT_CREATE_THREAD);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_EXIT_THREAD);
|
DEF_PY_CONST(DEBUG_EVENT_EXIT_THREAD);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_CREATE_PROCESS);
|
DEF_PY_CONST(DEBUG_EVENT_CREATE_PROCESS);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_EXIT_PROCESS);
|
DEF_PY_CONST(DEBUG_EVENT_EXIT_PROCESS);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_LOAD_MODULE);
|
DEF_PY_CONST(DEBUG_EVENT_LOAD_MODULE);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_UNLOAD_MODULE);
|
DEF_PY_CONST(DEBUG_EVENT_UNLOAD_MODULE);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_SYSTEM_ERROR);
|
DEF_PY_CONST(DEBUG_EVENT_SYSTEM_ERROR);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_SESSION_STATUS);
|
DEF_PY_CONST(DEBUG_EVENT_SESSION_STATUS);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_CHANGE_DEBUGGEE_STATE);
|
DEF_PY_CONST(DEBUG_EVENT_CHANGE_DEBUGGEE_STATE);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_CHANGE_ENGINE_STATE);
|
DEF_PY_CONST(DEBUG_EVENT_CHANGE_ENGINE_STATE);
|
||||||
_DEF_PY_CONST(DEBUG_EVENT_CHANGE_SYMBOL_STATE);
|
DEF_PY_CONST(DEBUG_EVENT_CHANGE_SYMBOL_STATE);
|
||||||
|
|
||||||
// debugger type
|
// debugger type
|
||||||
//_DEF_PY_CONST(DEBUG_CLASS_UNINITIALIZED);
|
//_DEF_PY_CONST(DEBUG_CLASS_UNINITIALIZED);
|
||||||
@ -424,10 +502,25 @@ private:
|
|||||||
|
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
|
|
||||||
boost::python::import( "pykd" );
|
|
||||||
|
|
||||||
main = boost::python::import("__main__");
|
main = boost::python::import("__main__");
|
||||||
|
|
||||||
|
boost::python::object main_namespace = main.attr("__dict__");
|
||||||
|
|
||||||
|
|
||||||
|
// äåëàåì àíàëîã from pykd import *
|
||||||
|
boost::python::object pykd = boost::python::import( "pykd" );
|
||||||
|
|
||||||
|
boost::python::dict pykd_namespace( pykd.attr("__dict__") );
|
||||||
|
|
||||||
|
boost::python::list iterkeys( pykd_namespace.iterkeys() );
|
||||||
|
|
||||||
|
for (int i = 0; i < boost::python::len(iterkeys); i++)
|
||||||
|
{
|
||||||
|
std::string key = boost::python::extract<std::string>(iterkeys[i]);
|
||||||
|
|
||||||
|
main_namespace[ key ] = pykd_namespace[ key ];
|
||||||
|
}
|
||||||
|
|
||||||
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
||||||
boost::python::object sys = boost::python::import( "sys");
|
boost::python::object sys = boost::python::import( "sys");
|
||||||
|
|
||||||
@ -492,6 +585,9 @@ DbgExt::DbgExt( IDebugClient4 *masterClient )
|
|||||||
client4 = NULL;
|
client4 = NULL;
|
||||||
masterClient->QueryInterface( __uuidof(IDebugClient4), (void **)&client4 );
|
masterClient->QueryInterface( __uuidof(IDebugClient4), (void **)&client4 );
|
||||||
|
|
||||||
|
client5 = NULL;
|
||||||
|
masterClient->QueryInterface( __uuidof(IDebugClient5), (void **)&client5 );
|
||||||
|
|
||||||
control = NULL;
|
control = NULL;
|
||||||
masterClient->QueryInterface( __uuidof(IDebugControl), (void **)&control );
|
masterClient->QueryInterface( __uuidof(IDebugControl), (void **)&control );
|
||||||
|
|
||||||
@ -747,7 +843,9 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
|||||||
|
|
||||||
if ( !stopInput )
|
if ( !stopInput )
|
||||||
try {
|
try {
|
||||||
|
|
||||||
boost::python::exec( str, WindbgGlobalSession::global(), WindbgGlobalSession::global() );
|
boost::python::exec( str, WindbgGlobalSession::global(), WindbgGlobalSession::global() );
|
||||||
|
|
||||||
}
|
}
|
||||||
catch( boost::python::error_already_set const & )
|
catch( boost::python::error_already_set const & )
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ public:
|
|||||||
|
|
||||||
IDebugClient *client;
|
IDebugClient *client;
|
||||||
IDebugClient4 *client4;
|
IDebugClient4 *client4;
|
||||||
|
IDebugClient5 *client5;
|
||||||
|
|
||||||
IDebugControl *control;
|
IDebugControl *control;
|
||||||
IDebugControl4 *control4;
|
IDebugControl4 *control4;
|
||||||
|
176
pykd/dbgmem.cpp
176
pykd/dbgmem.cpp
@ -13,40 +13,24 @@ using namespace std;
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadMemory( ULONG64 address, PVOID dest, ULONG length, BOOLEAN phyAddr )
|
loadMemory( ULONG64 address, PVOID dest, ULONG length, BOOLEAN phyAddr )
|
||||||
{
|
{
|
||||||
address = addr64( address );
|
address = addr64( address );
|
||||||
|
|
||||||
try {
|
HRESULT hres;
|
||||||
|
|
||||||
if ( phyAddr == FALSE )
|
if ( phyAddr == FALSE )
|
||||||
{
|
{
|
||||||
HRESULT hres = dbgExt->dataSpaces->ReadVirtual( address, dest, length, NULL );
|
hres = dbgExt->dataSpaces->ReadVirtual( address, dest, length, NULL );
|
||||||
if ( FAILED( hres ) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HRESULT hres = dbgExt->dataSpaces->ReadPhysical( address, dest, length, NULL );
|
hres = dbgExt->dataSpaces->ReadPhysical( address, dest, length, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
return false;
|
throw MemoryException( address, !!phyAddr );
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -151,8 +135,8 @@ loadPtrArray( ULONG64 address, ULONG number )
|
|||||||
{
|
{
|
||||||
boost::scoped_array<ULONG64> buffer(new ULONG64[number]);
|
boost::scoped_array<ULONG64> buffer(new ULONG64[number]);
|
||||||
|
|
||||||
if ( loadMemory( address, buffer.get(), number*sizeof(ULONG64) ) )
|
loadMemory( address, buffer.get(), number*sizeof(ULONG64) );
|
||||||
{
|
|
||||||
boost::python::list lst;
|
boost::python::list lst;
|
||||||
|
|
||||||
for ( ULONG i = 0; i < number; ++i )
|
for ( ULONG i = 0; i < number; ++i )
|
||||||
@ -160,15 +144,12 @@ loadPtrArray( ULONG64 address, ULONG number )
|
|||||||
|
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::object();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::scoped_array<ULONG> buffer(new ULONG[number]);
|
boost::scoped_array<ULONG> buffer(new ULONG[number]);
|
||||||
|
|
||||||
if ( loadMemory( address, buffer.get(), number*sizeof(ULONG) ) )
|
loadMemory( address, buffer.get(), number*sizeof(ULONG) );
|
||||||
{
|
|
||||||
boost::python::list lst;
|
boost::python::list lst;
|
||||||
|
|
||||||
for ( ULONG i = 0; i < number; ++i )
|
for ( ULONG i = 0; i < number; ++i )
|
||||||
@ -176,9 +157,6 @@ loadPtrArray( ULONG64 address, ULONG number )
|
|||||||
|
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::object();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -188,12 +166,9 @@ loadChars( ULONG64 address, ULONG number, BOOLEAN phyAddr )
|
|||||||
{
|
{
|
||||||
std::vector<char> buffer(number);
|
std::vector<char> buffer(number);
|
||||||
|
|
||||||
if ( loadMemory( address, &buffer[0], (ULONG)buffer.size(), phyAddr ) )
|
loadMemory( address, &buffer[0], (ULONG)buffer.size(), phyAddr );
|
||||||
{
|
|
||||||
return boost::python::object(std::string( buffer.begin(), buffer.end() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object(std::string( buffer.begin(), buffer.end() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -203,12 +178,9 @@ loadWChars( ULONG64 address, ULONG number, BOOLEAN phyAddr )
|
|||||||
{
|
{
|
||||||
std::vector<wchar_t> buffer(number);
|
std::vector<wchar_t> buffer(number);
|
||||||
|
|
||||||
if ( loadMemory( address, &buffer[0], (ULONG)buffer.size(), phyAddr ) )
|
loadMemory( address, &buffer[0], (ULONG)buffer.size(), phyAddr );
|
||||||
{
|
|
||||||
return boost::python::object(std::wstring( buffer.begin(), buffer.end() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object(std::wstring( buffer.begin(), buffer.end() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -222,7 +194,8 @@ loadPtrByPtr( ULONG64 address )
|
|||||||
loadMemory( address, &value, sizeof(ULONG64) );
|
loadMemory( address, &value, sizeof(ULONG64) );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( loadMemory( address, &value, sizeof(ULONG) ) )
|
loadMemory( address, &value, sizeof(ULONG) );
|
||||||
|
|
||||||
value = addr64( value );
|
value = addr64( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,12 +240,9 @@ loadByPtr<char>( ULONG64 address )
|
|||||||
{
|
{
|
||||||
char value;
|
char value;
|
||||||
|
|
||||||
if ( loadMemory( address, &value, sizeof(char) ) )
|
loadMemory( address, &value, sizeof(char) );
|
||||||
{
|
|
||||||
return boost::python::object( (int)value );
|
|
||||||
}
|
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object( (int)value );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -286,16 +256,14 @@ loadUnicodeStr( ULONG64 address )
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
if ( !loadMemory( address, &length, sizeof( length ) ) )
|
loadMemory( address, &length, sizeof( length ) );
|
||||||
break;
|
|
||||||
|
|
||||||
if ( length == 0 )
|
if ( length == 0 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
address += sizeof( length );
|
address += sizeof( length );
|
||||||
|
|
||||||
if ( !loadMemory( address, &maximumLength, sizeof( maximumLength ) ) )
|
loadMemory( address, &maximumLength, sizeof( maximumLength ) );
|
||||||
break;
|
|
||||||
|
|
||||||
address += sizeof( maximumLength );
|
address += sizeof( maximumLength );
|
||||||
|
|
||||||
@ -303,8 +271,7 @@ loadUnicodeStr( ULONG64 address )
|
|||||||
{
|
{
|
||||||
address += address % 8 ? ( 8 - address % 8 ) : 0 ; // âûðàâíèâàíèå íà 8 áàéò
|
address += address % 8 ? ( 8 - address % 8 ) : 0 ; // âûðàâíèâàíèå íà 8 áàéò
|
||||||
|
|
||||||
if ( !loadMemory( address, &buffer, 8 ) )
|
loadMemory( address, &buffer, 8 );
|
||||||
break;
|
|
||||||
|
|
||||||
address += 8;
|
address += 8;
|
||||||
}
|
}
|
||||||
@ -312,8 +279,7 @@ loadUnicodeStr( ULONG64 address )
|
|||||||
{
|
{
|
||||||
address += address % 4 ? ( 4 - address % 4 ) : 0 ; // âûðàâíèâàíèå íà 8 áàéò
|
address += address % 4 ? ( 4 - address % 4 ) : 0 ; // âûðàâíèâàíèå íà 8 áàéò
|
||||||
|
|
||||||
if ( !loadMemory( address, &buffer, 4 ) )
|
loadMemory( address, &buffer, 4 );
|
||||||
break;
|
|
||||||
|
|
||||||
buffer = addr64( buffer );
|
buffer = addr64( buffer );
|
||||||
|
|
||||||
@ -322,8 +288,7 @@ loadUnicodeStr( ULONG64 address )
|
|||||||
|
|
||||||
std::vector<wchar_t> str(length / 2);
|
std::vector<wchar_t> str(length / 2);
|
||||||
|
|
||||||
if ( !loadMemory( buffer, &str[0], length ) )
|
loadMemory( buffer, &str[0], length );
|
||||||
break;
|
|
||||||
|
|
||||||
std::wstring strValue(&str[0], length/2);
|
std::wstring strValue(&str[0], length/2);
|
||||||
|
|
||||||
@ -346,16 +311,14 @@ loadAnsiStr( ULONG64 address )
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
if ( !loadMemory( address, &length, sizeof( length ) ) )
|
loadMemory( address, &length, sizeof( length ) );
|
||||||
break;
|
|
||||||
|
|
||||||
if ( length == 0 )
|
if ( length == 0 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
address += sizeof( length );
|
address += sizeof( length );
|
||||||
|
|
||||||
if ( !loadMemory( address, &maximumLength, sizeof( maximumLength ) ) )
|
loadMemory( address, &maximumLength, sizeof( maximumLength ) );
|
||||||
break;
|
|
||||||
|
|
||||||
address += sizeof( maximumLength );
|
address += sizeof( maximumLength );
|
||||||
|
|
||||||
@ -363,8 +326,7 @@ loadAnsiStr( ULONG64 address )
|
|||||||
{
|
{
|
||||||
address += address % 8 ? ( 8 - address % 8 ) : 0; // âûðàâíèâàíèå íà 8 áàéò
|
address += address % 8 ? ( 8 - address % 8 ) : 0; // âûðàâíèâàíèå íà 8 áàéò
|
||||||
|
|
||||||
if ( !loadMemory( address, &buffer, 8 ) )
|
loadMemory( address, &buffer, 8 );
|
||||||
break;
|
|
||||||
|
|
||||||
address += 8;
|
address += 8;
|
||||||
}
|
}
|
||||||
@ -372,8 +334,7 @@ loadAnsiStr( ULONG64 address )
|
|||||||
{
|
{
|
||||||
address += address % 4 ? ( 4 - address % 4 ) : 0; // âûðàâíèâàíèå íà 8 áàéò
|
address += address % 4 ? ( 4 - address % 4 ) : 0; // âûðàâíèâàíèå íà 8 áàéò
|
||||||
|
|
||||||
if ( !loadMemory( address, &buffer, 4 ) )
|
loadMemory( address, &buffer, 4 );
|
||||||
break;
|
|
||||||
|
|
||||||
buffer = addr64( buffer );
|
buffer = addr64( buffer );
|
||||||
|
|
||||||
@ -383,8 +344,7 @@ loadAnsiStr( ULONG64 address )
|
|||||||
|
|
||||||
std::vector<char> str(length);
|
std::vector<char> str(length);
|
||||||
|
|
||||||
if ( !loadMemory( buffer, &str[0], length ) )
|
loadMemory( buffer, &str[0], length );
|
||||||
break;
|
|
||||||
|
|
||||||
std::string strVal ( &str[0], length );
|
std::string strVal ( &str[0], length );
|
||||||
|
|
||||||
@ -397,13 +357,11 @@ loadAnsiStr( ULONG64 address )
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadCStrToBuffer( ULONG64 address, PCHAR buffer, ULONG bufferLen )
|
loadCStrToBuffer( ULONG64 address, PCHAR buffer, ULONG bufferLen )
|
||||||
{
|
{
|
||||||
address = addr64( address );
|
address = addr64( address );
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
dbgExt->dataSpaces4->ReadMultiByteStringVirtual(
|
dbgExt->dataSpaces4->ReadMultiByteStringVirtual(
|
||||||
address,
|
address,
|
||||||
@ -413,31 +371,16 @@ loadCStrToBuffer( ULONG64 address, PCHAR buffer, ULONG bufferLen )
|
|||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
return false;
|
throw MemoryException( address );
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadWStrToBuffer( ULONG64 address, PWCHAR buffer, ULONG bufferLen )
|
loadWStrToBuffer( ULONG64 address, PWCHAR buffer, ULONG bufferLen )
|
||||||
{
|
{
|
||||||
address = addr64( address );
|
address = addr64( address );
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
dbgExt->dataSpaces4->ReadUnicodeStringVirtualWide(
|
dbgExt->dataSpaces4->ReadUnicodeStringVirtualWide(
|
||||||
address,
|
address,
|
||||||
@ -447,38 +390,20 @@ loadWStrToBuffer( ULONG64 address, PWCHAR buffer, ULONG bufferLen )
|
|||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
return false;
|
throw MemoryException( address );
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadCStr( ULONG64 address )
|
loadCStr( ULONG64 address )
|
||||||
{
|
{
|
||||||
const size_t maxLength = 0x1000;
|
const size_t maxLength = 0x1000;
|
||||||
boost::python::object strObj( std::string("") );
|
|
||||||
|
|
||||||
address = addr64( address );
|
address = addr64( address );
|
||||||
|
|
||||||
boost::scoped_array<char> buffer(new char[maxLength]);
|
boost::scoped_array<char> buffer(new char[maxLength]);
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
dbgExt->dataSpaces4->ReadMultiByteStringVirtual(
|
dbgExt->dataSpaces4->ReadMultiByteStringVirtual(
|
||||||
address,
|
address,
|
||||||
@ -488,21 +413,9 @@ loadCStr( ULONG64 address )
|
|||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugDataSpace4::ReadMultiByteStringVirtual failed" );
|
throw MemoryException( address );
|
||||||
|
|
||||||
strObj = boost::python::object( std::string( buffer.get() ) );
|
return boost::python::object( std::string( buffer.get() ) );
|
||||||
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return strObj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -511,14 +424,11 @@ boost::python::object
|
|||||||
loadWStr( ULONG64 address )
|
loadWStr( ULONG64 address )
|
||||||
{
|
{
|
||||||
const size_t maxLength = 0x1000;
|
const size_t maxLength = 0x1000;
|
||||||
boost::python::object strObj( std::wstring(L"") );
|
|
||||||
|
|
||||||
address = addr64( address );
|
address = addr64( address );
|
||||||
|
|
||||||
boost::scoped_array<wchar_t> buffer(new wchar_t[maxLength]);
|
boost::scoped_array<wchar_t> buffer(new wchar_t[maxLength]);
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
dbgExt->dataSpaces4->ReadUnicodeStringVirtualWide(
|
dbgExt->dataSpaces4->ReadUnicodeStringVirtualWide(
|
||||||
address,
|
address,
|
||||||
@ -528,21 +438,9 @@ loadWStr( ULONG64 address )
|
|||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugDataSpace4::ReadUnicodeStringVirtualWide failed" );
|
throw MemoryException( address );
|
||||||
|
|
||||||
strObj = boost::python::object( std::wstring(buffer.get()) );
|
return boost::python::object( std::wstring(buffer.get()) );
|
||||||
|
|
||||||
}
|
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return strObj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadMemory( ULONG64 address, PVOID dest, ULONG length, BOOLEAN phyAddr = FALSE );
|
loadMemory( ULONG64 address, PVOID dest, ULONG length, BOOLEAN phyAddr = FALSE );
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
@ -23,17 +23,14 @@ loadArray( ULONG64 address, ULONG number, BOOLEAN phyAddr = FALSE )
|
|||||||
{
|
{
|
||||||
boost::scoped_array<T> buffer(new T[number]);
|
boost::scoped_array<T> buffer(new T[number]);
|
||||||
|
|
||||||
if ( loadMemory( address, buffer.get(), number*sizeof(T), phyAddr ) )
|
loadMemory( address, buffer.get(), number*sizeof(T), phyAddr );
|
||||||
{
|
|
||||||
boost::python::list lst;
|
boost::python::list lst;
|
||||||
|
|
||||||
for ( ULONG i = 0; i < number; ++i )
|
for ( ULONG i = 0; i < number; ++i )
|
||||||
lst.append( buffer[i] );
|
lst.append( buffer[i] );
|
||||||
|
|
||||||
return lst;
|
return lst;
|
||||||
}
|
|
||||||
|
|
||||||
return boost::python::object();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
@ -48,12 +45,9 @@ loadByPtr( ULONG64 address )
|
|||||||
{
|
{
|
||||||
T value;
|
T value;
|
||||||
|
|
||||||
if ( loadMemory( address, &value, sizeof(T) ) )
|
loadMemory( address, &value, sizeof(T) );
|
||||||
{
|
|
||||||
return boost::python::object( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -72,13 +66,13 @@ loadAnsiStr( ULONG64 address );
|
|||||||
boost::python::object
|
boost::python::object
|
||||||
loadCStr( ULONG64 address );
|
loadCStr( ULONG64 address );
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadCStrToBuffer( ULONG64 address, PCHAR buffer, ULONG bufferLen );
|
loadCStrToBuffer( ULONG64 address, PCHAR buffer, ULONG bufferLen );
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadWStr( ULONG64 address );
|
loadWStr( ULONG64 address );
|
||||||
|
|
||||||
bool
|
void
|
||||||
loadWStrToBuffer( ULONG64 address, PWCHAR buffer, ULONG bufferLen );
|
loadWStrToBuffer( ULONG64 address, PWCHAR buffer, ULONG bufferLen );
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -388,7 +388,7 @@ getLocals()
|
|||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbolGroup2::GetSymbolOffset failed" );
|
throw DbgException( "IDebugSymbolGroup2::GetSymbolOffset failed" );
|
||||||
|
|
||||||
arr[ varName ] = loadTypedVar( moduleName, typeName, varOffset );
|
arr[ varName ] = TypedVar( moduleName, typeName, varOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
|
2179
pykd/dbgtype.cpp
2179
pykd/dbgtype.cpp
File diff suppressed because it is too large
Load Diff
770
pykd/dbgtype.h
770
pykd/dbgtype.h
@ -2,15 +2,251 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <vector>
|
||||||
|
|
||||||
#include "dbgmem.h"
|
#include "dbgmem.h"
|
||||||
#include "dbgsystem.h"
|
#include "dbgsystem.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
#include <boost/python/slice.hpp>
|
||||||
|
|
||||||
boost::python::object
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address );
|
|
||||||
|
class TypedVar;
|
||||||
|
class TypeInfo;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TypeInfo {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeInfo() :
|
||||||
|
m_size(0),
|
||||||
|
m_arraySize( 0 ),
|
||||||
|
m_parentOffset( 0 ),
|
||||||
|
m_align( ptrSize() ),
|
||||||
|
m_isFreezed( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypeInfo( const std::string customName, ULONG align=0 ) :
|
||||||
|
m_typeName( customName ),
|
||||||
|
m_size( 0 ),
|
||||||
|
m_arraySize( 0 ),
|
||||||
|
m_parentOffset( 0 ),
|
||||||
|
m_isFreezed( false ),
|
||||||
|
m_align( align == 0 ? ptrSize() : align )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
TypeInfo( const std::string &moduleName, ULONG64 moduleBase, ULONG typeId );
|
||||||
|
|
||||||
|
static
|
||||||
|
const TypeInfo&
|
||||||
|
get( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
size() const {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
count() const {
|
||||||
|
assert( m_size != 0 );
|
||||||
|
return m_arraySize / m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
fullSize() const {
|
||||||
|
return m_arraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string
|
||||||
|
name() const {
|
||||||
|
return m_typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string
|
||||||
|
moduleName() const {
|
||||||
|
return m_moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
load( void* buffer, size_t bufferLength ) const;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
printField( size_t index, void* buffer, size_t bufferLength ) const;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
print() const;
|
||||||
|
|
||||||
|
TypeInfo
|
||||||
|
getField( const std::string &fieldName ) const;
|
||||||
|
|
||||||
|
TypeInfo
|
||||||
|
getFieldAt( size_t index ) const;
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
getFieldOffset() const {
|
||||||
|
return m_parentOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
getFieldByIndex( boost::python::object &index ) const;
|
||||||
|
|
||||||
|
size_t
|
||||||
|
getFieldCount() const {
|
||||||
|
return m_fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
appendField( const TypeInfo &typeInfo, const std::string &fieldName, ULONG count = 1 );
|
||||||
|
|
||||||
|
bool
|
||||||
|
isBaseType() const {
|
||||||
|
return m_isBaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isPtr() const {
|
||||||
|
return m_isPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
loadVar( ULONG64 targetOffset, ULONG count = 1) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::map< std::pair<std::string, std::string>, TypeInfo> TypeInfoMap;
|
||||||
|
|
||||||
|
template< typename TTypeInfo>
|
||||||
|
struct TypeFieldT {
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
ULONG offset;
|
||||||
|
|
||||||
|
ULONG size;
|
||||||
|
|
||||||
|
TTypeInfo type;
|
||||||
|
|
||||||
|
TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
||||||
|
name( name_ ),
|
||||||
|
size( size_ ),
|
||||||
|
offset( offset_ ),
|
||||||
|
type( type_ )
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string print() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TypeFieldT<TypeInfo> TypeField;
|
||||||
|
|
||||||
|
typedef std::vector<TypeField> TypeFieldList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef
|
||||||
|
boost::python::object
|
||||||
|
(*basicTypeLoader)( void* address, size_t size );
|
||||||
|
|
||||||
|
typedef
|
||||||
|
std::string
|
||||||
|
(*basicTypePrinter)( void* address, size_t size );
|
||||||
|
|
||||||
|
static TypeInfoMap g_typeInfoCache;
|
||||||
|
|
||||||
|
static const char* basicTypeNames[];
|
||||||
|
|
||||||
|
static size_t basicTypeSizes[];
|
||||||
|
|
||||||
|
static basicTypeLoader basicTypeLoaders[];
|
||||||
|
|
||||||
|
static basicTypePrinter basicTypePrinters[];
|
||||||
|
|
||||||
|
ULONG m_size;
|
||||||
|
|
||||||
|
ULONG m_arraySize;
|
||||||
|
|
||||||
|
std::string m_typeName;
|
||||||
|
|
||||||
|
std::string m_moduleName;
|
||||||
|
|
||||||
|
TypeFieldList m_fields;
|
||||||
|
|
||||||
|
bool m_isPointer;
|
||||||
|
|
||||||
|
bool m_isBaseType;
|
||||||
|
|
||||||
|
bool m_isFreezed;
|
||||||
|
|
||||||
|
ULONG m_align;
|
||||||
|
|
||||||
|
ULONG m_parentOffset;
|
||||||
|
|
||||||
|
static bool checkBaseType( const std::string &typeName );
|
||||||
|
|
||||||
|
static ULONG getBaseTypeSize( const std::string &typeName );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TypedVar {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypedVar() :
|
||||||
|
m_targetOffset ( 0 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypedVar( const TypeInfo &typeInfo, ULONG64 targetOffset ) :
|
||||||
|
m_typeInfo( typeInfo ),
|
||||||
|
m_targetOffset( addr64(targetOffset) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 targetOffset ) :
|
||||||
|
m_typeInfo( moduleName, typeName ),
|
||||||
|
m_targetOffset( addr64(targetOffset) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
ULONG64
|
||||||
|
getAddress() const {
|
||||||
|
return m_targetOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
getSize() const {
|
||||||
|
return m_typeInfo.fullSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
boost::python::object
|
||||||
|
getFieldWrap( PyObject* self, const std::string &fieldName );
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
getField( boost::python::object &pyobj, const std::string &fieldName );
|
||||||
|
|
||||||
|
ULONG64 getTargetOffset() const {
|
||||||
|
return m_targetOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string print();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
TypedVar( const TypeInfo &typeInfo, ULONG64 targetOffset, char* buffer, size_t bufferLength );
|
||||||
|
|
||||||
|
ULONG64 m_targetOffset;
|
||||||
|
|
||||||
|
TypeInfo m_typeInfo;
|
||||||
|
|
||||||
|
std::vector<char> m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName );
|
loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName );
|
||||||
@ -21,250 +257,308 @@ loadTypedVarArray( ULONG64 address, const std::string &moduleName, const std::st
|
|||||||
boost::python::object
|
boost::python::object
|
||||||
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName );
|
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName );
|
||||||
|
|
||||||
boost::python::object
|
|
||||||
getTypeClass( const std::string &moduleName, const std::string &typeName );
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
sizeofType( const std::string &moduleName, const std::string &typeName );
|
sizeofType( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class TypeInfo {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template< typename TTypeInfo>
|
//public:
|
||||||
struct TypeFieldT {
|
//
|
||||||
ULONG size;
|
// typedVarClass() : m_addr(0)
|
||||||
ULONG offset;
|
// {}
|
||||||
TTypeInfo type;
|
//
|
||||||
std::string name;
|
// typedVarClass( const TypeInfo &typeInfo, ULONG64 addr) :
|
||||||
|
// m_typeInfo( typeInfo ),
|
||||||
|
// m_addr( addr )
|
||||||
|
// {}
|
||||||
|
//
|
||||||
|
// ULONG64
|
||||||
|
// getAddress() const {
|
||||||
|
// return m_addr;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //virtual void
|
||||||
|
// //printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
|
||||||
|
//
|
||||||
|
// //virtual void
|
||||||
|
// //printSelf( std::stringstream &sstr ) const override
|
||||||
|
// //{
|
||||||
|
// // sstr << std::hex << "0x" << getAddress() << std::dec << " ";
|
||||||
|
// //}
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
//
|
||||||
|
// TypeInfo m_typeInfo;
|
||||||
|
//
|
||||||
|
// ULONG64 m_addr;
|
||||||
|
//};
|
||||||
|
|
||||||
TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
name( name_ ),
|
|
||||||
size( size_ ),
|
|
||||||
offset( offset_ ),
|
|
||||||
type( type_ )
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeName {
|
|
||||||
std::string module;
|
|
||||||
std::string symbol;
|
|
||||||
|
|
||||||
TypeName( const std::string &module_, const std::string &symbol_ ) :
|
|
||||||
module( module_ ),
|
|
||||||
symbol( symbol_ )
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator < ( const TypeName &typeName ) const {
|
|
||||||
|
|
||||||
if ( typeName.module < module )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ( typeName.module > module )
|
//
|
||||||
return false;
|
//boost::python::object
|
||||||
|
//loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address );
|
||||||
return typeName.symbol < symbol;
|
//
|
||||||
}
|
//boost::python::object
|
||||||
|
//loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName );
|
||||||
};
|
//
|
||||||
|
//boost::python::object
|
||||||
typedef TypeFieldT<TypeInfo> TypeField;
|
//loadTypedVarArray( ULONG64 address, const std::string &moduleName, const std::string &typeName, long number );
|
||||||
|
//
|
||||||
typedef std::map<TypeName, TypeInfo> TypeInfoMap;
|
//boost::python::object
|
||||||
|
//containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName );
|
||||||
typedef std::list<TypeField> TypeFieldList;
|
//
|
||||||
|
//boost::python::object
|
||||||
public:
|
//getTypeClass( const std::string &moduleName, const std::string &typeName );
|
||||||
|
//
|
||||||
TypeInfo() :
|
//ULONG
|
||||||
m_size( 0 ),
|
//sizeofType( const std::string &moduleName, const std::string &typeName );
|
||||||
m_baseType( false ),
|
//
|
||||||
m_pointer( false )
|
//
|
||||||
{}
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
TypeInfo( const std::string &typeName ) :
|
//class TypeInfo {
|
||||||
m_size( 0 ),
|
//
|
||||||
m_baseType( false ),
|
//public:
|
||||||
m_pointer( false ),
|
//
|
||||||
m_typeName( typeName )
|
// template< typename TTypeInfo>
|
||||||
{}
|
// struct TypeFieldT {
|
||||||
|
// ULONG size;
|
||||||
boost::python::object
|
// ULONG offset;
|
||||||
load( ULONG64 targetAddr, PVOID cacheBuffer = NULL, ULONG offset = 0 ) const;
|
// TTypeInfo type;
|
||||||
|
// std::string name;
|
||||||
boost::python::object
|
//
|
||||||
build( ULONG offset = 0 ) const;
|
// TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
||||||
|
// name( name_ ),
|
||||||
ULONG64
|
// size( size_ ),
|
||||||
size() const
|
// offset( offset_ ),
|
||||||
{
|
// type( type_ )
|
||||||
return m_size;
|
// {}
|
||||||
}
|
// };
|
||||||
|
//
|
||||||
const std::string&
|
// struct TypeName {
|
||||||
name() const
|
// std::string module;
|
||||||
{
|
// std::string symbol;
|
||||||
return m_typeName;
|
//
|
||||||
}
|
// TypeName( const std::string &module_, const std::string &symbol_ ) :
|
||||||
|
// module( module_ ),
|
||||||
const TypeFieldList&
|
// symbol( symbol_ )
|
||||||
getFields() const {
|
// {}
|
||||||
return m_fields;
|
//
|
||||||
}
|
// bool
|
||||||
|
// operator < ( const TypeName &typeName ) const {
|
||||||
bool
|
//
|
||||||
isComplex() const {
|
// if ( typeName.module < module )
|
||||||
return !m_baseType;
|
// return true;
|
||||||
}
|
//
|
||||||
|
// if ( typeName.module > module )
|
||||||
bool
|
// return false;
|
||||||
isPtr() const {
|
//
|
||||||
return m_pointer;
|
// return typeName.symbol < symbol;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static const TypeInfo*
|
// };
|
||||||
get( const std::string &moduleName, const std::string &typeName );
|
//
|
||||||
|
// typedef TypeFieldT<TypeInfo> TypeField;
|
||||||
private:
|
//
|
||||||
|
// typedef std::map<TypeName, TypeInfo> TypeInfoMap;
|
||||||
static TypeInfoMap g_typeInfoCache;
|
//
|
||||||
|
// typedef std::list<TypeField> TypeFieldList;
|
||||||
boost::python::object
|
//
|
||||||
loadBaseType( PVOID addr ) const;
|
//public:
|
||||||
|
//
|
||||||
boost::python::object
|
// TypeInfo() :
|
||||||
ptrLoader( PVOID addr ) const {
|
// m_size( 0 ),
|
||||||
if ( is64bitSystem() )
|
// m_baseType( false ),
|
||||||
return boost::python::object( *(PULONG64)addr );
|
// m_pointer( false )
|
||||||
else
|
// {}
|
||||||
return boost::python::object( addr64( *(PULONG)addr ) );
|
//
|
||||||
}
|
// TypeInfo( const std::string &typeName ) :
|
||||||
|
// m_size( 0 ),
|
||||||
void
|
// m_baseType( false ),
|
||||||
setupBaseType();
|
// m_pointer( false ),
|
||||||
|
// m_typeName( typeName )
|
||||||
static bool
|
// {}
|
||||||
getById( const std::string &moduleName, ULONG typeId, TypeInfo& typeInfo );
|
//
|
||||||
|
// boost::python::object
|
||||||
private:
|
// load( ULONG64 targetAddr, PVOID cacheBuffer = NULL, ULONG offset = 0 ) const;
|
||||||
|
//
|
||||||
bool m_baseType;
|
// boost::python::object
|
||||||
bool m_pointer;
|
// build( ULONG offset = 0 ) const;
|
||||||
TypeFieldList m_fields;
|
//
|
||||||
std::string m_typeName;
|
// ULONG64
|
||||||
ULONG m_size;
|
// size() const
|
||||||
};
|
// {
|
||||||
|
// return m_size;
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
// }
|
||||||
|
//
|
||||||
class typeClass
|
// const std::string&
|
||||||
{
|
// name() const
|
||||||
public:
|
// {
|
||||||
|
// return m_typeName;
|
||||||
typeClass()
|
// }
|
||||||
: m_offset(0)
|
//
|
||||||
{
|
// const TypeFieldList&
|
||||||
}
|
// getFields() const {
|
||||||
|
// return m_fields;
|
||||||
typeClass(
|
// }
|
||||||
const TypeInfo &typeInfo,
|
//
|
||||||
ULONG offset
|
// bool
|
||||||
) : m_typeInfo(typeInfo)
|
// isComplex() const {
|
||||||
, m_offset(offset)
|
// return !m_baseType;
|
||||||
{
|
// }
|
||||||
}
|
//
|
||||||
|
// bool
|
||||||
// sizeof(TYPE)
|
// isPtr() const {
|
||||||
ULONG size() const
|
// return m_pointer;
|
||||||
{
|
// }
|
||||||
return (ULONG)m_typeInfo.size();
|
//
|
||||||
}
|
// static const TypeInfo*
|
||||||
|
// get( const std::string &moduleName, const std::string &typeName );
|
||||||
void setPyObj( const boost::python::object &obj )
|
//
|
||||||
{
|
//private:
|
||||||
m_pyobj = obj;
|
//
|
||||||
}
|
// static TypeInfoMap g_typeInfoCache;
|
||||||
|
//
|
||||||
// TypeInfo getter
|
// boost::python::object
|
||||||
TypeInfo &getTypeInfo()
|
// loadBaseType( PVOID addr ) const;
|
||||||
{
|
//
|
||||||
return m_typeInfo;
|
// boost::python::object
|
||||||
}
|
// ptrLoader( PVOID addr ) const {
|
||||||
const TypeInfo &getTypeInfo() const
|
// if ( is64bitSystem() )
|
||||||
{
|
// return boost::python::object( *(PULONG64)addr );
|
||||||
return m_typeInfo;
|
// else
|
||||||
}
|
// return boost::python::object( addr64( *(PULONG)addr ) );
|
||||||
|
// }
|
||||||
// boost::python::object getter
|
//
|
||||||
boost::python::object &getPyObj()
|
// void
|
||||||
{
|
// setupBaseType();
|
||||||
return m_pyobj;
|
//
|
||||||
}
|
// static bool
|
||||||
const boost::python::object &getPyObj() const
|
// getById( const std::string &moduleName, ULONG typeId, TypeInfo& typeInfo );
|
||||||
{
|
//
|
||||||
return m_pyobj;
|
//private:
|
||||||
}
|
//
|
||||||
|
// bool m_baseType;
|
||||||
std::string print() const;
|
// bool m_pointer;
|
||||||
|
// TypeFieldList m_fields;
|
||||||
virtual void printField(
|
// std::string m_typeName;
|
||||||
const TypeInfo::TypeField &field,
|
// ULONG m_size;
|
||||||
std::stringstream &sstr
|
//};
|
||||||
) const
|
//
|
||||||
{
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// no data - nothing print
|
//
|
||||||
}
|
//class typeClass
|
||||||
virtual void printSelf(
|
//{
|
||||||
std::stringstream &sstr
|
//public:
|
||||||
) const
|
//
|
||||||
{
|
// typeClass()
|
||||||
// no data - nothing print
|
// : m_offset(0)
|
||||||
}
|
// {
|
||||||
|
// }
|
||||||
// field offset getter/setter
|
//
|
||||||
ULONG getOffset() const { return m_offset; }
|
// typeClass(
|
||||||
|
// const TypeInfo &typeInfo,
|
||||||
private:
|
// ULONG offset
|
||||||
TypeInfo m_typeInfo;
|
// ) : m_typeInfo(typeInfo)
|
||||||
ULONG m_offset;
|
// , m_offset(offset)
|
||||||
boost::python::object m_pyobj;
|
// {
|
||||||
};
|
// }
|
||||||
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
// // sizeof(TYPE)
|
||||||
|
// ULONG size() const
|
||||||
class typedVarClass : public typeClass {
|
// {
|
||||||
|
// return (ULONG)m_typeInfo.size();
|
||||||
public:
|
// }
|
||||||
|
//
|
||||||
typedVarClass() : m_addr(0)
|
// void setPyObj( const boost::python::object &obj )
|
||||||
{}
|
// {
|
||||||
|
// m_pyobj = obj;
|
||||||
typedVarClass( const TypeInfo &typeInfo, ULONG offset, ULONG64 addr) :
|
// }
|
||||||
typeClass( typeInfo, offset ),
|
//
|
||||||
m_addr( addr )
|
// // TypeInfo getter
|
||||||
{}
|
// TypeInfo &getTypeInfo()
|
||||||
|
// {
|
||||||
ULONG64
|
// return m_typeInfo;
|
||||||
getAddress() const {
|
// }
|
||||||
return m_addr;
|
// const TypeInfo &getTypeInfo() const
|
||||||
}
|
// {
|
||||||
|
// return m_typeInfo;
|
||||||
virtual void
|
// }
|
||||||
printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
|
//
|
||||||
|
// // boost::python::object getter
|
||||||
virtual void
|
// boost::python::object &getPyObj()
|
||||||
printSelf( std::stringstream &sstr ) const override
|
// {
|
||||||
{
|
// return m_pyobj;
|
||||||
sstr << std::hex << "0x" << getAddress() << std::dec << " ";
|
// }
|
||||||
}
|
// const boost::python::object &getPyObj() const
|
||||||
|
// {
|
||||||
private:
|
// return m_pyobj;
|
||||||
|
// }
|
||||||
ULONG64 m_addr;
|
//
|
||||||
};
|
// std::string print() const;
|
||||||
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
// virtual void printField(
|
||||||
|
// const TypeInfo::TypeField &field,
|
||||||
|
// std::stringstream &sstr
|
||||||
|
// ) const
|
||||||
|
// {
|
||||||
|
// // no data - nothing print
|
||||||
|
// }
|
||||||
|
// virtual void printSelf(
|
||||||
|
// std::stringstream &sstr
|
||||||
|
// ) const
|
||||||
|
// {
|
||||||
|
// // no data - nothing print
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // field offset getter/setter
|
||||||
|
// ULONG getOffset() const { return m_offset; }
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// TypeInfo m_typeInfo;
|
||||||
|
// ULONG m_offset;
|
||||||
|
// boost::python::object m_pyobj;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//class typedVarClass : public typeClass {
|
||||||
|
//
|
||||||
|
//public:
|
||||||
|
//
|
||||||
|
// typedVarClass() : m_addr(0)
|
||||||
|
// {}
|
||||||
|
//
|
||||||
|
// typedVarClass( const TypeInfo &typeInfo, ULONG offset, ULONG64 addr) :
|
||||||
|
// typeClass( typeInfo, offset ),
|
||||||
|
// m_addr( addr )
|
||||||
|
// {}
|
||||||
|
//
|
||||||
|
// ULONG64
|
||||||
|
// getAddress() const {
|
||||||
|
// return m_addr;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// virtual void
|
||||||
|
// printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
|
||||||
|
//
|
||||||
|
// virtual void
|
||||||
|
// printSelf( std::stringstream &sstr ) const override
|
||||||
|
// {
|
||||||
|
// sstr << std::hex << "0x" << getAddress() << std::dec << " ";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
//
|
||||||
|
// ULONG64 m_addr;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
@ -356,6 +356,10 @@
|
|||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dbgbreak.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\dbgcmd.cpp"
|
RelativePath=".\dbgcmd.cpp"
|
||||||
>
|
>
|
||||||
@ -368,6 +372,10 @@
|
|||||||
RelativePath=".\dbgeventcb.cpp"
|
RelativePath=".\dbgeventcb.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dbgexcept.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\dbgext.cpp"
|
RelativePath=".\dbgext.cpp"
|
||||||
>
|
>
|
||||||
@ -462,6 +470,10 @@
|
|||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dbgbreak.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\dbgcallback.h"
|
RelativePath=".\dbgcallback.h"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user