#include #include #include //IID_IStdIdentity {0000001B-0000-0000-C000-000000000046} const GUID IID_IStdIdentity = {0x0000001B,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; #include #include DECLARE_API(iid) { INIT_API(); GUID CurrUUID; ULONG_PTR pUUID = 0; pUUID = GetExpression(args); if (pUUID){ ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0); WCHAR pszClsID[40]; StringFromGUID2(CurrUUID,pszClsID,40); WCHAR pszFullPath[MAX_PATH]; lstrcpyW(pszFullPath,L"Interface\\"); lstrcatW(pszFullPath,pszClsID); char pDataA[MAX_PATH]; HKEY hKey; LONG lRes; lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT, pszFullPath, 0, KEY_READ, &hKey); if (lRes == ERROR_SUCCESS){ DWORD dwType; WCHAR pData[MAX_PATH]; DWORD dwSize=sizeof(pData); lRes = RegQueryValueExW(hKey, NULL, // default NULL, &dwType, (BYTE *)pData, &dwSize); if (lRes == ERROR_SUCCESS) { WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL); dprintf(" IID_%s\n",pDataA); } RegCloseKey(hKey); } else { if (IsEqualGUID(CurrUUID,IID_IMarshal)){ dprintf(" IID_IMarshal\n"); } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) { dprintf(" IID_IStdIdentity\n"); } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) { dprintf(" IID_ICallFactory\n"); } else { WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL); dprintf("unable to open key %s\n",pDataA); } } } else { dprintf("unable to resolve %s\n",args); } } extern ArrayCLSID g_ArrayCLSID[]; DECLARE_API(clsid) { INIT_API(); GUID CurrUUID; ULONG_PTR pUUID = 0; pUUID = GetExpression(args); if (pUUID){ ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0); WCHAR pszClsID[40]; StringFromGUID2(CurrUUID,pszClsID,40); // look-up known DWORD i; for (i=0;i\n"); dprintf(" std_queue: print the first ULONG_PTR of a std::queue\n"); dprintf(" mapobj : print a std::map\n"); dprintf(" -------- HEAP family\n"); dprintf(" he : print the HEAP_ENTRY\n"); dprintf(" hef : walks the HEAP_ENTRY list forward\n"); dprintf(" hef : walks the HEAP_ENTRY list backward\n"); dprintf(" hs : print the HEAP_SEGMENT\n"); dprintf(" hp : print the HEAP\n"); dprintf(" hps : print a summary for all the HEAP in the process\n"); dprintf(" shp : search heap HEAP for address ADDR\n"); dprintf(" rllc : prints the free list in reverse order\n"); dprintf(" hpf : prints the free list of the heap at HEAP\n"); dprintf(" php : [s ADDR] prints the pageheap and searches\n"); dprintf(" -------- FASTPROX family\n"); dprintf(" wc : print the human readable WbemClass\n"); dprintf(" wi : print the human readable WbemClass\n"); dprintf(" blob : ADDR [size] print (part of) the ClassObject BLOB\n"); dprintf(" datap : ADDR print the WBEMDATA marshaling BLOB\n"); dprintf(" cp : print the human readable CClassPart\n"); dprintf(" cvar : print the CVar\n"); dprintf(" -------- WBEMCORE\n"); dprintf(" q : print wbemcore!g_pAsyncSvcQueue\n"); dprintf(" arb : print wbemcore!CWmiArbitrator__m_pArb\n"); dprintf(" -------- REPDRVFS\n"); dprintf(" tmpall : print the Allocators in repdrvfs\n"); dprintf(" forestc : [Addr] print the repdrvfs!CForestCache at Addr\n"); dprintf(" filec : [Addr] print repdrvfs!CFileCache at Addr\n"); dprintf(" fmap : \\fs\\[objects|index].map dumps the .MAP file from disk \n"); dprintf(" btr : dumps the index.btr/index.map file from disk \n"); dprintf(" varobj : dumps part of objects.data file from disk \n"); dprintf(" -------- THREAD family\n"); dprintf(" t : print RPC and OLE data for each thread\n"); dprintf(" inv : [param] invokes a function in the remote thread\n"); dprintf(" bs : rebuilds the stack from the info in the TEB\n"); dprintf(" st : prints the num DWORD saved by RtlCaptureStackBackTrace\n"); dprintf(" lpp : print linked list and unassemble backtrace\n"); dprintf(" vq : -a | -f Flag : calls VirtualQuery on the addr\n"); dprintf(" srt : searches the stacks of all threads for addr\n"); dprintf(" ksrt : searches the stacks of all threads for addr - KD only\n"); dprintf(" el : prints the exception list of the current thread x86 only\n"); dprintf(" -------- ESS\n"); dprintf(" ess : print wbemcore!g_pNewESS\n"); dprintf(" -------- PROVSS\n"); dprintf(" pc : print wbemcore!CCoreServices__m_pProvSS\n"); dprintf(" pf : print CServerObject_BindingFactory\n"); dprintf(" -------- 32-K-64\n"); dprintf(" hef64 : HEAP_ENTRY list forward\n"); dprintf(" heb64 : HEAP_ENTRY list backward\n"); dprintf(" hps64 : print heap summary\n"); dprintf(" cs64 : print CritSec list\n"); } void EnumLinkedListCB(IN LIST_ENTRY * pListHead, IN DWORD cbSizeOfStructure, IN DWORD cbListEntryOffset, IN pfnCallBack2 CallBack) { LIST_ENTRY ListHead; LIST_ENTRY * pListEntry; DWORD cItems = 0; void * pStorage = (void *)_alloca(cbSizeOfStructure); LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset); if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL)) { if (CallBack) { } else { dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink); } for ( pListEntry = ListHead.Flink; pListEntry != pListHead;) { if (CheckControlC()) break; ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset); // make a local copy of the debuggee structure if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL)) { if (CallBack) { CallBack((VOID *)pStructure_OOP,pStorage); } else { dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP); } pListEntry = pListEntryLocal->Flink; cItems++; } else { dprintf("RM %p\n",pStructure_OOP); break; } } dprintf( "%d entries traversed\n", cItems ); } else { dprintf("RM %p\n",pListHead); } } void EnumReverseLinkedListCB(IN LIST_ENTRY * pListHead, IN DWORD cbSizeOfStructure, IN DWORD cbListEntryOffset, IN pfnCallBack2 CallBack) { LIST_ENTRY ListHead; LIST_ENTRY * pListEntry; DWORD cItems = 0; void * pStorage = (void *)_alloca(cbSizeOfStructure); LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset); if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL)) { if (CallBack) { } else { dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink); } for ( pListEntry = ListHead.Blink; pListEntry != pListHead;) { if (CheckControlC()) break; ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset); // make a local copy of the debuggee structure if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL)) { if (CallBack) { CallBack((VOID *)pStructure_OOP,pStorage); } else { dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP); } pListEntry = pListEntryLocal->Blink; cItems++; } else { dprintf("RM %p\n",pStructure_OOP); break; } } dprintf( "%d entries traversed\n", cItems ); } else { dprintf("RM %p\n",pListHead); } } // // // NO-OP callback just for getting the number of items // /////////////////////////////////////////////////////////// DWORD CallBackListCount(VOID * pStructure_OOP, VOID * pLocalCopy) { return 0; } DECLARE_API( llc ) { INIT_API(); ULONG_PTR Addr = GetExpression(args); if (Addr) { EnumLinkedListCB((LIST_ENTRY *)Addr,sizeof(LIST_ENTRY),0,CallBackListCount); } else { dprintf("cannot resolve %s\n",args); } } void PrintStackTrace(ULONG_PTR ArrayAddr_OOP,DWORD dwNum,BOOL bOOP) { ULONG_PTR * pArray; BOOL bRet = FALSE; if (bOOP) { pArray = ( ULONG_PTR *)_alloca(dwNum*sizeof(ULONG_PTR)); bRet = ReadMemory(ArrayAddr_OOP,pArray,dwNum*sizeof(ULONG_PTR),NULL); } else { pArray = (ULONG_PTR *)ArrayAddr_OOP; bRet = TRUE; } if (bRet) { DWORD i; for (i=0;i Size) { dprintf("invalid tree\n"); return; } if (Verbose) { dprintf(" %p %p (%p,%p,%p) - %p %p %p\n", (*pNum)-1, pNode, BRN._Left,BRN._Parent,BRN._Right, BRN.Values[0], BRN.Values[1], BRN.Values[2]); if (CallBack) { //dprintf("CAllBack\n"); CallBack((VOID *)BRN.Values[0],(VOID *)BRN.Values[1]); } } if (!IsNil(BRN._Right)){ PrintTree(BRN._Right,pNum,Verbose,Size,CallBack); }; } else { dprintf(" RM %p err %d\n",pNode,GetLastError()); } } void PrintMapCB(_Map * pMap,BOOL Verbose, pfnCallBack2 CallBack) { _Map MAP; if (ReadMemory((ULONG_PTR)pMap,&MAP,sizeof(_Map),NULL)) { if (MAP.pQm) { dprintf(" std::map at %p : size %p\n",pMap,MAP.Size); _QM QM; if (ReadMemory((ULONG_PTR)MAP.pQm,&QM,sizeof(QM),NULL)) { if (QM._Parent && !IsNil(QM._Parent)) { DWORD Num = 0; PrintTree(QM._Parent,&Num,Verbose,MAP.Size,CallBack); dprintf(" traversed %d nodes\n",Num); } } else { dprintf("RM %p err %d\n",MAP.pQm,GetLastError()); } } else { dprintf("empty tree\n"); } } else { dprintf("RM %p\n",pMap); } } // // // prints a generic std::map // //////////////////////////////////// DECLARE_API( std_map ) { INIT_API(); _Map * pMap = (_Map *)GetExpression( args ); if (pMap){ PrintMapCB(pMap,TRUE,NULL); } else { dprintf("invalid address %s\n",args); } } void PrintListCB(_List * pList_OOP, pfnCallBack1 CallBack) { _List List; if (ReadMemory((ULONG_PTR)pList_OOP,&List,sizeof(_List),NULL)) { dprintf(" std::queue @ %p _Allocator %p _Head %p _Size %p\n",pList_OOP,List._Allocator,List._Head,List._Size); _Node_List NodeList; if (ReadMemory((ULONG_PTR)List._Head,&NodeList,sizeof(_Node_List),NULL)) { _Node_List * pNodeList = NodeList._Next; DWORD i = 0; while (pNodeList != List._Head) { if (CheckControlC()) break; if (ReadMemory((ULONG_PTR)pNodeList,&NodeList,sizeof(_Node_List),NULL)) { dprintf(" %x %p (%p, %p) - %p\n",i++,pNodeList,NodeList._Next,NodeList._Prev,NodeList._Value); if (CallBack) { CallBack(NodeList._Value); } pNodeList = NodeList._Next; } else { dprintf("RM %p\n",pNodeList); } } } else { dprintf("RM %p\n",List._Head); } } else { dprintf("RM %p\n",pList_OOP); } } // // // prints a generic std::list // ////////////////////////////////////// DECLARE_API( std_queue) { INIT_API(); _List * pList = (_List *)GetExpression( args ); if (pList){ PrintListCB(pList,NULL); } else { dprintf("invalid address %s\n",args); } } // // // this is for Pat // he has a std::map // ////////////////////////////////////////////////// DWORD CallBackObj(void * pKey, void * pValue) { GetVTable((MEMORY_ADDRESS)pKey); return 0; } DECLARE_API( mapobj ) { INIT_API(); _Map * pMap = (_Map *)GetExpression( args ); if (pMap){ PrintMapCB(pMap,TRUE,CallBackObj); } else { dprintf("invalid address %s\n",args); } } void PrintIID(GUID & CurrUUID){ WCHAR pszClsID[40]; StringFromGUID2(CurrUUID,pszClsID,40); WCHAR pszFullPath[MAX_PATH]; lstrcpyW(pszFullPath,L"Interface\\"); lstrcatW(pszFullPath,pszClsID); char pDataA[MAX_PATH]; HKEY hKey; LONG lRes; lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT, pszFullPath, 0, KEY_READ, &hKey); if (lRes == ERROR_SUCCESS){ DWORD dwType; WCHAR pData[MAX_PATH]; DWORD dwSize=sizeof(pData); lRes = RegQueryValueExW(hKey, NULL, // default NULL, &dwType, (BYTE *)pData, &dwSize); if (lRes == ERROR_SUCCESS) { WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL); dprintf(" IID_%s\n",pDataA); } RegCloseKey(hKey); } else { if (IsEqualGUID(CurrUUID,IID_IMarshal)){ dprintf(" IID_IMarshal\n"); } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) { dprintf(" IID_IStdIdentity\n"); } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) { dprintf(" IID_ICallFactory\n"); } else { WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL); dprintf(" %s\n",pDataA); } } } class OXIDEntry; class CCtxComChnl; class IRCEntry; typedef GUID IPID; typedef struct tagIPIDEntry { struct tagIPIDEntry *pNextIPID; // next IPIDEntry for same object // WARNING: next 6 fields must remain in their respective locations // and in the same format as the IPIDTmp structure above. DWORD dwFlags; // flags (see IPIDFLAGS) ULONG cStrongRefs; // strong reference count ULONG cWeakRefs; // weak reference count ULONG cPrivateRefs; // private reference count void *pv; // real interface pointer IUnknown *pStub; // proxy or stub pointer OXIDEntry *pOXIDEntry; // ptr to OXIDEntry in OXID Table // WARNING: previous 7 fields must remain in their respective locations // and in the same format as the IPIDTmp structure above. IPID ipid; // interface pointer identifier IID iid; // interface iid CCtxComChnl *pChnl; // channel pointer IRCEntry *pIRCEntry; // reference cache line struct tagIPIDEntry *pOIDFLink; // In use OID list struct tagIPIDEntry *pOIDBLink; } IPIDEntry; DECLARE_API( ipidl ) { INIT_API(); IPIDEntry IpId; ULONG_PTR Addr = GetExpression(args); if (Addr) { DWORD nCount=0; while (Addr && ReadMemory(Addr,&IpId,sizeof(IpId),NULL)) { dprintf(" -- %x\n",nCount); dprintf(" pNextIPID %p\n",IpId.pNextIPID); dprintf(" dwFlags %08x\n",IpId.dwFlags); dprintf(" cStrongRefs %08x\n",IpId.cStrongRefs); dprintf(" cWeakRefs %08x\n",IpId.cWeakRefs); dprintf(" cPrivateRefs %08x\n",IpId.cPrivateRefs); dprintf(" pv %p\n",IpId.pv); dprintf(" pStub %p\n",IpId.pStub); dprintf(" pOXIDEntry %p\n",IpId.pOXIDEntry); PrintIID(IpId.ipid); PrintIID(IpId.iid); dprintf(" pChnl %p\n",IpId.pChnl); dprintf(" pIRCEntry %p\n",IpId.pIRCEntry); dprintf(" pOIDFLink %p\n",IpId.pOIDFLink); dprintf(" pOIDBLink %p\n",IpId.pOIDBLink); Addr = (ULONG_PTR)IpId.pNextIPID; nCount++; if (CheckControlC()) break; }; } else { dprintf(" unable to resolve %s\n",args); } } void PrintCLSID(GUID & CurrUUID){ WCHAR pszClsID[40]; StringFromGUID2(CurrUUID,pszClsID,40); // look-up known DWORD i; for (i=0;i dt rpcss!CServerTableEntry 6fb`ffcdb170 +0x000 __VFN_table : 0x00000000`702a2b60 +0x008 _references : +0x010 _pnext : (null) +0x018 _id : 0x11d0f196`61738644 +0x020 _id2 : 0xc119d94f`c0005399 +0x028 _EntryType : 0 ( ENTRY_TYPE_CLASS ) +0x030 _pParentTableLock : 0x000006fb`ffc9d590 +0x038 _pParentTable : 0x000006fb`ffc9d700 +0x040 _bComPlusProcess : 0 +0x044 _lThreadToken : 0 +0x048 _dwProcessId : 0 +0x050 _hProcess : (null) +0x058 _pProcess : (null) +0x060 _pvRunAsHandle : (null) +0x068 _bSuspendedClsid : 0 +0x06c _bSuspendedApplication : 0 +0x070 _ServerList : CServerList +0x080 _ServerLock : CSharedLock */ DECLARE_API( rot ) { INIT_API(); CHashTable * pChashTable; ULONG_PTR Addr = GetExpression("rpcss!gpClassTable"); if (Addr) { CHashTable * pChashTable; ReadMemory(Addr,&pChashTable,sizeof(CHashTable *),0); CHashTable MyHashTable; if (pChashTable) { dprintf("CServerTable %p\n",pChashTable); ReadMemory((ULONG_PTR)pChashTable,&MyHashTable,sizeof(CHashTable),NULL); CTableElement ** StackArray = (CTableElement **)_alloca(MyHashTable._cBuckets * sizeof(CTableElement *)); ReadMemory((ULONG_PTR)MyHashTable._buckets,StackArray,MyHashTable._cBuckets * sizeof(CTableElement *),NULL); DWORD i; for (i=0;iCriticalSection,pStructure_OOP); RTL_CRITICAL_SECTION CritSec; if (ReadMemory((ULONG_PTR)pDebugInfo->CriticalSection,&CritSec,sizeof(RTL_CRITICAL_SECTION),NULL)) { dprintf(" - %p %x %x %x\n", CritSec.DebugInfo, CritSec.LockCount, CritSec.RecursionCount, CritSec.OwningThread); } else { dprintf("RM %p\n",pDebugInfo->CriticalSection); } return 0; } #define ARRAY_TO_GO_BACK 16 DWORD EnumListCritSec2(VOID * pStructure_OOP, VOID * pLocalStructure) { RTL_CRITICAL_SECTION_DEBUG * pDebugInfo = (RTL_CRITICAL_SECTION_DEBUG *)pLocalStructure; dprintf(" CS %p DI %p \n",pDebugInfo->CriticalSection,pStructure_OOP); struct _TmpStr { ULONG_PTR Array[ARRAY_TO_GO_BACK]; RTL_CRITICAL_SECTION CritSec; } TmpStr; if (ReadMemory(((ULONG_PTR)pDebugInfo->CriticalSection) - FIELD_OFFSET(_TmpStr,CritSec),&TmpStr,sizeof(_TmpStr),NULL)) { dprintf(" - %p %x %x %x\n", TmpStr.CritSec.DebugInfo, TmpStr.CritSec.LockCount, TmpStr.CritSec.RecursionCount, TmpStr.CritSec.OwningThread); for (int i=(ARRAY_TO_GO_BACK-1);i>=0;i--) { if (GetVTable((MEMORY_ADDRESS)TmpStr.Array[i])) { break; // don't be too verbose } } } else { dprintf("RM around %p\n",pDebugInfo->CriticalSection); } return 0; } DECLARE_API( cs ) { INIT_API(); ULONG_PTR Addr = GetExpression("ntdll!RtlCriticalSectionList"); ULONG_PTR bGoAndFindVTable = TRUE; if (!Addr) { Addr = GetExpression(args); } else { bGoAndFindVTable = GetExpression(args); } if (Addr) { if (bGoAndFindVTable) { EnumLinkedListCB((LIST_ENTRY *)Addr, sizeof(RTL_CRITICAL_SECTION_DEBUG), FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList), EnumListCritSec2); } else { EnumLinkedListCB((LIST_ENTRY *)Addr, sizeof(RTL_CRITICAL_SECTION_DEBUG), FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList), EnumListCritSec); } } else { dprintf("unable to resolve ntdll!RtlCriticalSectionList\n"); } } BOOL GetVTable(MEMORY_ADDRESS pThis_OOP){ MEMORY_ADDRESS pVTable; ReadMemory(pThis_OOP,&pVTable,sizeof(pVTable),0); BYTE pString[256]; pString[0]=0; #ifdef KDEXT_64BIT ULONG64 Displ; #else ULONG Displ; #endif GetSymbol(pVTable,(PCHAR)pString,&Displ); if (lstrlenA((CHAR *)pString)) { dprintf(" %s+%x\n",pString,Displ); return TRUE; } else { return FALSE; } } /* kd> dt ntdll!RTL_CRITICAL_SECTION +0x000 DebugInfo : Ptr64 _RTL_CRITICAL_SECTION_DEBUG +0x008 LockCount : Int4B +0x00c RecursionCount : Int4B +0x010 OwningThread : Ptr64 Void +0x018 LockSemaphore : Ptr64 Void +0x020 SpinCount : Uint8B kd> dt ntdll!_RTL_CRITICAL_SECTION_DEBUG +0x000 Type : Uint2B +0x002 CreatorBackTraceIndex : Uint2B +0x008 CriticalSection : Ptr64 _RTL_CRITICAL_SECTION +0x010 ProcessLocksList : _LIST_ENTRY +0x020 EntryCount : Uint4B +0x024 ContentionCount : Uint4B +0x028 Spare : [2] Uint4B kd> */ #ifdef KDEXT_64BIT struct _LIST_ENTRY_64 { ULONG64 Flink; ULONG64 Blink; }; struct _RTL_CRITICAL_SECTION_64 { ULONG64 DebugInfo; DWORD LockCount; DWORD RecursionCount; ULONG64 OwningThread; ULONG64 LockSemaphore; ULONG64 SpinCount; }; struct _RTL_CRITICAL_SECTION_DEBUG_64 { WORD Type; WORD CreatorBackTraceIndex; ULONG64 CriticalSection; _LIST_ENTRY_64 ProcessLocksList; DWORD EntryCount; DWORD ContentionCount; DWORD Spare; }; #endif /*KDEXT_64BIT*/ DECLARE_API(cs64) { INIT_API(); #ifdef KDEXT_64BIT _RTL_CRITICAL_SECTION_DEBUG_64 DebugInfo; _RTL_CRITICAL_SECTION_64 CritSec; _LIST_ENTRY_64 ListEntry; ULONG64 MemAddr = GetExpression(args); if (MemAddr) { ULONG64 AddrHead = MemAddr; if (ReadMemory(MemAddr,&ListEntry,sizeof(ListEntry),NULL)) { DebugInfo.ProcessLocksList.Flink = ListEntry.Flink; while (DebugInfo.ProcessLocksList.Flink != AddrHead) { if (CheckControlC()) break; MemAddr = DebugInfo.ProcessLocksList.Flink - FIELD_OFFSET(_RTL_CRITICAL_SECTION_DEBUG_64,ProcessLocksList); if (ReadMemory((MEMORY_ADDRESS)MemAddr,&DebugInfo,sizeof(DebugInfo),NULL)) { dprintf(" C %p D %p\n",DebugInfo.CriticalSection,MemAddr); if (ReadMemory((MEMORY_ADDRESS)DebugInfo.CriticalSection,&CritSec,sizeof(CritSec),NULL)) { dprintf(" - CS %p %x %x %p\n", CritSec.DebugInfo, CritSec.LockCount, CritSec.RecursionCount, CritSec.OwningThread); } else { dprintf("RM %p\n",DebugInfo.CriticalSection); } } else { break; } } } else { dprintf("RM %p\n",MemAddr); } } else { dprintf("unable to resolve %s\n",args); } #endif /*KDEXT_64BIT*/ }