From ed0831362bde0bf3c717047fc7a9ad1b40b0933d Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Thu, 22 Nov 2012 07:30:54 +0000 Subject: [PATCH] [0.2.x] fixed : multiple bug with WOW64 debugging git-svn-id: https://pykd.svn.codeplex.com/svn@81305 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/typedvar.cpp | 12 +++++---- pykd/typeinfo.cpp | 42 ++++++++++++++++++++---------- pykd/typeinfo.h | 9 ++++++- pykd/vardata.cpp | 58 +++++------------------------------------- pykd/vardata.h | 16 +++--------- samples/samples.py | 1 + samples/um/critlist.py | 34 +++++++++++++++++++++++++ samples/um/ldr.py | 54 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 143 insertions(+), 83 deletions(-) create mode 100644 samples/um/critlist.py create mode 100644 samples/um/ldr.py diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index c056270..b83cd9a 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -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 ) ); } diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index 182896c..3eb4886 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -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 ) { diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 96680da..c5a0c56 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -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; }; /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/vardata.cpp b/pykd/vardata.cpp index 455b274..aac55f6 100644 --- a/pykd/vardata.cpp +++ b/pykd/vardata.cpp @@ -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 ); } ////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/vardata.h b/pykd/vardata.h index d170945..d4b6904 100644 --- a/pykd/vardata.h +++ b/pykd/vardata.h @@ -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 - //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 > m_dataBuff; - - }; } diff --git a/samples/samples.py b/samples/samples.py index 59a9d08..f9a6d24 100644 --- a/samples/samples.py +++ b/samples/samples.py @@ -8,6 +8,7 @@ from pykd import dprint def printAllSamples(): dprintln( "User mode", True) dprintln( "Get critical sections list Run Source", True) + dprintln( "Get module list from PEB Run Source", True) dprintln( "Kernel mode", True ) dprintln( "Get process list Run Source", True) dprintln( "Get kernel service list Run Source", True) diff --git a/samples/um/critlist.py b/samples/um/critlist.py new file mode 100644 index 0000000..d8f0465 --- /dev/null +++ b/samples/um/critlist.py @@ -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() \ No newline at end of file diff --git a/samples/um/ldr.py b/samples/um/ldr.py new file mode 100644 index 0000000..ffa4f2b --- /dev/null +++ b/samples/um/ldr.py @@ -0,0 +1,54 @@ +from pykd import * + +def main(): + pass + +def listModuleFromLdr64(): + + dprintln( "64 bit modules:", 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( "\n32 bit modules:", 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() \ No newline at end of file