2010-07-06 22:49:02 +08:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
2011-09-12 14:59:11 +08:00
|
|
|
|
#include <dbgeng.h>
|
2011-09-17 02:07:00 +08:00
|
|
|
|
#include <dia2.h>
|
2010-07-06 22:49:02 +08:00
|
|
|
|
|
2011-10-07 14:30:09 +08:00
|
|
|
|
#include <boost/tokenizer.hpp>
|
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
#include "windbg.h"
|
2011-09-15 22:16:20 +08:00
|
|
|
|
#include "module.h"
|
|
|
|
|
#include "diawrapper.h"
|
|
|
|
|
#include "dbgclient.h"
|
2011-10-03 19:34:36 +08:00
|
|
|
|
#include "dbgio.h"
|
2011-10-07 14:30:09 +08:00
|
|
|
|
#include "dbgpath.h"
|
2011-09-15 22:16:20 +08:00
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
using namespace pykd;
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI DllMain(
|
|
|
|
|
__in HINSTANCE /*hinstDLL*/,
|
|
|
|
|
__in DWORD fdwReason,
|
|
|
|
|
__in LPVOID /*lpvReserved*/
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
switch (fdwReason)
|
|
|
|
|
{
|
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
|
CoInitialize(NULL);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2011-09-15 22:16:20 +08:00
|
|
|
|
|
2011-09-12 14:59:11 +08:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2011-04-08 15:53:37 +08:00
|
|
|
|
|
2011-09-21 06:17:40 +08:00
|
|
|
|
static python::dict genDict(const pyDia::Symbol::ValueNameEntry srcValues[], size_t cntValues)
|
|
|
|
|
{
|
|
|
|
|
python::dict resDict;
|
|
|
|
|
for (size_t i = 0; i < cntValues; ++i)
|
|
|
|
|
resDict[srcValues[i].first] = srcValues[i].second;
|
|
|
|
|
return resDict;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2011-10-07 14:30:09 +08:00
|
|
|
|
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, dprint, 1, 2 )
|
|
|
|
|
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 )
|
|
|
|
|
|
2011-09-17 02:07:00 +08:00
|
|
|
|
#define DEF_PY_CONST_ULONG(x) \
|
|
|
|
|
python::scope().attr(#x) = ULONG(##x)
|
2011-09-17 01:13:40 +08:00
|
|
|
|
|
2011-09-15 22:16:20 +08:00
|
|
|
|
BOOST_PYTHON_MODULE( pykd )
|
2010-10-25 15:54:10 +08:00
|
|
|
|
{
|
2011-09-29 15:53:45 +08:00
|
|
|
|
python::class_<pykd::DebugClient, pykd::DebugClientPtr>("dbgClient", "Class representing a debugging session", python::no_init )
|
2011-09-21 23:53:02 +08:00
|
|
|
|
.def( "loadDump", &pykd::DebugClient::loadDump,
|
|
|
|
|
"Load crash dump" )
|
|
|
|
|
.def( "startProcess", &pykd::DebugClient::startProcess,
|
|
|
|
|
"Start process for debugging" )
|
|
|
|
|
.def( "attachProcess", &pykd::DebugClient::attachProcess,
|
|
|
|
|
"Attach debugger to a exsisting process" )
|
|
|
|
|
.def( "attachKernel", &pykd::DebugClient::attachKernel,
|
|
|
|
|
"Attach debugger to a target's kernel" )
|
|
|
|
|
.def( "loadModule", &pykd::DebugClient::loadModule,
|
|
|
|
|
"Return instance of Module class" )
|
|
|
|
|
.def( "findModule", &pykd::DebugClient::findModule,
|
2011-10-03 19:34:36 +08:00
|
|
|
|
"Return instance of the Module class which posseses specified address" )
|
|
|
|
|
.def( "dprint", &pykd::DebugClient::dprint,
|
|
|
|
|
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
|
|
|
|
|
.def( "dprintln", &pykd::DebugClient::dprintln,
|
|
|
|
|
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" );
|
|
|
|
|
|
2011-10-10 19:19:12 +08:00
|
|
|
|
python::def( "createDbgClient", (DebugClientPtr(*)())&pykd::DebugClient::createDbgClient,
|
|
|
|
|
"create a new instance of the dbgClient class" );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "loadDump", &pykd::loadDump,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Load crash dump (only for console)");
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "startProcess", &pykd::startProcess,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Start process for debugging (only for console)");
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "attachProcess", &pykd::attachProcess,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Attach debugger to a exsisting process" );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "attachKernel", &pykd::attachKernel,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Attach debugger to a kernel target" );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "loadModule", &pykd::loadModule,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Return instance of Module class" );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::def( "findModule", &pykd::findModule,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Return instance of the Module class which posseses specified address" );
|
2011-10-07 14:30:09 +08:00
|
|
|
|
python::def( "dprint", &pykd::dprint, dprint_( boost::python::args( "str", "dml" ),
|
|
|
|
|
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
|
|
|
|
|
python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ),
|
|
|
|
|
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
|
2011-10-04 15:00:54 +08:00
|
|
|
|
|
|
|
|
|
python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init )
|
|
|
|
|
.def( "name", &pykd::TypeInfo::getName )
|
2011-10-06 14:26:25 +08:00
|
|
|
|
.def( "size", &pykd::TypeInfo::getSize )
|
2011-10-04 15:00:54 +08:00
|
|
|
|
.def( "offset", &pykd::TypeInfo::getOffset )
|
2011-10-06 14:26:25 +08:00
|
|
|
|
.def( "field", &pykd::TypeInfo::getField )
|
2011-10-04 15:00:54 +08:00
|
|
|
|
.def( "__getattr__", &pykd::TypeInfo::getField );
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-09-15 22:16:20 +08:00
|
|
|
|
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
|
2011-09-26 16:46:32 +08:00
|
|
|
|
.def("begin", &pykd::Module::getBase,
|
2011-09-19 15:05:22 +08:00
|
|
|
|
"Return start address of the module" )
|
2011-09-26 16:46:32 +08:00
|
|
|
|
.def("end", &pykd::Module::getEnd,
|
2011-09-19 15:05:22 +08:00
|
|
|
|
"Return end address of the module" )
|
2011-09-26 16:46:32 +08:00
|
|
|
|
.def("size", &pykd::Module::getSize,
|
2011-09-19 15:05:22 +08:00
|
|
|
|
"Return size of the module" )
|
2011-09-26 16:46:32 +08:00
|
|
|
|
.def("name", &pykd::Module::getName,
|
|
|
|
|
"Return name of the module" )
|
|
|
|
|
.def("image", &pykd::Module::getImageName,
|
|
|
|
|
"Return name of the image of the module" )
|
|
|
|
|
.def("pdb", &pykd::Module::getPdbName,
|
2011-09-21 23:53:02 +08:00
|
|
|
|
"Return the full path to the module's pdb file ( symbol information )" )
|
2011-09-26 16:46:32 +08:00
|
|
|
|
.def("reload", &pykd::Module::reloadSymbols,
|
|
|
|
|
"(Re)load symbols for the module" )
|
2011-09-29 15:53:45 +08:00
|
|
|
|
.def("offset", &pykd::Module::getSymbol,
|
|
|
|
|
"Return offset of the symbol" )
|
|
|
|
|
.def("rva", &pykd::Module::getSymbolRva,
|
|
|
|
|
"Return rva of the symbol" )
|
2011-10-03 15:40:27 +08:00
|
|
|
|
.def("type", &pykd::Module::getTypeByName,
|
|
|
|
|
"Return typeInfo class by type name" )
|
2011-09-29 15:53:45 +08:00
|
|
|
|
.def("__getattr__", &pykd::Module::getSymbol,
|
|
|
|
|
"Return address of the symbol" );
|
2011-10-07 14:30:09 +08:00
|
|
|
|
|
|
|
|
|
boost::python::class_<DbgOut>( "dout", "dout", python::no_init )
|
|
|
|
|
.def( "write", &DbgOut::write );
|
|
|
|
|
|
|
|
|
|
boost::python::class_<DbgIn>( "din", "din", python::no_init )
|
|
|
|
|
.def( "readline", &DbgIn::readline );
|
2011-09-26 16:46:32 +08:00
|
|
|
|
|
2011-09-23 17:37:56 +08:00
|
|
|
|
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
|
2011-09-17 02:07:00 +08:00
|
|
|
|
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
|
|
|
|
|
|
2011-09-26 16:38:28 +08:00
|
|
|
|
python::class_<pyDia::Symbol, pyDia::SymbolPtr>(
|
|
|
|
|
"DiaSymbol", "class wrapper for MS DIA Symbol", python::no_init )
|
2011-09-21 20:41:05 +08:00
|
|
|
|
.def( "findEx", &pyDia::Symbol::findChildrenEx,
|
2011-09-17 02:07:00 +08:00
|
|
|
|
"Retrieves the children of the symbol" )
|
|
|
|
|
.def( "find", &pyDia::Symbol::findChildren,
|
|
|
|
|
"Retrieves the children of the symbol" )
|
2011-09-17 01:13:40 +08:00
|
|
|
|
.def( "size", &pyDia::Symbol::getSize,
|
|
|
|
|
"Retrieves the number of bits or bytes of memory used by the object represented by this symbol" )
|
2011-09-19 00:50:42 +08:00
|
|
|
|
.def( "name", &pyDia::Symbol::getName,
|
|
|
|
|
"Retrieves the name of the symbol" )
|
|
|
|
|
.def( "type", &pyDia::Symbol::getType,
|
|
|
|
|
"Retrieves the symbol that represents the type for this symbol" )
|
2011-09-21 06:17:40 +08:00
|
|
|
|
.def( "indexType", &pyDia::Symbol::getIndexType,
|
2011-09-22 19:20:31 +08:00
|
|
|
|
"Retrieves a reference to the class parent of the symbol" )
|
2011-09-19 00:50:42 +08:00
|
|
|
|
.def( "rva", &pyDia::Symbol::getRva,
|
|
|
|
|
"Retrieves the relative virtual address (RVA) of the location")
|
|
|
|
|
.def( "symTag", &pyDia::Symbol::getSymTag,
|
2011-09-17 01:13:40 +08:00
|
|
|
|
"Retrieves the symbol type classifier: SymTagXxx" )
|
2011-09-19 00:50:42 +08:00
|
|
|
|
.def( "locType", &pyDia::Symbol::getLocType,
|
|
|
|
|
"Retrieves the location type of a data symbol: LocIsXxx" )
|
2011-09-22 19:20:31 +08:00
|
|
|
|
.def( "offset", &pyDia::Symbol::getOffset,
|
|
|
|
|
"Retrieves the offset of the symbol location" )
|
2011-09-23 22:16:29 +08:00
|
|
|
|
.def( "count", &pyDia::Symbol::getCount,
|
|
|
|
|
"Retrieves the number of items in a list or array" )
|
2011-09-19 00:50:42 +08:00
|
|
|
|
.def( "value", &pyDia::Symbol::getValue,
|
|
|
|
|
"Retrieves the value of a constant")
|
2011-09-21 06:17:40 +08:00
|
|
|
|
.def( "isBasic", &pyDia::Symbol::isBasicType,
|
|
|
|
|
"Retrieves a flag of basic type for symbol")
|
|
|
|
|
.def( "baseType", &pyDia::Symbol::getBaseType,
|
|
|
|
|
"Retrieves the base type for this symbol")
|
2011-09-22 18:05:56 +08:00
|
|
|
|
.def( "bitPos", &pyDia::Symbol::getBitPosition,
|
|
|
|
|
"Retrieves the base type for this symbol")
|
2011-09-22 19:20:31 +08:00
|
|
|
|
.def( "indexId", &pyDia::Symbol::getIndexId,
|
|
|
|
|
"Retrieves the unique symbol identifier")
|
|
|
|
|
.def( "udtKind", &pyDia::Symbol::getUdtKind,
|
|
|
|
|
"Retrieves the variety of a user-defined type")
|
2011-09-23 05:54:27 +08:00
|
|
|
|
.def("registerId", &pyDia::Symbol::getRegisterId,
|
|
|
|
|
"Retrieves the register designator of the location:\n"
|
|
|
|
|
"CV_REG_XXX (for IMAGE_FILE_MACHINE_I386) or CV_AMD64_XXX (for IMAGE_FILE_MACHINE_AMD64)")
|
2011-09-23 21:33:11 +08:00
|
|
|
|
.def("machineType", &pyDia::Symbol::getMachineType,
|
|
|
|
|
"Retrieves the type of the target CPU: IMAGE_FILE_MACHINE_XXX")
|
2011-09-19 00:50:42 +08:00
|
|
|
|
.def( "__str__", &pyDia::Symbol::print)
|
2011-09-22 16:25:42 +08:00
|
|
|
|
.def("__getitem__", &pyDia::Symbol::getChildByName)
|
2011-09-17 01:13:40 +08:00
|
|
|
|
.def("__len__", &pyDia::Symbol::getChildCount )
|
|
|
|
|
.def("__getitem__", &pyDia::Symbol::getChildByIndex);
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-26 16:38:28 +08:00
|
|
|
|
python::class_<pyDia::GlobalScope, pyDia::GlobalScopePtr, python::bases<pyDia::Symbol> >(
|
|
|
|
|
"DiaScope", "class wrapper for MS DIA Symbol", python::no_init )
|
2011-09-23 17:01:49 +08:00
|
|
|
|
.def("findByRva", &pyDia::GlobalScope::findByRva,
|
2011-09-23 17:37:56 +08:00
|
|
|
|
"Find symbol by RVA. Return tuple: (DiaSymbol, offset)")
|
|
|
|
|
.def("symbolById", &pyDia::GlobalScope::getSymbolById,
|
|
|
|
|
"Retrieves a symbol by its unique identifier: DiaSymbol::indexId()");
|
2011-09-23 05:54:27 +08:00
|
|
|
|
|
|
|
|
|
// CPU type:
|
|
|
|
|
DEF_PY_CONST_ULONG(IMAGE_FILE_MACHINE_I386);
|
|
|
|
|
DEF_PY_CONST_ULONG(IMAGE_FILE_MACHINE_IA64);
|
|
|
|
|
DEF_PY_CONST_ULONG(IMAGE_FILE_MACHINE_AMD64);
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
// type of symbol
|
2011-09-17 02:07:00 +08:00
|
|
|
|
DEF_PY_CONST_ULONG(SymTagNull);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagExe);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagCompiland);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagCompilandDetails);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagCompilandEnv);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFunction);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagBlock);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagData);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagAnnotation);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagLabel);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagPublicSymbol);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagUDT);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagEnum);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFunctionType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagPointerType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagArrayType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagBaseType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagTypedef);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagBaseClass);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFriend);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFunctionArgType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFuncDebugStart);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagFuncDebugEnd);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagUsingNamespace);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagVTableShape);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagVTable);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagCustom);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagThunk);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagCustomType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagManagedType);
|
|
|
|
|
DEF_PY_CONST_ULONG(SymTagDimension);
|
2011-09-21 06:17:40 +08:00
|
|
|
|
python::scope().attr("diaSymTagName") =
|
|
|
|
|
genDict(pyDia::Symbol::symTagName, _countof(pyDia::Symbol::symTagName));
|
2011-09-17 02:07:00 +08:00
|
|
|
|
|
|
|
|
|
// search options for symbol and file names
|
|
|
|
|
DEF_PY_CONST_ULONG(nsfCaseSensitive);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsfCaseInsensitive);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsfFNameExt);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsfRegularExpression);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsfUndecoratedName);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsCaseSensitive);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsCaseInsensitive);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsFNameExt);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsRegularExpression);
|
|
|
|
|
DEF_PY_CONST_ULONG(nsCaseInRegularExpression);
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-19 00:50:42 +08:00
|
|
|
|
// location type
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsNull);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsStatic);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsTLS);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsRegRel);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsThisRel);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsEnregistered);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsBitField);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsSlot);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsIlRel);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocInMetaData);
|
|
|
|
|
DEF_PY_CONST_ULONG(LocIsConstant);
|
2011-09-21 06:17:40 +08:00
|
|
|
|
python::scope().attr("diaLocTypeName") =
|
2011-09-29 15:53:45 +08:00
|
|
|
|
genDict(pyDia::Symbol::locTypeName, _countof(pyDia::Symbol::locTypeName));
|
2011-09-21 06:17:40 +08:00
|
|
|
|
|
|
|
|
|
DEF_PY_CONST_ULONG(btNoType);
|
|
|
|
|
DEF_PY_CONST_ULONG(btVoid);
|
|
|
|
|
DEF_PY_CONST_ULONG(btChar);
|
|
|
|
|
DEF_PY_CONST_ULONG(btWChar);
|
|
|
|
|
DEF_PY_CONST_ULONG(btInt);
|
|
|
|
|
DEF_PY_CONST_ULONG(btUInt);
|
|
|
|
|
DEF_PY_CONST_ULONG(btFloat);
|
|
|
|
|
DEF_PY_CONST_ULONG(btBCD);
|
|
|
|
|
DEF_PY_CONST_ULONG(btBool);
|
|
|
|
|
DEF_PY_CONST_ULONG(btLong);
|
|
|
|
|
DEF_PY_CONST_ULONG(btULong);
|
|
|
|
|
DEF_PY_CONST_ULONG(btCurrency);
|
|
|
|
|
DEF_PY_CONST_ULONG(btDate);
|
|
|
|
|
DEF_PY_CONST_ULONG(btVariant);
|
|
|
|
|
DEF_PY_CONST_ULONG(btComplex);
|
|
|
|
|
DEF_PY_CONST_ULONG(btBit);
|
|
|
|
|
DEF_PY_CONST_ULONG(btBSTR);
|
|
|
|
|
DEF_PY_CONST_ULONG(btHresult);
|
|
|
|
|
python::scope().attr("diaBasicType") =
|
|
|
|
|
genDict(pyDia::Symbol::basicTypeName, pyDia::Symbol::cntBasicTypeName);
|
2011-09-19 00:50:42 +08:00
|
|
|
|
|
2011-09-22 19:20:31 +08:00
|
|
|
|
DEF_PY_CONST_ULONG(UdtStruct);
|
|
|
|
|
DEF_PY_CONST_ULONG(UdtClass);
|
|
|
|
|
DEF_PY_CONST_ULONG(UdtUnion);
|
|
|
|
|
python::scope().attr("diaUdtKind") =
|
|
|
|
|
genDict(pyDia::Symbol::udtKindName, pyDia::Symbol::cntUdtKindName);
|
|
|
|
|
|
2011-09-23 05:54:27 +08:00
|
|
|
|
// i386/amd64 cpu registers
|
|
|
|
|
#include "diaregs.h"
|
|
|
|
|
python::scope().attr("diaI386Regs") =
|
|
|
|
|
genDict(pyDia::Symbol::i386RegName, pyDia::Symbol::cntI386RegName);
|
|
|
|
|
python::scope().attr("diaAmd64Regs") =
|
|
|
|
|
genDict(pyDia::Symbol::amd64RegName, pyDia::Symbol::cntAmd64RegName);
|
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
// exception:
|
2011-09-21 23:53:02 +08:00
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
// base exception
|
2011-09-21 23:53:02 +08:00
|
|
|
|
python::class_<pykd::DbgException> dbgExceptionClass( "BaseException",
|
2011-09-17 01:13:40 +08:00
|
|
|
|
"Pykd base exception class",
|
|
|
|
|
python::no_init );
|
|
|
|
|
dbgExceptionClass
|
|
|
|
|
.def( python::init<std::string>( python::args("desc"), "constructor" ) )
|
2011-09-21 23:53:02 +08:00
|
|
|
|
.def( "desc", &pykd::DbgException::getDesc,
|
2011-09-17 03:23:25 +08:00
|
|
|
|
"Get exception description" )
|
2011-09-21 23:53:02 +08:00
|
|
|
|
.def( "__str__", &pykd::DbgException::print);
|
|
|
|
|
pykd::DbgException::setTypeObject( dbgExceptionClass.ptr() );
|
|
|
|
|
boost::python::register_exception_translator<pykd::DbgException>(
|
|
|
|
|
&pykd::DbgException::exceptionTranslate );
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
// DIA exceptions
|
2011-09-21 06:31:51 +08:00
|
|
|
|
python::class_<pyDia::Exception, python::bases<DbgException> > diaException(
|
|
|
|
|
"DiaException", "Debug interface access exception",
|
|
|
|
|
python::no_init );
|
|
|
|
|
diaException
|
|
|
|
|
.def( "hres", &pyDia::Exception::getRes );
|
2011-09-17 01:13:40 +08:00
|
|
|
|
pyDia::Exception::setTypeObject( diaException.ptr() );
|
|
|
|
|
boost::python::register_exception_translator<pyDia::Exception>(
|
|
|
|
|
&pyDia::Exception::exceptionTranslate );
|
|
|
|
|
}
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-17 02:07:00 +08:00
|
|
|
|
#undef DEF_PY_CONST_ULONG
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-09-17 01:13:40 +08:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2011-09-12 14:59:11 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
WindbgGlobalSession::WindbgGlobalSession() {
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
PyImport_AppendInittab("pykd", initpykd );
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
PyEval_InitThreads();
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
Py_Initialize();
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
main = boost::python::import("__main__");
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::object main_namespace = main.attr("__dict__");
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> from pykd import *
|
|
|
|
|
python::object pykd = boost::python::import( "pykd" );
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
python::dict pykd_namespace( pykd.attr("__dict__") );
|
|
|
|
|
|
|
|
|
|
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 ];
|
2011-10-06 14:26:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pyState = PyEval_SaveThread();
|
2011-10-03 19:34:36 +08:00
|
|
|
|
}
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
volatile LONG WindbgGlobalSession::sessionCount = 0;
|
|
|
|
|
|
|
|
|
|
WindbgGlobalSession *WindbgGlobalSession::windbgGlobalSession = NULL;
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
|
|
|
CALLBACK
|
|
|
|
|
DebugExtensionInitialize(
|
|
|
|
|
OUT PULONG Version,
|
|
|
|
|
OUT PULONG Flags )
|
|
|
|
|
{
|
|
|
|
|
*Version = DEBUG_EXTENSION_VERSION( 1, 0 );
|
|
|
|
|
*Flags = 0;
|
|
|
|
|
|
|
|
|
|
WindbgGlobalSession::StartWindbgSession();
|
|
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
|
CALLBACK
|
|
|
|
|
DebugExtensionUninitialize()
|
|
|
|
|
{
|
|
|
|
|
WindbgGlobalSession::StopWindbgSession();
|
|
|
|
|
}
|
2011-09-15 22:16:20 +08:00
|
|
|
|
|
2011-09-12 14:59:11 +08:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
|
|
|
|
HRESULT
|
|
|
|
|
CALLBACK
|
|
|
|
|
py( PDEBUG_CLIENT4 client, PCSTR args )
|
|
|
|
|
{
|
|
|
|
|
DebugClientPtr dbgClient = DebugClient::createDbgClient( client );
|
|
|
|
|
DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient );
|
|
|
|
|
|
2011-10-06 14:26:25 +08:00
|
|
|
|
WindbgGlobalSession::RestorePyState();
|
|
|
|
|
|
2011-10-03 15:40:27 +08:00
|
|
|
|
PyThreadState *globalInterpreter = PyThreadState_Swap( NULL );
|
|
|
|
|
PyThreadState *localInterpreter = Py_NewInterpreter();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
2011-10-07 14:30:09 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> exec_file )
|
2011-10-10 19:19:12 +08:00
|
|
|
|
python::object main = python::import("__main__");
|
2011-10-07 14:30:09 +08:00
|
|
|
|
|
2011-10-10 19:19:12 +08:00
|
|
|
|
python::object global(main.attr("__dict__"));
|
2011-10-07 14:30:09 +08:00
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> print )
|
|
|
|
|
|
2011-10-10 19:19:12 +08:00
|
|
|
|
python::object sys = python::import("sys");
|
2011-10-07 14:30:09 +08:00
|
|
|
|
|
|
|
|
|
sys.attr("stdout") = python::object( dbgClient->dout() );
|
|
|
|
|
sys.attr("stdin") = python::object( dbgClient->din() );
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> traceback <20> )
|
|
|
|
|
boost::python::object tracebackModule = python::import("traceback");
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
typedef boost::escaped_list_separator<char> char_separator_t;
|
|
|
|
|
typedef boost::tokenizer< char_separator_t > char_tokenizer_t;
|
|
|
|
|
|
|
|
|
|
std::string argsStr( args );
|
|
|
|
|
|
|
|
|
|
char_tokenizer_t token( argsStr , char_separator_t( "", " \t", "\"" ) );
|
|
|
|
|
std::vector<std::string> argsList;
|
|
|
|
|
|
|
|
|
|
for ( char_tokenizer_t::iterator it = token.begin(); it != token.end(); ++it )
|
|
|
|
|
{
|
|
|
|
|
if ( *it != "" )
|
|
|
|
|
argsList.push_back( *it );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( argsList.size() == 0 )
|
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
|
|
char **pythonArgs = new char* [ argsList.size() ];
|
|
|
|
|
|
|
|
|
|
for ( size_t i = 0; i < argsList.size(); ++i )
|
|
|
|
|
pythonArgs[i] = const_cast<char*>( argsList[i].c_str() );
|
|
|
|
|
|
|
|
|
|
PySys_SetArgv( (int)argsList.size(), pythonArgs );
|
|
|
|
|
|
|
|
|
|
delete[] pythonArgs;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::string scriptName;
|
|
|
|
|
std::string filePath;
|
|
|
|
|
DbgPythonPath dbgPythonPath;
|
|
|
|
|
|
|
|
|
|
if ( !dbgPythonPath.findPath( argsList[0], scriptName, filePath ) )
|
|
|
|
|
{
|
|
|
|
|
dbgClient->eprintln( L"script file not found" );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
python::object result;
|
2011-10-03 15:40:27 +08:00
|
|
|
|
|
2011-10-07 14:30:09 +08:00
|
|
|
|
result = python::exec_file( scriptName.c_str(), global, global );
|
|
|
|
|
}
|
|
|
|
|
catch( boost::python::error_already_set const & )
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL;
|
|
|
|
|
|
|
|
|
|
PyErr_Fetch( &errtype, &errvalue, &traceback );
|
|
|
|
|
|
|
|
|
|
if(errvalue != NULL)
|
|
|
|
|
{
|
|
|
|
|
PyObject *errvalueStr= PyUnicode_FromObject(errvalue);
|
|
|
|
|
|
|
|
|
|
dbgClient->eprintln( PyUnicode_AS_UNICODE( errvalueStr ) );
|
|
|
|
|
|
|
|
|
|
if ( traceback )
|
|
|
|
|
{
|
|
|
|
|
python::object traceObj( python::handle<>( python::borrowed( traceback ) ) );
|
|
|
|
|
|
|
|
|
|
dbgClient->eprintln( L"\nTraceback:" );
|
|
|
|
|
|
|
|
|
|
python::object pFunc( tracebackModule.attr("format_tb") );
|
|
|
|
|
python::list traceList( pFunc( traceObj ) );
|
|
|
|
|
|
|
|
|
|
for ( long i = 0; i < python::len(traceList); ++i )
|
|
|
|
|
dbgClient->eprintln( python::extract<std::wstring>(traceList[i]) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Py_DECREF(errvalueStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Py_XDECREF(errvalue);
|
|
|
|
|
Py_XDECREF(errtype);
|
|
|
|
|
Py_XDECREF(traceback);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-03 15:40:27 +08:00
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
2011-10-07 14:30:09 +08:00
|
|
|
|
dbgClient->eprintln( L"unexpected error" );
|
2011-10-03 15:40:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Py_EndInterpreter( localInterpreter );
|
|
|
|
|
PyThreadState_Swap( globalInterpreter );
|
|
|
|
|
|
2011-10-06 14:26:25 +08:00
|
|
|
|
WindbgGlobalSession::SavePyState();
|
|
|
|
|
|
2011-10-03 15:40:27 +08:00
|
|
|
|
DebugClient::setDbgClientCurrent( oldClient );
|
|
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
|
|
|
CALLBACK
|
|
|
|
|
pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
|
|
|
|
{
|
2011-10-03 19:34:36 +08:00
|
|
|
|
DebugClientPtr dbgClient = DebugClient::createDbgClient( client );
|
|
|
|
|
DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient );
|
|
|
|
|
|
2011-10-06 14:26:25 +08:00
|
|
|
|
WindbgGlobalSession::RestorePyState();
|
|
|
|
|
|
2011-10-03 19:34:36 +08:00
|
|
|
|
try {
|
|
|
|
|
|
2011-10-10 19:19:12 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
|
|
|
|
|
python::object sys = python::import("sys");
|
|
|
|
|
|
|
|
|
|
sys.attr("stdout") = python::object( DbgOut( client ) );
|
|
|
|
|
sys.attr("stdin") = python::object( DbgIn( client ) );
|
|
|
|
|
|
|
|
|
|
client->SetOutputMask( DEBUG_OUTPUT_NORMAL );
|
|
|
|
|
//client->SetInputCallbacks( NULL );
|
|
|
|
|
|
|
|
|
|
PyRun_String(
|
|
|
|
|
"__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()",
|
|
|
|
|
Py_file_input,
|
|
|
|
|
WindbgGlobalSession::global().ptr(),
|
|
|
|
|
WindbgGlobalSession::global().ptr()
|
|
|
|
|
);
|
2011-10-03 19:34:36 +08:00
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
2011-10-07 14:30:09 +08:00
|
|
|
|
dbgClient->eprintln( L"unexpected error" );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2011-10-06 14:26:25 +08:00
|
|
|
|
WindbgGlobalSession::SavePyState();
|
2011-10-03 19:34:36 +08:00
|
|
|
|
|
2011-10-06 14:26:25 +08:00
|
|
|
|
DebugClient::setDbgClientCurrent( oldClient );
|
2011-10-03 19:34:36 +08:00
|
|
|
|
|
2011-10-03 15:40:27 +08:00
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-12 14:59:11 +08:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|