git-svn-id: https://pykd.svn.codeplex.com/svn@50344 9b283d60-5439-405e-af05-b73fd8c4d996

This commit is contained in:
SND\kernelnet_cp 2010-07-06 14:49:02 +00:00
parent 457e39a970
commit 9e57e58b88
32 changed files with 1813 additions and 0 deletions

5
kdar/cmd.py Normal file
View File

@ -0,0 +1,5 @@
from pykd import *
s = dbgCommand( "dt nt!_DRIVER_OBJECT" )
dprintln( s )

11
kdar/drvobj.py Normal file
View File

@ -0,0 +1,11 @@
from pykd import *
drvObj = typedVar( "nt", "_DRIVER_OBJECT", addr64( 0x82000c08 ) )
dprintln( "DriverName.Length = %(1)d" % { "1" : drvObj.DriverName.Length } )
for i,f in drvObj.MajorFunction.iteritems():
dprintln( "MajorFunction[%(1)d] = " % { "1" : i } + findSymbol( addr64( f ) ) )

62
kdar/idt.py Normal file
View File

@ -0,0 +1,62 @@
from pykd import *
if not is64bitSystem():
dprintln( "check interrupt handlers...\n" )
idtr = reg( "idtr" )
nt = loadModule( "nt" )
nt.KiInterruptDispatch = getOffset( "nt", "KiInterruptDispatch" )
nt.KiChainedDispatch = getOffset( "nt", "KiChainedDispatch" )
nt.KiInterruptTemplate = getOffset( "nt", "KiInterruptTemplate" )
hal = loadModule( "hal" )
ErrorCount = 0
for i in range(0,255):
idtEntry = typedVar( "nt", "_KIDTENTRY", idtr + i*8 )
if idtEntry.Selector == 8:
InterruptHandler = ( idtEntry.ExtendedOffset * 0x10000 ) + idtEntry.Offset
if InterruptHandler != 0 and not nt.contain( InterruptHandler ) and not hal.contain( InterruptHandler ):
kinterrupt = containingRecord( InterruptHandler, "nt", "_KINTERRUPT", "DispatchCode" )
dprintln ( "KINTERRUPT: %(1)x" % { "1" : kinterrupt.getAddress() } )
if addr64( kinterrupt.DispatchAddress ) != nt.KiInterruptDispatch and addr64( kinterrupt.DispatchAddress ) != nt.KiChainedDispatch:
dprintln ( "Threat!!! KINTERRUPT::DispatchAddress PATCHED" )
ErrorCount += 1
if findModule( kinterrupt.ServiceRoutine ) == None:
dprintln ( "Threat!!! KINTERRUPT::ServiceRoutine (%(1)x) out of any module" % { "1" : kinterrupt.ServiceRoutine } )
ErrorCount += 1
if not compareMemory( nt.KiInterruptTemplate, InterruptHandler, 98 ):
dprintln ( "Threat!!! KINTERRUPT::DispatchCode area PATCHED" )
ErrorCount += 1
dprintln ( "" )
dprintln( "check end: %(1)d threats" % { "1" : ErrorCount } )
else:
dprintln( "x64 is not supported" )

30
pykd.sln Normal file
View File

@ -0,0 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pykd", "pykd\pykd.vcproj", "{C0A12E93-4B76-4B17-B837-37020F957AD2}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|Win32.ActiveCfg = Debug|Win32
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|Win32.Build.0 = Debug|Win32
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|x64.ActiveCfg = Debug|x64
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|x64.Build.0 = Debug|x64
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|Win32.ActiveCfg = Release|Win32
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|Win32.Build.0 = Release|Win32
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|x64.ActiveCfg = Release|x64
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

BIN
pykd.suo Normal file

Binary file not shown.

127
pykd/dbgcmd.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgcmd.h"
#include "dbgexcept.h"
///////////////////////////////////////////////////////////////////////////////
// êëàññ äëÿ ïåðåõâàòà âûâîäà â îòëàä÷èê
class OutputReader : public IDebugOutputCallbacks {
public:
OutputReader( IDebugClient *debugClient )
{
HRESULT hres;
try {
m_debugClient = debugClient;
m_debugClient->AddRef();
hres = m_debugClient->GetOutputCallbacks( &m_previousCallback );
if ( FAILED( hres ) )
{
throw hres;
}
hres = m_debugClient->SetOutputCallbacks( this );
if ( FAILED( hres ) )
{
throw hres;
}
} catch( ... )
{
m_debugClient->Release();
m_debugClient = NULL;
}
}
~OutputReader()
{
if ( m_debugClient )
{
m_debugClient->SetOutputCallbacks( m_previousCallback );
m_debugClient->Release();
}
}
const std::string&
Line() const {
return m_readLine;
}
private:
// IUnknown.
STDMETHOD(QueryInterface)(
__in REFIID InterfaceId,
__out PVOID* Interface ) {
return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)() {
return 1L;
}
STDMETHOD_(ULONG, Release)() {
return 0L;
}
STDMETHOD(Output)(
__in ULONG Mask,
__in PCSTR Text )
{
if ( Mask == DEBUG_OUTPUT_NORMAL )
{
m_readLine += std::string( Text );
}
return S_OK;
}
private:
std::string m_readLine;
IDebugClient *m_debugClient;
IDebugOutputCallbacks *m_previousCallback;
};
///////////////////////////////////////////////////////////////////////////////
std::string
dbgCommand( const std::string &command )
{
HRESULT hres;
try {
OutputReader outReader( g_Ext->m_Client );
hres = g_Ext->m_Control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::Execute failed" );
return std::string( outReader.Line() );
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return "error";
}
///////////////////////////////////////////////////////////////////////////////

16
pykd/dbgcmd.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <string>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
std::string
dbgCommand( const std::string &command );
/////////////////////////////////////////////////////////////////////////////////

16
pykd/dbgexcept.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <exception>
/////////////////////////////////////////////////////////////////////////////////
class DbgException : public std::exception
{
public:
DbgException( const char* desc ) :
std::exception( desc )
{}
};
/////////////////////////////////////////////////////////////////////////////////

143
pykd/dbgext.cpp Normal file
View File

@ -0,0 +1,143 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include <boost/python.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include "dbgprint.h"
#include "dbgreg.h"
#include "dbgtype.h"
#include "dbgmodule.h"
#include "dbgsym.h"
#include "dbgmem.h"
#include "dbgsystem.h"
#include "dbgcmd.h"
/////////////////////////////////////////////////////////////////////////////////
BOOST_PYTHON_MODULE( pykd )
{
boost::python::def( "dprint", &DbgPrint::dprint );
boost::python::def( "dprintln", &DbgPrint::dprintln );
boost::python::def( "dbgCommand", &dbgCommand );
boost::python::def( "is64bitSystem", is64bitSystem );
boost::python::def( "reg", &loadRegister );
boost::python::def( "typedVar", &loadTypedVar );
boost::python::def( "containingRecord", &containingRecord );
boost::python::def( "loadModule", &loadModule );
boost::python::def( "findSymbol", &findSymbolForAddress );
boost::python::def( "getOffset", &findAddressForSymbol );
boost::python::def( "findModule", &findModule );
boost::python::def( "addr64", &addr64 );
boost::python::def( "compareMemory", &compareMemory );
boost::python::class_<typedVarClass>( "typedVarClass" )
.def("getAddress", &typedVarClass::getAddress );
boost::python::class_<dbgModuleClass>( "dbgModuleClass" )
.add_property("begin", &dbgModuleClass::getBegin )
.add_property("end", &dbgModuleClass::getEnd )
.def("contain", &dbgModuleClass::contain );
}
/////////////////////////////////////////////////////////////////////////////////
class EXT_CLASS : public ExtExtension
{
public:
virtual HRESULT Initialize(void) {
HRESULT hr = ExtExtension::Initialize();
if ( FAILED( hr ) )
return hr;
Py_Initialize();
PyImport_AppendInittab("pykd",initpykd );
return hr;
}
virtual void Uninitialize(void) {
Py_Finalize();
}
public:
EXT_COMMAND_METHOD( info );
EXT_COMMAND_METHOD( exec );
};
EXT_DECLARE_GLOBALS();
/////////////////////////////////////////////////////////////////////////////////
EXT_COMMAND(
info,
"Python Info",
"" )
{
Out( "Python Info" );
}
/////////////////////////////////////////////////////////////////////////////////
EXT_COMMAND(
exec,
"Execute python code",
"{f;b;;quite mode}{;x}" )
{
bool fromFile = false;
if ( HasArg( "f" ) )
fromFile = true;
try {
boost::python::object main = boost::python::import("__main__");
boost::python::object global(main.attr("__dict__"));
boost::python::object result;
if ( fromFile )
{
result = boost::python::exec_file( GetUnnamedArgStr( 0 ), global, global );
}
else
{
result = boost::python::exec( GetUnnamedArgStr( 0 ), global, global );
}
}
catch( boost::python::error_already_set const & )
{
// îøèáêà â ñêðèïòå
PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL;
PyErr_Fetch( &errtype, &errvalue, &traceback );
if(errvalue != NULL)
{
PyObject *s = PyObject_Str(errvalue);
DbgPrint::dprintln( PyString_AS_STRING( s ) );
Py_DECREF(s);
}
Py_XDECREF(errvalue);
Py_XDECREF(errtype);
Py_XDECREF(traceback);
}
catch(...)
{
}
}
/////////////////////////////////////////////////////////////////////////////////

92
pykd/dbgmem.cpp Normal file
View File

@ -0,0 +1,92 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgexcept.h"
#include "dbgmem.h"
using namespace std;
///////////////////////////////////////////////////////////////////////////////////
bool
loadMemory( ULONG64 address, PVOID dest, ULONG length )
{
address = addr64( address );
try {
HRESULT hres = g_Ext->m_Data->ReadVirtual( address, dest, length, NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpace::ReadVirtual failed" );
return true;
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "Kd2Lua unexpected error\n" );
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////
ULONG64
addr64( ULONG64 addr )
{
if ( *( (ULONG*)&addr + 1 ) == 0 )
*( (ULONG*)&addr + 1 ) = 0xFFFFFFFF;
return addr;
}
///////////////////////////////////////////////////////////////////////////////////
bool
compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length )
{
HRESULT hres;
bool result = false;
addr1 = addr64( addr1 );
addr2 = addr64( addr2 );
char* m1 = new char[length];
char* m2 = new char[length];
try {
hres = g_Ext->m_Data->ReadVirtual( addr1, m1, length, NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpace::ReadVirtual failed" );
hres = g_Ext->m_Data->ReadVirtual( addr2, m2, length, NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpace::ReadVirtual failed" );
result = memcmp( m1, m2, length ) == 0;
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "Kd2Lua unexpected error\n" );
}
delete[] m1;
delete[] m2;
return result;
}
///////////////////////////////////////////////////////////////////////////////////

14
pykd/dbgmem.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////////
bool
loadMemory( ULONG64 address, PVOID dest, ULONG length );
bool
compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length );
ULONG64
addr64( ULONG64 addr );
/////////////////////////////////////////////////////////////////////////////////

84
pykd/dbgmodule.cpp Normal file
View File

@ -0,0 +1,84 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgmodule.h"
#include "dbgexcept.h"
#include "dbgmem.h"
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadModule( const std::string &moduleName )
{
HRESULT hres;
try {
ULONG64 moduleBase;
hres = g_Ext->m_Symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
hres = g_Ext->m_Symbols->GetModuleParameters( 1, &moduleBase, 0, &moduleParam );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
return boost::python::object( dbgModuleClass( moduleBase, moduleParam.Size ) );
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::object();
}
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
findModule( ULONG64 addr )
{
HRESULT hres;
addr = addr64( addr );
try {
ULONG moduleIndex;
ULONG64 moduleBase;
hres = g_Ext->m_Symbols->GetModuleByOffset( addr, 0, &moduleIndex, &moduleBase );
if ( FAILED( hres ) )
{
return boost::python::object();
}
DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
hres = g_Ext->m_Symbols->GetModuleParameters( 1, &moduleBase, 0, &moduleParam );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
return boost::python::object( dbgModuleClass( moduleBase, moduleParam.Size ) );
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::object();
}
/////////////////////////////////////////////////////////////////////////////////

58
pykd/dbgmodule.h Normal file
View File

@ -0,0 +1,58 @@
#pragma once
#include <string>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
class dbgModuleClass {
public:
dbgModuleClass() :
m_base( 0 ),
m_end( 0 )
{}
dbgModuleClass( ULONG64 base, ULONG size ) :
m_base( base ),
m_end( base + size )
{}
ULONG64
getBegin() const {
return m_base;
}
ULONG64
getEnd() const {
return m_end;
}
bool
contain( ULONG64 addr ) const {
if ( *( (ULONG*)&addr + 1 ) == 0 )
*( (ULONG*)&addr + 1 ) = 0xFFFFFFFF;
return m_base <= addr && addr <= m_end;
}
private:
ULONG64 m_base;
ULONG64 m_end;
};
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadModule( const std::string &moduleName );
boost::python::object
findModule( ULONG64 addr );
/////////////////////////////////////////////////////////////////////////////////

16
pykd/dbgprint.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "stdafx.h"
#include "dbgprint.h"
#include <engextcpp.hpp>
using namespace std;
void DbgPrint::dprint( const string& str )
{
g_Ext->Out( str.c_str() );
}
void DbgPrint::dprintln( const std::string& str )
{
g_Ext->Out( str.c_str() );
g_Ext->Out( "\r\n" );
}

15
pykd/dbgprint.h Normal file
View File

@ -0,0 +1,15 @@
// âûâîä èíôîðìàöèè â îòëàä÷èê
#pragma once
#include <string>
class DbgPrint {
public:
static void dprint( const std::string& str );
static void dprintln( const std::string& str );
};

62
pykd/dbgreg.cpp Normal file
View File

@ -0,0 +1,62 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgreg.h"
#include "dbgexcept.h"
using namespace std;
///////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadRegister( const std::string &registerName )
{
HRESULT hres;
try {
ULONG registerIndex = 0;
hres = g_Ext->m_Registers->GetIndexByName( registerName.c_str(), &registerIndex );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetIndexByName failed" );
DEBUG_VALUE debugValue;
hres = g_Ext->m_Registers->GetValue( registerIndex, &debugValue );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetValue failed" );
switch( debugValue.Type )
{
case DEBUG_VALUE_INT8:
return boost::python::long_( debugValue.I8 );
break;
case DEBUG_VALUE_INT16:
return boost::python::long_( debugValue.I16 );
break;
case DEBUG_VALUE_INT32:
return boost::python::long_( debugValue.I32 );
break;
case DEBUG_VALUE_INT64:
return boost::python::long_(debugValue.I64 );
break;
}
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::str( "REG_ERR" );
}
///////////////////////////////////////////////////////////////////////////////////

13
pykd/dbgreg.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <string>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadRegister( const std::string &registerName );
/////////////////////////////////////////////////////////////////////////////////

105
pykd/dbgsym.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgsym.h"
#include "dbgexcept.h"
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
findSymbolForAddress( ULONG64 addr )
{
HRESULT hres;
try {
DEBUG_MODULE_AND_ID debugId;
ULONG64 displace = 0;
if ( *( (ULONG*)&addr + 1 ) == 0 )
*( (ULONG*)&addr + 1 ) = 0xFFFFFFFF;
ULONG moduleIndex;
ULONG64 moduleBase;
hres = g_Ext->m_Symbols->GetModuleByOffset( addr, 0, &moduleIndex, &moduleBase );
if ( FAILED( hres ) )
{
return boost::python::object( "out of module" );
}
char moduleName[0x100];
hres = g_Ext->m_Symbols2->GetModuleNameString( DEBUG_MODNAME_MODULE, moduleIndex, moduleBase,
moduleName, sizeof( moduleName ), NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol2::GetModuleNameString failed" );
ULONG entries = 0;
hres = g_Ext->m_Symbols3->GetSymbolEntriesByOffset( addr, 0, &debugId, &displace, 1, &entries );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol3::GetSymbolEntriesByOffset failed" );
std::stringstream ss;
if ( entries == 0 )
{
ss << moduleName << "+" << std::hex << ( addr - moduleBase );
return boost::python::object( ss.str() );
}
char symbolName[0x100];
hres = g_Ext->m_Symbols3->GetSymbolEntryString( &debugId, 0, symbolName, sizeof(symbolName ), NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol3::GetSymbolEntryString failed" );
ss << moduleName << "!" << symbolName;
return boost::python::object( ss.str() );
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::object( addr );
}
/////////////////////////////////////////////////////////////////////////////////
ULONG64
findAddressForSymbol( const std::string &moduleName, const std::string &symbolName )
{
HRESULT hres;
try {
std::string ModuleSymName = moduleName;
ModuleSymName += "!";
ModuleSymName += symbolName;
ULONG64 offset = 0ULL;
hres = g_Ext->m_Symbols->GetOffsetByName( ModuleSymName.c_str(), &offset );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetOffsetByName failed" );
return offset;
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return (ULONG64)~0;
}
/////////////////////////////////////////////////////////////////////////////////

16
pykd/dbgsym.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <string>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
findSymbolForAddress( ULONG64 addr );
ULONG64
findAddressForSymbol( const std::string &moduleName, const std::string &symbolName );
/////////////////////////////////////////////////////////////////////////////////

33
pykd/dbgsystem.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include <exception>
#include "dbgsystem.h"
/////////////////////////////////////////////////////////////////////////////////
bool
is64bitSystem()
{
HRESULT hres;
try {
hres = g_Ext->m_Control->IsPointer64Bit();
return hres == S_OK;
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////

14
pykd/dbgsystem.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////////
bool
is64bitSystem();
inline
int
ptrSize() {
return is64bitSystem() ? 8 : 4;
}
/////////////////////////////////////////////////////////////////////////////////

266
pykd/dbgtype.cpp Normal file
View File

@ -0,0 +1,266 @@
#include "stdafx.h"
#include <engextcpp.hpp>
#include "dbgtype.h"
#include "dbgexcept.h"
#include "dbgmem.h"
#include "dbgsystem.h"
using namespace std;
bool
isBaseType( const std::string &typeName );
boost::python::object
loadBaseType( const std::string &typeName, ULONG64 address, ULONG size );
typedef
boost::python::object
(*basicTypeLoader)( ULONG64 address, ULONG size );
boost::python::object
voidLoader( ULONG64 address, ULONG size ) {
return boost::python::object();
}
template< typename valType>
boost::python::object
valueLoader( ULONG64 address, ULONG size );
template<>
boost::python::object
valueLoader<void*>( ULONG64 address, ULONG size )
{
if ( is64bitSystem() )
return valueLoader<__int64>( address, size );
else
return valueLoader<long>( address, size );
}
static const char*
basicTypeNames[] = {
"unsigned char",
"char",
"unsigned short",
"short",
"unsigned long",
"long",
"<function>",
"void"
};
basicTypeLoader basicTypeLoaders[] = {
valueLoader<unsigned char>,
valueLoader<char>,
valueLoader<unsigned short>,
valueLoader<short>,
valueLoader<unsigned long>,
valueLoader<long>,
valueLoader<void*>,
voidLoader };
///////////////////////////////////////////////////////////////////////////////////
//
boost::python::object
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address )
{
HRESULT hres;
try {
ULONG64 moduleBase;
if ( typeName.find("*") < typeName.size() )
{
return valueLoader<void*>( address, ptrSize() );
}
hres = g_Ext->m_Symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
ULONG typeId;
hres = g_Ext->m_Symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeId failed" );
typedVarClass temp( address );
boost::python::object var( temp );
for ( ULONG i = 0; ; ++i )
{
char fieldName[100];
hres = g_Ext->m_Symbols2->GetFieldName( moduleBase, typeId, i, fieldName, sizeof(fieldName), NULL );
if ( FAILED( hres ) )
break;
ULONG fieldTypeId;
ULONG fieldOffset;
hres = g_Ext->m_Symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
char fieldTypeName[100];
hres = g_Ext->m_Symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
ULONG fieldSize;
hres = g_Ext->m_Symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeName failed" );
if ( isBaseType( fieldTypeName ) )
{
var.attr( fieldName ) = loadBaseType( fieldTypeName, address + fieldOffset, fieldSize );
}
else
{
var.attr( fieldName ) = loadTypedVar( moduleName, fieldTypeName, address + fieldOffset );
}
}
return var;
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::str( "VAR_ERR" );
}
///////////////////////////////////////////////////////////////////////////////////
boost::python::object
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName )
{
HRESULT hres;
try {
ULONG64 moduleBase;
hres = g_Ext->m_Symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
ULONG typeId;
hres = g_Ext->m_Symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeId failed" );
ULONG fieldTypeId;
ULONG fieldOffset;
hres = g_Ext->m_Symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
return loadTypedVar( moduleName, typeName, address - fieldOffset );
}
catch( std::exception &e )
{
g_Ext->Out( "pykd error: %s\n", e.what() );
}
catch(...)
{
g_Ext->Out( "pykd unexpected error\n" );
}
return boost::python::str( "VAR_ERR" );
}
///////////////////////////////////////////////////////////////////////////////////
bool
isBaseType( const std::string &typeName )
{
for ( int i = 0; i < sizeof( basicTypeNames ) / sizeof( char* ); ++i )
{
if ( typeName == basicTypeNames[i] )
return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadBaseType( const std::string &typeName, ULONG64 address, ULONG size )
{
for ( int i = 0; i < sizeof( basicTypeNames ) / sizeof( char* ); ++i )
{
if ( typeName == basicTypeNames[i] )
return basicTypeLoaders[i]( address, size );
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
return valueLoader<void*>( address, size );
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
return basicTypeLoaders[i]( address, size );
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
return valueLoader<void*>( address, size );
}
return boost::python::object();
}
///////////////////////////////////////////////////////////////////////////////////
template< typename valType>
boost::python::object
valueLoader( ULONG64 address, ULONG size )
{
if ( size == sizeof(valType) )
{
valType v;
if ( loadMemory( address, &v, sizeof(v) ) )
return boost::python::long_( (unsigned __int64)v );
}
else
{
boost::python::dict arr;
for ( int i = 0; i < size / sizeof(valType); ++i )
{
valType v;
if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
return boost::python::object();
arr[i] = boost::python::long_( (unsigned __int64)v );
}
return arr;
}
return boost::python::object();
}
///////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadComplexType( const std::string &typeName, ULONG64 address, ULONG size )
{
return boost::python::object();
}
///////////////////////////////////////////////////////////////////////////////////

41
pykd/dbgtype.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include <string>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
class typedVarClass {
public:
typedVarClass()
{}
typedVarClass( ULONG64 addr ) :
m_addr( addr )
{}
ULONG64
getAddress() const {
return m_addr;
}
private:
ULONG64 m_addr;
};
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address );
boost::python::object
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName );
/////////////////////////////////////////////////////////////////////////////////

0
pykd/pykd.cpp Normal file
View File

6
pykd/pykd.def Normal file
View File

@ -0,0 +1,6 @@
EXPORTS
DebugExtensionInitialize
DebugExtensionUninitialize
info
exec

BIN
pykd/pykd.suo Normal file

Binary file not shown.

488
pykd/pykd.vcproj Normal file
View File

@ -0,0 +1,488 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="pykd"
ProjectGUID="{C0A12E93-4B76-4B17-B837-37020F957AD2}"
RootNamespace="pykd"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
GeneratePreprocessedFile="0"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbgeng.lib engextcpp.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(DBG_SDK_ROOT)\lib\i386&quot;;&quot;$(PYTHON_ROOT)\libs&quot;;&quot;$(BOOST_ROOT)\stage\lib&quot;"
ModuleDefinitionFile="pykd.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
GeneratePreprocessedFile="0"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbgeng.lib engextcpp.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(DBG_SDK_ROOT)\lib\amd64&quot;;&quot;$(PYTHON_ROOT)\libs&quot;;&quot;$(BOOST_ROOT)\stage64\lib&quot;"
ModuleDefinitionFile="pykd.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbgeng.lib engextcpp.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(DBG_SDK_ROOT)\lib\i386&quot;;&quot;$(PYTHON_ROOT)\libs&quot;;&quot;$(BOOST_ROOT)\stage\lib&quot;"
ModuleDefinitionFile="pykd.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbgeng.lib engextcpp.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(DBG_SDK_ROOT)\lib\amd64&quot;;&quot;$(PYTHON_ROOT)\libs&quot;;&quot;$(BOOST_ROOT)\stage64\lib&quot;"
ModuleDefinitionFile="pykd.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\dbgcmd.cpp"
>
</File>
<File
RelativePath=".\dbgext.cpp"
>
</File>
<File
RelativePath=".\dbgmem.cpp"
>
</File>
<File
RelativePath=".\dbgmodule.cpp"
>
</File>
<File
RelativePath=".\dbgprint.cpp"
>
</File>
<File
RelativePath=".\dbgreg.cpp"
>
</File>
<File
RelativePath=".\dbgsym.cpp"
>
</File>
<File
RelativePath=".\dbgsystem.cpp"
>
</File>
<File
RelativePath=".\dbgtype.cpp"
>
</File>
<File
RelativePath=".\pykd.def"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\dbgcmd.h"
>
</File>
<File
RelativePath=".\dbgexcept.h"
>
</File>
<File
RelativePath=".\dbgmem.h"
>
</File>
<File
RelativePath=".\dbgmodule.h"
>
</File>
<File
RelativePath=".\dbgprint.h"
>
</File>
<File
RelativePath=".\dbgreg.h"
>
</File>
<File
RelativePath=".\dbgsym.h"
>
</File>
<File
RelativePath=".\dbgsystem.h"
>
</File>
<File
RelativePath=".\dbgtype.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

8
pykd/stdafx.cpp Normal file
View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// pykd.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

35
pykd/stdafx.h Normal file
View File

@ -0,0 +1,35 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#define __field_ecount_opt(x)
#define BOOST_PYTHON_STATIC_LIB
// TODO: reference additional headers your program requires here

8
test/print.py Normal file
View File

@ -0,0 +1,8 @@
from pykd import *
dprint ( "hello windbg!\n" )
dprintln ( "hello windbg!" )
hello = "hello windbg!"
dprintln( hello )
dprintln( hello + " from python" )

16
test/regs.py Normal file
View File

@ -0,0 +1,16 @@
from pykd import *
dprintln( "regs tests begin" )
al = reg("al")
ax = reg("ax")
eax = reg("eax")
dprintln( "al: " + str(al) )
dprintln( "ax: " + str(ax) )
dprintln( "eax: " + str(eax) )
dprintln( "regs tests end" )

13
test/type.py Normal file
View File

@ -0,0 +1,13 @@
from pykd import *
dprintln( "type test begin" )
idtr=reg("idtr")
var = typedVar( "nt", "_KIDTENTRY", idtr )
for t, v in var.iteritems():
dprintln( t + " : " + str(v) )
dprintln( "type test end" )