mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] fixed : multiple bug with WOW64 debugging
git-svn-id: https://pykd.svn.codeplex.com/svn@81305 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
2ef78de6cf
commit
ed0831362b
@ -186,14 +186,14 @@ std::string BasicTypedVar::printValue()
|
|||||||
|
|
||||||
BaseTypeVariant PtrTypedVar::getValue()
|
BaseTypeVariant PtrTypedVar::getValue()
|
||||||
{
|
{
|
||||||
return m_varData->readPtr();
|
return m_varData->readPtr( getSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypedVarPtr PtrTypedVar::deref()
|
TypedVarPtr PtrTypedVar::deref()
|
||||||
{
|
{
|
||||||
VarDataPtr varData = VarDataMemory::factory( m_varData->readPtr() );
|
VarDataPtr varData = VarDataMemory::factory( m_varData->readPtr( getSize() ) );
|
||||||
return TypedVar::getTypedVar( m_typeInfo->deref(), varData );
|
return TypedVar::getTypedVar( m_typeInfo->deref(), varData );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
|
|||||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||||
typeInfo->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
typeInfo->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||||
|
|
||||||
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr();
|
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr( typeInfo->ptrSize() );
|
||||||
|
|
||||||
VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
|
VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
|
||||||
|
|
||||||
@ -545,14 +545,16 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
|
|||||||
|
|
||||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
||||||
|
|
||||||
|
ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord;
|
||||||
|
|
||||||
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
||||||
{
|
{
|
||||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
|
for( entryAddress = ptrFunc( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrFunc( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
|
||||||
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) );
|
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
for( entryAddress = ptrFunc( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrFunc( entryAddress ) )
|
||||||
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ ULONG64 TypeInfo::getOffset( const std::string &fullName )
|
|||||||
TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
|
TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
|
||||||
{
|
{
|
||||||
ULONG symTag = typeSym->getSymTag();
|
ULONG symTag = typeSym->getSymTag();
|
||||||
|
TypeInfoPtr ptr;
|
||||||
|
|
||||||
switch( symTag )
|
switch( symTag )
|
||||||
{
|
{
|
||||||
@ -134,44 +135,59 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
|
|||||||
|
|
||||||
if ( typeSym->getLocType() == LocIsBitField )
|
if ( typeSym->getLocType() == LocIsBitField )
|
||||||
{
|
{
|
||||||
return TypeInfoPtr( new BitFieldTypeInfo(typeSym) );
|
ptr = TypeInfoPtr( new BitFieldTypeInfo(typeSym) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeSym->getDataKind() == DataIsConstant )
|
if ( typeSym->getDataKind() == DataIsConstant )
|
||||||
{
|
{
|
||||||
BaseTypeVariant constVal;
|
BaseTypeVariant constVal;
|
||||||
typeSym->getValue( constVal );
|
typeSym->getValue( constVal );
|
||||||
TypeInfoPtr ptr = getTypeInfo( typeSym->getType() );
|
ptr = getTypeInfo( typeSym->getType() );
|
||||||
ptr->setConstant( constVal );
|
ptr->setConstant( constVal );
|
||||||
return ptr;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTypeInfo( typeSym->getType() );
|
ptr = getTypeInfo( typeSym->getType() );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagBaseType:
|
case SymTagBaseType:
|
||||||
return getBaseTypeInfo( typeSym );
|
ptr = getBaseTypeInfo( typeSym );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagUDT:
|
case SymTagUDT:
|
||||||
case SymTagBaseClass:
|
case SymTagBaseClass:
|
||||||
return TypeInfoPtr( new UdtTypeInfo( typeSym ) );
|
ptr = TypeInfoPtr( new UdtTypeInfo( typeSym ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagArrayType:
|
case SymTagArrayType:
|
||||||
return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
ptr = TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagPointerType:
|
case SymTagPointerType:
|
||||||
return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
ptr = TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagVTable:
|
case SymTagVTable:
|
||||||
return TypeInfoPtr( new PointerTypeInfo( typeSym->getType() ) );
|
ptr = TypeInfoPtr( new PointerTypeInfo( typeSym->getType() ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagEnum:
|
case SymTagEnum:
|
||||||
return TypeInfoPtr( new EnumTypeInfo( typeSym ) );
|
ptr = TypeInfoPtr( new EnumTypeInfo( typeSym ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case SymTagTypedef:
|
case SymTagTypedef:
|
||||||
return getTypeInfo( typeSym->getType() );
|
ptr = getTypeInfo( typeSym->getType() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw TypeException( typeSym->getName(), "this type is not supported" );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw TypeException( typeSym->getName(), "this type is not supported" );
|
if ( ptr )
|
||||||
|
ptr->m_ptrSize = (typeSym->getMachineType() == IMAGE_FILE_MACHINE_AMD64) ? 8 : 4;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -58,7 +58,8 @@ public:
|
|||||||
m_virtualMember( false ),
|
m_virtualMember( false ),
|
||||||
m_virtualBasePtr( 0 ),
|
m_virtualBasePtr( 0 ),
|
||||||
m_virtualDispIndex( 0 ),
|
m_virtualDispIndex( 0 ),
|
||||||
m_virtualDispSize( 0 )
|
m_virtualDispSize( 0 ),
|
||||||
|
m_ptrSize( 0 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::string print() {
|
virtual std::string print() {
|
||||||
@ -215,6 +216,10 @@ public:
|
|||||||
return this == rhs;
|
return this == rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG ptrSize() const {
|
||||||
|
return m_ptrSize;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string getComplexName();
|
std::string getComplexName();
|
||||||
@ -242,6 +247,8 @@ protected:
|
|||||||
ULONG m_virtualDispSize;
|
ULONG m_virtualDispSize;
|
||||||
|
|
||||||
TypeInfoPtr m_virtualBaseType;
|
TypeInfoPtr m_virtualBaseType;
|
||||||
|
|
||||||
|
ULONG m_ptrSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -51,9 +51,9 @@ void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG64 VarDataMemory::readPtr() const
|
ULONG64 VarDataMemory::readPtr( ULONG ptrSize ) const
|
||||||
{
|
{
|
||||||
return ptrPtr( m_addr );
|
return ptrSize == 4 ? ptrDWord( m_addr ) : ptrQWord( m_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -64,53 +64,7 @@ VarDataConst::VarDataConst( SymbolPtr &symData) :
|
|||||||
symData->getValue(m_value);
|
symData->getValue(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VARIANT vtValue = {0};
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
// symData->getValue(vtValue);
|
|
||||||
//
|
|
||||||
// switch (vtValue.vt)
|
|
||||||
// {
|
|
||||||
// case VT_I1:
|
|
||||||
// case VT_UI1:
|
|
||||||
// fillDataBuff(vtValue.bVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_BOOL:
|
|
||||||
// fillDataBuff(!!vtValue.iVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_I2:
|
|
||||||
// case VT_UI2:
|
|
||||||
// fillDataBuff(vtValue.iVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_I4:
|
|
||||||
// case VT_UI4:
|
|
||||||
// case VT_INT:
|
|
||||||
// case VT_UINT:
|
|
||||||
// case VT_ERROR:
|
|
||||||
// case VT_HRESULT:
|
|
||||||
// fillDataBuff(vtValue.lVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_I8:
|
|
||||||
// case VT_UI8:
|
|
||||||
// fillDataBuff(vtValue.llVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_R4:
|
|
||||||
// fillDataBuff(vtValue.fltVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case VT_R8:
|
|
||||||
// fillDataBuff(vtValue.dblVal);
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// default:
|
|
||||||
// throw DbgException( "Unsupported const value" );
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string VarDataConst::asString() const
|
std::string VarDataConst::asString() const
|
||||||
{
|
{
|
||||||
@ -144,9 +98,11 @@ void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////'
|
//////////////////////////////////////////////////////////////////////////////////'
|
||||||
|
|
||||||
ULONG64 VarDataConst::readPtr() const
|
ULONG64 VarDataConst::readPtr( ULONG ptrSize ) const
|
||||||
{
|
{
|
||||||
return boost::apply_visitor( VariantToULong64(), m_value );
|
return ptrSize == 4 ?
|
||||||
|
boost::apply_visitor( VariantToULong64(), m_value ) :
|
||||||
|
boost::apply_visitor( VariantToULong(), m_value );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -26,7 +26,7 @@ public:
|
|||||||
virtual ULONG64 getAddr() const = 0;
|
virtual ULONG64 getAddr() const = 0;
|
||||||
virtual VarDataPtr fork(ULONG offset) const = 0;
|
virtual VarDataPtr fork(ULONG offset) const = 0;
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
|
||||||
virtual ULONG64 readPtr() const = 0;
|
virtual ULONG64 readPtr( ULONG ptrSize ) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// variable in memory
|
// variable in memory
|
||||||
@ -40,7 +40,7 @@ public:
|
|||||||
virtual VarDataPtr fork(ULONG offset) const;
|
virtual VarDataPtr fork(ULONG offset) const;
|
||||||
|
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
||||||
virtual ULONG64 readPtr() const;
|
virtual ULONG64 readPtr(ULONG ptrSize) const;
|
||||||
|
|
||||||
static VarDataPtr factory(ULONG64 addr) {
|
static VarDataPtr factory(ULONG64 addr) {
|
||||||
return VarDataPtr( new VarDataMemory(addr) );
|
return VarDataPtr( new VarDataMemory(addr) );
|
||||||
@ -65,7 +65,7 @@ public:
|
|||||||
virtual VarDataPtr fork(ULONG offset) const;
|
virtual VarDataPtr fork(ULONG offset) const;
|
||||||
|
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
||||||
virtual ULONG64 readPtr() const;
|
virtual ULONG64 readPtr(ULONG ptrSize) const;
|
||||||
|
|
||||||
static VarDataPtr factory(SymbolPtr &symData) {
|
static VarDataPtr factory(SymbolPtr &symData) {
|
||||||
return VarDataPtr( new VarDataConst(symData) );
|
return VarDataPtr( new VarDataConst(symData) );
|
||||||
@ -75,21 +75,11 @@ protected:
|
|||||||
VarDataConst(SymbolPtr &symData);
|
VarDataConst(SymbolPtr &symData);
|
||||||
VarDataConst(const VarDataConst &from, ULONG fieldOffset);
|
VarDataConst(const VarDataConst &from, ULONG fieldOffset);
|
||||||
|
|
||||||
//template<typename T>
|
|
||||||
//void fillDataBuff(const T &data)
|
|
||||||
//{
|
|
||||||
// RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) );
|
|
||||||
//}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
BaseTypeVariant m_value;
|
BaseTypeVariant m_value;
|
||||||
ULONG m_fieldOffset;
|
ULONG m_fieldOffset;
|
||||||
|
|
||||||
//ULONG m_fieldOffset;
|
|
||||||
//boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ from pykd import dprint
|
|||||||
def printAllSamples():
|
def printAllSamples():
|
||||||
dprintln( "<b>User mode</b>", True)
|
dprintln( "<b>User mode</b>", True)
|
||||||
dprintln( "Get critical sections list <link cmd=\"!py samples run um.critlist\">Run</link> <link cmd=\"!py samples source um.critlist\">Source</link>", True)
|
dprintln( "Get critical sections list <link cmd=\"!py samples run um.critlist\">Run</link> <link cmd=\"!py samples source um.critlist\">Source</link>", True)
|
||||||
|
dprintln( "Get module list from PEB <link cmd=\"!py samples run um.ldr\">Run</link> <link cmd=\"!py samples source um.ldr\">Source</link>", True)
|
||||||
dprintln( "<b>Kernel mode</b>", True )
|
dprintln( "<b>Kernel mode</b>", True )
|
||||||
dprintln( "Get process list <link cmd=\"!py samples run km.proclist\">Run</link> <link cmd=\"!py samples source km.proclist\">Source</link>", True)
|
dprintln( "Get process list <link cmd=\"!py samples run km.proclist\">Run</link> <link cmd=\"!py samples source km.proclist\">Source</link>", True)
|
||||||
dprintln( "Get kernel service list <link cmd=\"!py samples run km.ssdt\">Run</link> <link cmd=\"!py samples source km.ssdt\">Source</link>", True)
|
dprintln( "Get kernel service list <link cmd=\"!py samples run km.ssdt\">Run</link> <link cmd=\"!py samples source km.ssdt\">Source</link>", True)
|
||||||
|
34
samples/um/critlist.py
Normal file
34
samples/um/critlist.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from pykd import *
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def listCritSections():
|
||||||
|
|
||||||
|
ntdll = module("ntdll")
|
||||||
|
|
||||||
|
dbglst = ntdll.typedVarList( ntdll.RtlCriticalSectionList, "_RTL_CRITICAL_SECTION_DEBUG", "ProcessLocksList" )
|
||||||
|
|
||||||
|
crtlst = [ ntdll.typedVar( "_RTL_CRITICAL_SECTION", x.CriticalSection ) for x in dbglst ]
|
||||||
|
|
||||||
|
for crtsec in crtlst:
|
||||||
|
dprintln("")
|
||||||
|
dprintln( "CRITICAL SECTION address = %#x ( %s ) " % ( crtsec, findSymbol( crtsec ) ) )
|
||||||
|
dprintln( " Owning thread = %x" % crtsec.OwningThread )
|
||||||
|
dprintln( " Lock count = %d" % crtsec.LockCount )
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
if isKernelDebugging():
|
||||||
|
dprintln( "not a user debugging" )
|
||||||
|
break
|
||||||
|
|
||||||
|
listCritSections()
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run()
|
54
samples/um/ldr.py
Normal file
54
samples/um/ldr.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
from pykd import *
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def listModuleFromLdr64():
|
||||||
|
|
||||||
|
dprintln( "<u>64 bit modules:</u>", True )
|
||||||
|
|
||||||
|
peb = typedVar( "ntdll!PEB", getCurrentProcess() )
|
||||||
|
|
||||||
|
moduleLst = typedVarList( peb.Ldr.deref().InLoadOrderModuleList, "ntdll!_LDR_DATA_TABLE_ENTRY", "InMemoryOrderLinks" )
|
||||||
|
|
||||||
|
for mod in moduleLst:
|
||||||
|
name = typedVar( "ntdll!_UNICODE_STRING", mod.BaseDllName )
|
||||||
|
dprintln(loadWChars(name.Buffer, name.Length/2))
|
||||||
|
|
||||||
|
dprintln( "\n<u>32 bit modules:</u>", True)
|
||||||
|
|
||||||
|
peb32 = typedVar( "ntdll32!_PEB", getCurrentProcess() - pageSize() )
|
||||||
|
|
||||||
|
moduleLst = typedVarList( peb32.Ldr.deref().InLoadOrderModuleList, "ntdll32!_LDR_DATA_TABLE_ENTRY", "InMemoryOrderLinks" )
|
||||||
|
|
||||||
|
for mod in moduleLst:
|
||||||
|
name = typedVar( "ntdll32!_UNICODE_STRING", mod.BaseDllName )
|
||||||
|
dprintln(loadWChars(name.Buffer, name.Length/2))
|
||||||
|
|
||||||
|
def listModuleFromLdr():
|
||||||
|
|
||||||
|
peb = typedVar( "ntdll!PEB", getCurrentProcess() )
|
||||||
|
|
||||||
|
moduleLst = typedVarList( peb.Ldr.deref().InLoadOrderModuleList, "ntdll!_LDR_DATA_TABLE_ENTRY", "InMemoryOrderLinks" )
|
||||||
|
|
||||||
|
for mod in moduleLst:
|
||||||
|
dprintln(loadUnicodeString(mod.BaseDllName))
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
if isKernelDebugging():
|
||||||
|
dprintln( "not a user debugging" )
|
||||||
|
break
|
||||||
|
|
||||||
|
if is64bitSystem():
|
||||||
|
listModuleFromLdr64()
|
||||||
|
else:
|
||||||
|
listModuleFromLdr()
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run()
|
Loading…
Reference in New Issue
Block a user