mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 02:53:22 +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()
|
||||
{
|
||||
return m_varData->readPtr();
|
||||
return m_varData->readPtr( getSize() );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
|
||||
ULONG 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);
|
||||
|
||||
@ -545,14 +545,16 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
|
||||
|
||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
||||
|
||||
ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord;
|
||||
|
||||
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 ) );
|
||||
}
|
||||
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 ) );
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,7 @@ ULONG64 TypeInfo::getOffset( const std::string &fullName )
|
||||
TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
|
||||
{
|
||||
ULONG symTag = typeSym->getSymTag();
|
||||
TypeInfoPtr ptr;
|
||||
|
||||
switch( symTag )
|
||||
{
|
||||
@ -134,44 +135,59 @@ TypeInfoPtr TypeInfo::getTypeInfo( SymbolPtr &typeSym )
|
||||
|
||||
if ( typeSym->getLocType() == LocIsBitField )
|
||||
{
|
||||
return TypeInfoPtr( new BitFieldTypeInfo(typeSym) );
|
||||
ptr = TypeInfoPtr( new BitFieldTypeInfo(typeSym) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( typeSym->getDataKind() == DataIsConstant )
|
||||
{
|
||||
BaseTypeVariant constVal;
|
||||
typeSym->getValue( constVal );
|
||||
TypeInfoPtr ptr = getTypeInfo( typeSym->getType() );
|
||||
ptr = getTypeInfo( typeSym->getType() );
|
||||
ptr->setConstant( constVal );
|
||||
return ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
return getTypeInfo( typeSym->getType() );
|
||||
ptr = getTypeInfo( typeSym->getType() );
|
||||
break;
|
||||
|
||||
case SymTagBaseType:
|
||||
return getBaseTypeInfo( typeSym );
|
||||
ptr = getBaseTypeInfo( typeSym );
|
||||
break;
|
||||
|
||||
case SymTagUDT:
|
||||
case SymTagBaseClass:
|
||||
return TypeInfoPtr( new UdtTypeInfo( typeSym ) );
|
||||
ptr = TypeInfoPtr( new UdtTypeInfo( typeSym ) );
|
||||
break;
|
||||
|
||||
case SymTagArrayType:
|
||||
return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
||||
ptr = TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
|
||||
break;
|
||||
|
||||
case SymTagPointerType:
|
||||
return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
||||
ptr = TypeInfoPtr( new PointerTypeInfo( typeSym ) );
|
||||
break;
|
||||
|
||||
case SymTagVTable:
|
||||
return TypeInfoPtr( new PointerTypeInfo( typeSym->getType() ) );
|
||||
ptr = TypeInfoPtr( new PointerTypeInfo( typeSym->getType() ) );
|
||||
break;
|
||||
|
||||
case SymTagEnum:
|
||||
return TypeInfoPtr( new EnumTypeInfo( typeSym ) );
|
||||
ptr = TypeInfoPtr( new EnumTypeInfo( typeSym ) );
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -731,7 +747,7 @@ void UdtTypeInfo::getFields(
|
||||
|
||||
void UdtTypeInfo::getVirtualFields()
|
||||
{
|
||||
ULONG childCount = m_dia->getChildCount(SymTagBaseClass);
|
||||
ULONG childCount = m_dia->getChildCount(SymTagBaseClass);
|
||||
|
||||
for ( ULONG i = 0; i < childCount; ++i )
|
||||
{
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
m_virtualMember( false ),
|
||||
m_virtualBasePtr( 0 ),
|
||||
m_virtualDispIndex( 0 ),
|
||||
m_virtualDispSize( 0 )
|
||||
m_virtualDispSize( 0 ),
|
||||
m_ptrSize( 0 )
|
||||
{}
|
||||
|
||||
virtual std::string print() {
|
||||
@ -215,6 +216,10 @@ public:
|
||||
return this == rhs;
|
||||
}
|
||||
|
||||
ULONG ptrSize() const {
|
||||
return m_ptrSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::string getComplexName();
|
||||
@ -242,6 +247,8 @@ protected:
|
||||
ULONG m_virtualDispSize;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
@ -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 VarDataPtr fork(ULONG offset) 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
|
||||
@ -40,7 +40,7 @@ public:
|
||||
virtual VarDataPtr fork(ULONG offset) 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) {
|
||||
return VarDataPtr( new VarDataMemory(addr) );
|
||||
@ -65,7 +65,7 @@ public:
|
||||
virtual VarDataPtr fork(ULONG offset) 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) {
|
||||
return VarDataPtr( new VarDataConst(symData) );
|
||||
@ -75,21 +75,11 @@ protected:
|
||||
VarDataConst(SymbolPtr &symData);
|
||||
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:
|
||||
|
||||
BaseTypeVariant m_value;
|
||||
ULONG m_fieldOffset;
|
||||
|
||||
//ULONG m_fieldOffset;
|
||||
//boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ from pykd import dprint
|
||||
def printAllSamples():
|
||||
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 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( "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)
|
||||
|
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