Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2144 lines
64 KiB

  1. #include <wmiexts.h>
  2. #include <malloc.h>
  3. #include <objbase.h>
  4. #include <obase.h>
  5. //IID_IStdIdentity {0000001B-0000-0000-C000-000000000046}
  6. const GUID IID_IStdIdentity = {0x0000001B,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  7. #include <data.h>
  8. #include <utilfun.h>
  9. DECLARE_API(iid) {
  10. INIT_API();
  11. GUID CurrUUID;
  12. MEMORY_ADDRESS pUUID = 0;
  13. pUUID = GetExpression(args);
  14. if (pUUID){
  15. ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0);
  16. WCHAR pszClsID[40];
  17. StringFromGUID2(CurrUUID,pszClsID,40);
  18. WCHAR pszFullPath[MAX_PATH];
  19. lstrcpyW(pszFullPath,L"Interface\\");
  20. lstrcatW(pszFullPath,pszClsID);
  21. char pDataA[MAX_PATH];
  22. HKEY hKey;
  23. LONG lRes;
  24. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  25. pszFullPath,
  26. 0,
  27. KEY_READ,
  28. &hKey);
  29. if (lRes == ERROR_SUCCESS){
  30. DWORD dwType;
  31. WCHAR pData[MAX_PATH];
  32. DWORD dwSize=sizeof(pData);
  33. lRes = RegQueryValueExW(hKey,
  34. NULL, // default
  35. NULL,
  36. &dwType,
  37. (BYTE *)pData,
  38. &dwSize);
  39. if (lRes == ERROR_SUCCESS) {
  40. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  41. dprintf(" IID_%s\n",pDataA);
  42. }
  43. RegCloseKey(hKey);
  44. } else {
  45. if (IsEqualGUID(CurrUUID,IID_IMarshal)){
  46. dprintf(" IID_IMarshal\n");
  47. } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) {
  48. dprintf(" IID_IStdIdentity\n");
  49. } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) {
  50. dprintf(" IID_ICallFactory\n");
  51. } else {
  52. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  53. dprintf("unable to open key %s\n",pDataA);
  54. }
  55. }
  56. } else {
  57. dprintf("unable to resolve %s\n",args);
  58. }
  59. }
  60. extern ArrayCLSID g_ArrayCLSID[];
  61. DECLARE_API(clsid) {
  62. INIT_API();
  63. GUID CurrUUID;
  64. MEMORY_ADDRESS pUUID = 0;
  65. pUUID = GetExpression(args);
  66. if (pUUID){
  67. ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0);
  68. WCHAR pszClsID[40];
  69. StringFromGUID2(CurrUUID,pszClsID,40);
  70. // look-up known
  71. DWORD i;
  72. for (i=0;i<g_nClsids;i++){
  73. if(IsEqualGUID(CurrUUID,*g_ArrayCLSID[i].pClsid)){
  74. dprintf(" CLSID : %s\n",g_ArrayCLSID[i].pStrClsid);
  75. break;
  76. }
  77. }
  78. WCHAR pszFullPath[MAX_PATH];
  79. lstrcpyW(pszFullPath,L"CLSID\\");
  80. lstrcatW(pszFullPath,pszClsID);
  81. char pDataA[MAX_PATH];
  82. HKEY hKey;
  83. LONG lRes;
  84. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  85. pszFullPath,
  86. 0,
  87. KEY_READ,
  88. &hKey);
  89. if (lRes == ERROR_SUCCESS){
  90. DWORD dwType;
  91. WCHAR pData[MAX_PATH];
  92. DWORD dwSize=sizeof(pData);
  93. lRes = RegQueryValueExW(hKey,
  94. NULL, // default
  95. NULL,
  96. &dwType,
  97. (BYTE *)pData,
  98. &dwSize);
  99. if (lRes == ERROR_SUCCESS) {
  100. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  101. dprintf(" ProgID %s\n",pDataA);
  102. };
  103. RegCloseKey(hKey);
  104. // no open InProcServer32
  105. WCHAR pszFullPathDll[MAX_PATH];
  106. lstrcpyW(pszFullPathDll,pszFullPath);
  107. lstrcatW(pszFullPathDll,L"\\InprocServer32");
  108. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  109. pszFullPathDll,
  110. 0,
  111. KEY_READ,
  112. &hKey);
  113. if (lRes == ERROR_SUCCESS){
  114. dwSize = sizeof(pData);
  115. lRes = RegQueryValueExW(hKey,
  116. NULL, // default
  117. NULL,
  118. &dwType,
  119. (BYTE *)pData,
  120. &dwSize);
  121. if (lRes == ERROR_SUCCESS) {
  122. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  123. dprintf(" Path: %s\n",pDataA);
  124. };
  125. RegCloseKey(hKey);
  126. }
  127. } else {
  128. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  129. dprintf("unable to open key %s\n",pDataA);
  130. }
  131. } else {
  132. dprintf("unable to resolve %s\n",args);
  133. }
  134. }
  135. //
  136. //
  137. // Dumps a SAFE_ARRAY
  138. //
  139. //
  140. DECLARE_API(sa) {
  141. INIT_API();
  142. SAFEARRAY SA;
  143. MEMORY_ADDRESS pSA = 0;
  144. pSA = GetExpression(args);
  145. if (pSA){
  146. ReadMemory(pSA,&SA,sizeof(SA),0);
  147. dprintf(" cDims %d cbElements %d pvData %08x\n",SA.cDims,SA.cbElements,SA.pvData);
  148. dprintf("rgsabound.cElements %d lLbound %d\n",SA.rgsabound[0].cElements,SA.rgsabound[0].lLbound);
  149. } else {
  150. dprintf("invalid address %s\n",args);
  151. }
  152. }
  153. //
  154. // help for the extension
  155. // may commands are not listed here
  156. //
  157. //
  158. DECLARE_API(help) {
  159. INIT_API();
  160. dprintf(" WMI debugger extension\n");
  161. dprintf(" iid : print the human readable IID_xxx\n");
  162. dprintf(" clsid : print the human readable CLSID_xxx\n");
  163. dprintf(" rot : print the human readable rpcss!gpClassTable\n");
  164. dprintf(" gpl : print the human readable rpcss!gpProcessList\n");
  165. dprintf(" gipid : print the global list of IPIDEntry\n");
  166. dprintf(" goxid : print the global list of OXIDEntry\n");
  167. dprintf(" ipidl : print the list of IPIDEntry for CStdIdentiry\n");
  168. dprintf(" srtbl : print the list of secure reference IPID in ole32!gSRFTbl\n");
  169. dprintf(" llc : print linked list count\n");
  170. dprintf(" cs : print the list of CRITICAL_SECTION\n");
  171. dprintf(" std_map : print the first 3 DWORD of a std::map<K,V>\n");
  172. dprintf(" std_queue: print the first ULONG_PTR of a std::queue<V>\n");
  173. dprintf(" std_deque: print the first ULONG_PTR of a std::deque<V>\n");
  174. //dprintf(" mapobj : print a std::map<IUnk,bool>\n");
  175. dprintf(" -------- HEAP family\n");
  176. dprintf(" he : print the HEAP_ENTRY\n");
  177. dprintf(" hef : walks the HEAP_ENTRY list forward\n");
  178. dprintf(" hef : walks the HEAP_ENTRY list backward\n");
  179. dprintf(" hs : print the HEAP_SEGMENT\n");
  180. dprintf(" hp : print the HEAP\n");
  181. dprintf(" lhp : <HEAP> prints the LookAside list for the HEAP\n");
  182. dprintf(" hps : print a summary for all the HEAP in the process\n");
  183. dprintf(" shp : <HEAP> <ADDR> search heap HEAP for address ADDR\n");
  184. dprintf(" rllc : <ADDR> prints the free list in reverse order\n");
  185. dprintf(" hpf : <HEAP> prints the free list of the heap at HEAP\n");
  186. dprintf(" php : <HEAP> [s ADDR] prints the pageheap and searches\n");
  187. dprintf(" -------- FASTPROX family\n");
  188. dprintf(" wc : print the human readable WbemClass\n");
  189. dprintf(" wi : print the human readable WbemClass\n");
  190. dprintf(" blob : ADDR [size] print (part of) the ClassObject BLOB\n");
  191. dprintf(" datap : ADDR print the WBEMDATA marshaling BLOB\n");
  192. dprintf(" cp : print the human readable CClassPart\n");
  193. dprintf(" cvar : print the CVar\n");
  194. dprintf(" -------- WBEMCORE\n");
  195. dprintf(" q : print wbemcore!g_pAsyncSvcQueue\n");
  196. dprintf(" arb : print wbemcore!CWmiArbitrator__m_pArb\n");
  197. dprintf(" -------- REPDRVFS\n");
  198. dprintf(" tmpall : print the Allocators in repdrvfs\n");
  199. dprintf(" forestc : [Addr] print the repdrvfs!CForestCache at Addr\n");
  200. dprintf(" filec : [Addr] print repdrvfs!CFileCache at Addr\n");
  201. dprintf(" fmap : \\fs\\[objects|index].map dumps the .MAP file from disk \n");
  202. dprintf(" btr : dumps the index.btr/index.map file from disk \n");
  203. dprintf(" varobj : dumps part of objects.data file from disk \n");
  204. dprintf(" -------- THREAD family\n");
  205. dprintf(" t : print RPC and OLE data for each thread\n");
  206. dprintf(" inv : <addr> [param] invokes a function in the remote thread\n");
  207. dprintf(" bs : <teb> rebuilds the stack from the info in the TEB\n");
  208. dprintf(" st : <addr> <num> prints the num DWORD saved by RtlCaptureStackBackTrace\n");
  209. dprintf(" lpp : print linked list and unassemble backtrace\n");
  210. dprintf(" vq : -a <addr> | -f Flag : calls VirtualQuery on the addr\n");
  211. dprintf(" srt : <addr> searches the stacks of all threads for addr\n");
  212. dprintf(" ksrt : <addr> searches the stacks of all threads for addr - KD only\n");
  213. dprintf(" el : <TEB> prints the exception list of the current thread x86 only\n");
  214. dprintf(" -------- ESS\n");
  215. dprintf(" ess : print wbemcore!g_pNewESS\n");
  216. dprintf(" -------- PROVSS\n");
  217. dprintf(" pc : print wbemcore!CCoreServices__m_pProvSS\n");
  218. dprintf(" pf : print CServerObject_BindingFactory\n");
  219. dprintf(" -------- 32-K-64\n");
  220. dprintf(" hef64 : <addr> HEAP_ENTRY list forward\n");
  221. dprintf(" heb64 : <addr> HEAP_ENTRY list backward\n");
  222. dprintf(" hps64 : print heap summary\n");
  223. dprintf(" cs64 : print CritSec list\n");
  224. }
  225. void
  226. EnumLinkedListCB(IN LIST_ENTRY * pListHead,
  227. IN DWORD cbSizeOfStructure,
  228. IN DWORD cbListEntryOffset,
  229. IN pfnCallBack2 CallBack,
  230. IN VOID * Context)
  231. {
  232. LIST_ENTRY ListHead;
  233. LIST_ENTRY * pListEntry;
  234. DWORD cItems = 0;
  235. void * pStorage = (void *)_alloca(cbSizeOfStructure);
  236. LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset);
  237. if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL))
  238. {
  239. if (CallBack)
  240. {
  241. }
  242. else
  243. {
  244. dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink);
  245. }
  246. for ( pListEntry = ListHead.Flink;
  247. pListEntry != pListHead;)
  248. {
  249. if (CheckControlC())
  250. break;
  251. ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset);
  252. // make a local copy of the debuggee structure
  253. if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL))
  254. {
  255. if (CallBack)
  256. {
  257. //dprintf(" CallBack %p\n",CallBack);
  258. if (NULL == Context)
  259. {
  260. CallBack((VOID *)pStructure_OOP,pStorage);
  261. }
  262. else
  263. {
  264. //dprintf(" CallBackEx %p %p\n",CallBack,Context);
  265. pfnCallBack3 CallBackEx = (pfnCallBack3)CallBack;
  266. CallBackEx((VOID *)pStructure_OOP,pStorage,Context);
  267. }
  268. }
  269. else
  270. {
  271. dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP);
  272. }
  273. pListEntry = pListEntryLocal->Flink;
  274. cItems++;
  275. }
  276. else
  277. {
  278. dprintf("RM %p\n",pStructure_OOP);
  279. break;
  280. }
  281. }
  282. dprintf( "%d entries traversed\n", cItems );
  283. }
  284. else
  285. {
  286. dprintf("RM %p\n",pListHead);
  287. }
  288. }
  289. void
  290. EnumReverseLinkedListCB(IN LIST_ENTRY * pListHead,
  291. IN DWORD cbSizeOfStructure,
  292. IN DWORD cbListEntryOffset,
  293. IN pfnCallBack2 CallBack)
  294. {
  295. LIST_ENTRY ListHead;
  296. LIST_ENTRY * pListEntry;
  297. DWORD cItems = 0;
  298. void * pStorage = (void *)_alloca(cbSizeOfStructure);
  299. LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset);
  300. if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL))
  301. {
  302. if (CallBack)
  303. {
  304. }
  305. else
  306. {
  307. dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink);
  308. }
  309. for ( pListEntry = ListHead.Blink;
  310. pListEntry != pListHead;)
  311. {
  312. if (CheckControlC())
  313. break;
  314. ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset);
  315. // make a local copy of the debuggee structure
  316. if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL))
  317. {
  318. if (CallBack)
  319. {
  320. CallBack((VOID *)pStructure_OOP,pStorage);
  321. }
  322. else
  323. {
  324. dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP);
  325. }
  326. pListEntry = pListEntryLocal->Blink;
  327. cItems++;
  328. }
  329. else
  330. {
  331. dprintf("RM %p\n",pStructure_OOP);
  332. break;
  333. }
  334. }
  335. dprintf( "%d entries traversed\n", cItems );
  336. }
  337. else
  338. {
  339. dprintf("RM %p\n",pListHead);
  340. }
  341. }
  342. //
  343. //
  344. // NO-OP callback just for getting the number of items
  345. //
  346. ///////////////////////////////////////////////////////////
  347. DWORD
  348. CallBackListCount(VOID * pStructure_OOP,
  349. VOID * pLocalCopy)
  350. {
  351. return 0;
  352. }
  353. DECLARE_API( llc )
  354. {
  355. INIT_API();
  356. MEMORY_ADDRESS Addr = GetExpression(args);
  357. if (Addr)
  358. {
  359. EnumLinkedListCB((LIST_ENTRY *)Addr,sizeof(LIST_ENTRY),0,CallBackListCount);
  360. }
  361. else
  362. {
  363. dprintf("cannot resolve %s\n",args);
  364. }
  365. }
  366. void
  367. PrintStackTrace(MEMORY_ADDRESS ArrayAddr_OOP,DWORD dwNum,BOOL bOOP)
  368. {
  369. MEMORY_ADDRESS * pArray;
  370. BOOL bRet = FALSE;
  371. if (bOOP)
  372. {
  373. pArray = ( MEMORY_ADDRESS *)_alloca(dwNum*sizeof(MEMORY_ADDRESS));
  374. bRet = ReadMemory(ArrayAddr_OOP,pArray,dwNum*sizeof(MEMORY_ADDRESS),NULL);
  375. }
  376. else
  377. {
  378. pArray = (MEMORY_ADDRESS *)ArrayAddr_OOP;
  379. bRet = TRUE;
  380. }
  381. if (bRet)
  382. {
  383. DWORD i;
  384. for (i=0;i<dwNum;i++)
  385. {
  386. BYTE pString[256];
  387. pString[0] = 0;
  388. #ifdef KDEXT_64BIT
  389. ULONG64 Displ = 0;
  390. #else
  391. ULONG Displ = 0;
  392. #endif
  393. if (pArray[i])
  394. {
  395. GetSymbol(pArray[i],(PCHAR)pString,&Displ);
  396. pString[255] = 0;
  397. dprintf(" %s+%x\n",pString,Displ);
  398. }
  399. }
  400. }
  401. }
  402. //
  403. // printf stack trace
  404. //
  405. DECLARE_API( st )
  406. {
  407. INIT_API();
  408. int Len = strlen(args);
  409. CHAR * pArgs = (CHAR *)_alloca((Len+1));
  410. lstrcpy(pArgs,(CHAR *)args);
  411. MEMORY_ADDRESS NumInst = 6;
  412. MEMORY_ADDRESS pAddr = 0;
  413. while (isspace(*pArgs))
  414. {
  415. pArgs++;
  416. }
  417. CHAR * pFirst = pArgs;
  418. while(!isspace(*pArgs)) pArgs++;
  419. // terminate string, if possible
  420. if (isspace(*pArgs))
  421. {
  422. *pArgs = 0;
  423. pArgs++;
  424. }
  425. else
  426. {
  427. pArgs = NULL;
  428. }
  429. pAddr = GetExpression(pFirst);
  430. if (pArgs)
  431. {
  432. NumInst = GetExpression(pArgs);
  433. }
  434. if (pAddr)
  435. {
  436. dprintf("StackTrace @ %p num %d\n",pAddr,NumInst);
  437. PrintStackTrace(pAddr,(DWORD)NumInst,TRUE);
  438. }
  439. else
  440. {
  441. dprintf("usage: address num\n");
  442. }
  443. }
  444. //
  445. //
  446. // this is the CallBack called by the enumerator
  447. // of a Double-Liked list of objects with
  448. // struct _Instrument
  449. // {
  450. // LIST_ENTRY ListEntry;
  451. // ULONG_PTR ArrayFuncts[32];
  452. // }
  453. //
  454. //////////////////////////////////////////////////////////
  455. DWORD
  456. CallBackCreateStacks(VOID * pStructure_OOP,
  457. VOID * pLocalStructure)
  458. {
  459. dprintf(" ----- %p \n",pStructure_OOP);
  460. PrintStackTrace((ULONG_PTR)((BYTE *)pLocalStructure+sizeof(LIST_ENTRY)),6,FALSE);
  461. return 0;
  462. }
  463. DECLARE_API( lpp )
  464. {
  465. INIT_API();
  466. MEMORY_ADDRESS Addr = GetExpression(args);
  467. if (Addr)
  468. {
  469. EnumLinkedListCB((LIST_ENTRY *)Addr,
  470. sizeof(LIST_ENTRY)+32*sizeof(ULONG_PTR),
  471. 0,
  472. CallBackCreateStacks);
  473. }
  474. else
  475. {
  476. dprintf("cannot resolve %s\n",args);
  477. }
  478. }
  479. //
  480. //
  481. //
  482. /////////////
  483. void PrintDequeCB(MEMORY_ADDRESS pDeque_OOP,pfnCallBack2 pCallBack)
  484. {
  485. _Deque Deque;
  486. if (ReadMemory(pDeque_OOP,&Deque,sizeof(Deque),NULL))
  487. {
  488. dprintf(" std::deque @ %p _Allocator %p head %p tail %p _Size %p\n",pDeque_OOP,Deque._Allocator,Deque._First._Next,Deque._Last._Next,Deque._Size);
  489. ULONG_PTR Size = Deque._Size;
  490. ULONG_PTR ByteSize = (ULONG_PTR)Deque._Last._Next-(ULONG_PTR)Deque._First._Next;
  491. ULONG_PTR pArray_OOP = (ULONG_PTR)Deque._First._Next;
  492. BYTE * pArray = NULL;
  493. if (Size)
  494. pArray = (BYTE *)HeapAlloc(GetProcessHeap(),0,ByteSize);
  495. if (pArray)
  496. {
  497. ULONG_PTR SizeElem = ByteSize/Size;
  498. if (ReadMemory(pArray_OOP,pArray,(ULONG)ByteSize,0))
  499. {
  500. for (ULONG_PTR i=0;i<Size;i++)
  501. {
  502. dprintf(" %p -[%p] %p\n",i,pArray_OOP+i*SizeElem,*((void **)(&pArray[i*SizeElem])));
  503. if (pCallBack)
  504. {
  505. // address OOP and address of the In-Proc opy of the memory are passed down
  506. pCallBack((void *)(pArray_OOP+i*SizeElem),(void *)(&pArray[i*SizeElem]));
  507. }
  508. }
  509. }
  510. else
  511. {
  512. dprintf("RM %p\n",pArray_OOP);
  513. }
  514. HeapFree(GetProcessHeap(),0,pArray);
  515. }
  516. }
  517. else
  518. {
  519. dprintf("RM %p\n",pDeque_OOP);
  520. }
  521. }
  522. //
  523. //
  524. // prints a generic std::deque
  525. //
  526. ////////////////////////////////////
  527. DECLARE_API( std_deque )
  528. {
  529. INIT_API();
  530. _Deque * pDeque = (_Deque *)GetExpression( args );
  531. if (pDeque)
  532. {
  533. PrintDequeCB((MEMORY_ADDRESS)pDeque,NULL);
  534. }
  535. else
  536. {
  537. dprintf("invalid address %s\n",args);
  538. }
  539. }
  540. // left parent right
  541. BOOL
  542. IsNil(_BRN * pNode){
  543. _BRN_HEAD BRN;
  544. ReadMemory((ULONG_PTR)pNode,&BRN,sizeof(_BRN_HEAD),NULL);
  545. return ((BRN._Left == NULL) &&
  546. (BRN._Right == NULL));
  547. }
  548. void
  549. PrintTree(_BRN * pNode,
  550. DWORD * pNum,
  551. BOOL Verbose,
  552. ULONG_PTR Size,
  553. pfnCallBack2 CallBack){
  554. //dprintf(" Node %p\n",pNode);
  555. _BRN BRN;
  556. if (ReadMemory((ULONG_PTR)pNode,&BRN,sizeof(_BRN),NULL))
  557. {
  558. if (!IsNil(BRN._Left)){
  559. PrintTree(BRN._Left,pNum,Verbose,Size,CallBack);
  560. };
  561. if (CheckControlC())
  562. return;
  563. if (pNum){
  564. (*pNum)++;
  565. }
  566. if (*pNum > Size)
  567. {
  568. dprintf("invalid tree\n");
  569. return;
  570. }
  571. if (Verbose) {
  572. dprintf(" %p %p (%p,%p,%p) - %p %p %p\n",
  573. (*pNum)-1,
  574. pNode,
  575. BRN._Left,BRN._Parent,BRN._Right,
  576. BRN.Values[0],
  577. BRN.Values[1],
  578. BRN.Values[2]);
  579. if (CallBack)
  580. {
  581. //dprintf("CAllBack\n");
  582. CallBack((VOID *)BRN.Values[0],(VOID *)BRN.Values[1]);
  583. }
  584. }
  585. if (!IsNil(BRN._Right)){
  586. PrintTree(BRN._Right,pNum,Verbose,Size,CallBack);
  587. };
  588. }
  589. else
  590. {
  591. dprintf(" RM %p err %d\n",pNode,GetLastError());
  592. }
  593. }
  594. void
  595. PrintMapCB(_Map * pMap,BOOL Verbose, pfnCallBack2 CallBack)
  596. {
  597. _Map MAP;
  598. if (ReadMemory((ULONG_PTR)pMap,&MAP,sizeof(_Map),NULL))
  599. {
  600. if (MAP.pQm)
  601. {
  602. dprintf(" std::map at %p : size %p\n",pMap,MAP.Size);
  603. _QM QM;
  604. if (ReadMemory((ULONG_PTR)MAP.pQm,&QM,sizeof(QM),NULL))
  605. {
  606. if (QM._Parent && !IsNil(QM._Parent))
  607. {
  608. DWORD Num = 0;
  609. PrintTree(QM._Parent,&Num,Verbose,MAP.Size,CallBack);
  610. dprintf(" traversed %d nodes\n",Num);
  611. }
  612. }
  613. else
  614. {
  615. dprintf("RM %p err %d\n",MAP.pQm,GetLastError());
  616. }
  617. } else {
  618. dprintf("empty tree\n");
  619. }
  620. }
  621. else
  622. {
  623. dprintf("RM %p\n",pMap);
  624. }
  625. }
  626. //
  627. //
  628. // prints a generic std::map
  629. //
  630. ////////////////////////////////////
  631. DECLARE_API( std_map )
  632. {
  633. INIT_API();
  634. _Map * pMap = (_Map *)GetExpression( args );
  635. if (pMap){
  636. PrintMapCB(pMap,TRUE,NULL);
  637. } else {
  638. dprintf("invalid address %s\n",args);
  639. }
  640. }
  641. void
  642. PrintListCB(_List * pList_OOP, pfnCallBack1 CallBack)
  643. {
  644. _List List;
  645. if (ReadMemory((ULONG_PTR)pList_OOP,&List,sizeof(_List),NULL))
  646. {
  647. dprintf(" std::queue @ %p _Allocator %p _Head %p _Size %p\n",pList_OOP,List._Allocator,List._Head,List._Size);
  648. _Node_List NodeList;
  649. if (ReadMemory((ULONG_PTR)List._Head,&NodeList,sizeof(_Node_List),NULL))
  650. {
  651. _Node_List * pNodeList = NodeList._Next;
  652. DWORD i = 0;
  653. while (pNodeList != List._Head)
  654. {
  655. if (CheckControlC())
  656. break;
  657. if (ReadMemory((ULONG_PTR)pNodeList,&NodeList,sizeof(_Node_List),NULL))
  658. {
  659. dprintf(" %x %p (%p, %p) - %p\n",i++,pNodeList,NodeList._Next,NodeList._Prev,NodeList._Value);
  660. if (CallBack)
  661. {
  662. CallBack(NodeList._Value);
  663. }
  664. pNodeList = NodeList._Next;
  665. }
  666. else
  667. {
  668. dprintf("RM %p\n",pNodeList);
  669. }
  670. }
  671. }
  672. else
  673. {
  674. dprintf("RM %p\n",List._Head);
  675. }
  676. }
  677. else
  678. {
  679. dprintf("RM %p\n",pList_OOP);
  680. }
  681. }
  682. //
  683. //
  684. // prints a generic std::list
  685. //
  686. //////////////////////////////////////
  687. DECLARE_API( std_queue)
  688. {
  689. INIT_API();
  690. _List * pList = (_List *)GetExpression( args );
  691. if (pList){
  692. PrintListCB(pList,NULL);
  693. } else {
  694. dprintf("invalid address %s\n",args);
  695. }
  696. }
  697. //
  698. //
  699. // this is for Pat
  700. // he has a std::map<pObject,BOOL>
  701. //
  702. //////////////////////////////////////////////////
  703. DWORD
  704. CallBackObj(void * pKey, void * pValue)
  705. {
  706. GetVTable((MEMORY_ADDRESS)pKey);
  707. return 0;
  708. }
  709. DECLARE_API( mapobj )
  710. {
  711. INIT_API();
  712. _Map * pMap = (_Map *)GetExpression( args );
  713. if (pMap){
  714. PrintMapCB(pMap,TRUE,CallBackObj);
  715. } else {
  716. dprintf("invalid address %s\n",args);
  717. }
  718. }
  719. void PrintIID(GUID & CurrUUID){
  720. WCHAR pszClsID[40];
  721. StringFromGUID2(CurrUUID,pszClsID,40);
  722. WCHAR pszFullPath[MAX_PATH];
  723. lstrcpyW(pszFullPath,L"Interface\\");
  724. lstrcatW(pszFullPath,pszClsID);
  725. char pDataA[MAX_PATH];
  726. HKEY hKey;
  727. LONG lRes;
  728. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  729. pszFullPath,
  730. 0,
  731. KEY_READ,
  732. &hKey);
  733. if (lRes == ERROR_SUCCESS){
  734. DWORD dwType;
  735. WCHAR pData[MAX_PATH];
  736. DWORD dwSize=sizeof(pData);
  737. lRes = RegQueryValueExW(hKey,
  738. NULL, // default
  739. NULL,
  740. &dwType,
  741. (BYTE *)pData,
  742. &dwSize);
  743. if (lRes == ERROR_SUCCESS) {
  744. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  745. dprintf(" IID_%s\n",pDataA);
  746. }
  747. RegCloseKey(hKey);
  748. } else {
  749. if (IsEqualGUID(CurrUUID,IID_IMarshal)){
  750. dprintf(" IID_IMarshal\n");
  751. } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) {
  752. dprintf(" IID_IStdIdentity\n");
  753. } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) {
  754. dprintf(" IID_ICallFactory\n");
  755. } else {
  756. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  757. dprintf(" %s\n",pDataA);
  758. }
  759. }
  760. }
  761. class OXIDEntry;
  762. class CCtxComChnl;
  763. class IRCEntry;
  764. typedef GUID IPID;
  765. typedef enum tagIPIDFLAGS
  766. {
  767. IPIDF_CONNECTING = 0x1, // ipid is being connected
  768. IPIDF_DISCONNECTED = 0x2, // ipid is disconnected
  769. IPIDF_SERVERENTRY = 0x4, // SERVER IPID vs CLIENT IPID
  770. IPIDF_NOPING = 0x8, // dont need to ping the server or release
  771. IPIDF_COPY = 0x10, // copy for security only
  772. IPIDF_VACANT = 0x80, // entry is vacant (ie available to reuse)
  773. IPIDF_NONNDRSTUB = 0x100, // stub does not use NDR marshaling
  774. IPIDF_NONNDRPROXY = 0x200, // proxy does not use NDR marshaling
  775. IPIDF_NOTIFYACT = 0x400, // notify activation on marshal/release
  776. IPIDF_TRIED_ASYNC = 0x800, // tried to call this server interface async
  777. IPIDF_ASYNC_SERVER = 0x1000, // server implements an async interface
  778. IPIDF_DEACTIVATED = 0x2000, // IPID has been deactivated
  779. IPIDF_WEAKREFCACHE = 0x4000, // IPID holds weak references in refcache
  780. IPIDF_STRONGREFCACHE = 0x8000 // IPID holds strong references in refcache
  781. } IPIDFLAGS;
  782. typedef struct tagIPIDEntry
  783. {
  784. struct tagIPIDEntry *pNextIPID; // next IPIDEntry for same object
  785. // WARNING: next 6 fields must remain in their respective locations
  786. // and in the same format as the IPIDTmp structure above.
  787. DWORD dwFlags; // flags (see IPIDFLAGS)
  788. ULONG cStrongRefs; // strong reference count
  789. ULONG cWeakRefs; // weak reference count
  790. ULONG cPrivateRefs; // private reference count
  791. void *pv; // real interface pointer
  792. IUnknown *pStub; // proxy or stub pointer
  793. OXIDEntry *pOXIDEntry; // ptr to OXIDEntry in OXID Table
  794. // WARNING: previous 7 fields must remain in their respective locations
  795. // and in the same format as the IPIDTmp structure above.
  796. IPID ipid; // interface pointer identifier
  797. IID iid; // interface iid
  798. CCtxComChnl *pChnl; // channel pointer
  799. IRCEntry *pIRCEntry; // reference cache line
  800. struct tagIPIDEntry *pOIDFLink; // In use OID list
  801. struct tagIPIDEntry *pOIDBLink;
  802. } IPIDEntry;
  803. void PrintIPIDFlags(DWORD Flags)
  804. {
  805. if (Flags & IPIDF_CONNECTING) dprintf("IPIDF_CONNECTING ");
  806. if (Flags & IPIDF_DISCONNECTED) dprintf("IPIDF_DISCONNECTED ");
  807. if (Flags & IPIDF_SERVERENTRY) dprintf("IPIDF_SERVERENTRY ");
  808. if (Flags & IPIDF_NOPING) dprintf("IPIDF_NOPING ");
  809. if (Flags & IPIDF_COPY) dprintf("IPIDF_COPY ");
  810. if (Flags & IPIDF_VACANT) dprintf("IPIDF_VACANT ");
  811. if (Flags & IPIDF_NONNDRSTUB) dprintf("IPIDF_NONNDRSTUB ");
  812. if (Flags & IPIDF_NONNDRPROXY) dprintf("IPIDF_NONNDRPROXY ");
  813. if (Flags & IPIDF_NOTIFYACT) dprintf("IPIDF_NOTIFYACT ");
  814. if (Flags & IPIDF_TRIED_ASYNC) dprintf("IPIDF_TRIED_ASYNC ");
  815. if (Flags & IPIDF_ASYNC_SERVER) dprintf("IPIDF_ASYNC_SERVER ");
  816. if (Flags & IPIDF_DEACTIVATED) dprintf("IPIDF_DEACTIVATED ");
  817. if (Flags & IPIDF_WEAKREFCACHE) dprintf("IPIDF_WEAKREFCACHE ");
  818. if (Flags & IPIDF_WEAKREFCACHE) dprintf("IPIDF_WEAKREFCACHE ");
  819. };
  820. void DumpIPID(IPIDEntry & IpId)
  821. {
  822. dprintf(" pNextIPID %p\n",IpId.pNextIPID);
  823. dprintf(" dwFlags "); PrintIPIDFlags(IpId.dwFlags); dprintf("\n");
  824. dprintf(" cStrongRefs %08x\n",IpId.cStrongRefs);
  825. dprintf(" cWeakRefs %08x\n",IpId.cWeakRefs);
  826. dprintf(" cPrivateRefs %08x\n",IpId.cPrivateRefs);
  827. dprintf(" pv %p\n",IpId.pv);
  828. GetVTable((ULONG_PTR)IpId.pv);
  829. dprintf(" pStub %p\n",IpId.pStub);
  830. dprintf(" pOXIDEntry %p\n",IpId.pOXIDEntry);
  831. PrintIID(IpId.ipid);
  832. PrintIID(IpId.iid);
  833. dprintf(" pChnl %p\n",IpId.pChnl);
  834. dprintf(" pIRCEntry %p\n",IpId.pIRCEntry);
  835. //dprintf(" pOIDFLink %p\n",IpId.pOIDFLink);
  836. //dprintf(" pOIDBLink %p\n",IpId.pOIDBLink);
  837. }
  838. DECLARE_API( gipid )
  839. {
  840. INIT_API();
  841. char * pString = (CHAR *)args;
  842. CLSID ClsidToSearch;
  843. BOOL bClsIdFound = FALSE;
  844. if (pString)
  845. {
  846. while (isspace((char)pString)) pString++;
  847. WCHAR pClsid[64];
  848. DWORD nChar = 0;
  849. for (;*pString && nChar < 64;nChar++,pString++)
  850. {
  851. pClsid[nChar] = (WCHAR)(*pString);
  852. }
  853. pClsid[nChar] = 0;
  854. if (SUCCEEDED(CLSIDFromString(pClsid,&ClsidToSearch)))
  855. bClsIdFound = TRUE;
  856. }
  857. IPIDEntry gIpId;
  858. MEMORY_ADDRESS Addr = GetExpression("ole32!CIPIDTable___oidListHead");
  859. if (Addr)
  860. {
  861. dprintf("ole32!CIPIDTable___oidListHead @ %p\n",Addr);
  862. DWORD nItems = 0;
  863. gIpId.pOIDFLink = (IPIDEntry *)Addr;
  864. do
  865. {
  866. MEMORY_ADDRESS pCurrentIPID = (MEMORY_ADDRESS)gIpId.pOIDFLink;
  867. if (ReadMemory(pCurrentIPID,&gIpId,sizeof(gIpId),NULL))
  868. {
  869. if (bClsIdFound)
  870. {
  871. if (0 == memcmp(&gIpId.ipid,&ClsidToSearch,sizeof(CLSID)))
  872. {
  873. DumpIPID(gIpId);
  874. }
  875. }
  876. else
  877. {
  878. if (nItems > 0)
  879. {
  880. dprintf(" -------- tagIPIDEntry %p - %x\n",pCurrentIPID,nItems-1);
  881. DumpIPID(gIpId);
  882. }
  883. nItems++;
  884. }
  885. }
  886. else
  887. {
  888. dprintf("RM %p\n",Addr);
  889. break;
  890. }
  891. if (CheckControlC())
  892. break;
  893. } while (Addr != (MEMORY_ADDRESS)gIpId.pOIDFLink);
  894. }
  895. else
  896. {
  897. dprintf("uanble to resolve ole32!CIPIDTable___oidListHead\n");
  898. }
  899. }
  900. typedef GUID MOXID;
  901. typedef ULONG64 MID;
  902. typedef void CComApartment;
  903. typedef void CChannelHandle;
  904. typedef void MIDEntry;
  905. typedef void IRemUnknown;
  906. class OXIDEntry
  907. {
  908. private:
  909. OXIDEntry *_pNext; // next entry on free/inuse list
  910. OXIDEntry *_pPrev; // previous entry on inuse list
  911. DWORD _dwPid; // process id of server
  912. DWORD _dwTid; // thread id of server
  913. MOXID _moxid; // object exporter identifier + machine id
  914. MID _mid; // copy of our _pMIDEntry's mid value
  915. IPID _ipidRundown; // IPID of IRundown and Remote Unknown
  916. DWORD _dwFlags; // state flags
  917. HWND _hServerSTA; // HWND of server
  918. CComApartment *_pParentApt; // Parent apartment, not ref counted
  919. public:
  920. // CODEWORK: channel accessing this member variable directly
  921. CChannelHandle *_pRpc; // Binding handle info for server
  922. private:
  923. void *_pAuthId; // must be held till rpc handle is freed
  924. DUALSTRINGARRAY *_pBinding; // protseq and security strings.
  925. DWORD _dwAuthnHint; // authentication level hint.
  926. DWORD _dwAuthnSvc; // index of default authentication service.
  927. MIDEntry *_pMIDEntry; // MIDEntry for machine where server lives
  928. IRemUnknown *_pRUSTA; // proxy for Remote Unknown
  929. LONG _cRefs; // count of IPIDs using this OXIDEntry
  930. HANDLE _hComplete; // set when last outstanding call completes
  931. LONG _cCalls; // number of calls dispatched
  932. LONG _cResolverRef; //References to resolver
  933. DWORD _dwExpiredTime; // rundown timer ID for STA servers
  934. COMVERSION _version; // COM version of the machine
  935. unsigned long _ulMarshaledTargetInfoLength; // credman credentials length
  936. unsigned char *_pMarshaledTargetInfo; // credman credentials
  937. };
  938. void PrintDSA(DUALSTRINGARRAY * pDSA_OOP)
  939. {
  940. if (pDSA_OOP)
  941. {
  942. DUALSTRINGARRAY DSA;
  943. if (ReadMemory((ULONG_PTR)pDSA_OOP,&DSA,sizeof(DSA),NULL))
  944. {
  945. DWORD Size = sizeof(DUALSTRINGARRAY)+(1+DSA.wNumEntries)*sizeof(WCHAR);
  946. DUALSTRINGARRAY * pDSA = (DUALSTRINGARRAY *)_alloca(Size);
  947. if (ReadMemory((ULONG_PTR)pDSA_OOP,pDSA,Size,0))
  948. {
  949. dprintf(" %S\n",pDSA->aStringArray);
  950. }
  951. else
  952. {
  953. dprintf("RM %p\n",pDSA_OOP);
  954. }
  955. }
  956. else
  957. {
  958. dprintf("RM %p\n",pDSA_OOP);
  959. }
  960. }
  961. }
  962. void PrintOxid(OXIDEntry * pEntry)
  963. {
  964. // _pNext
  965. // _pPrev
  966. dprintf(" _dwPid %x\n",pEntry->_dwPid);
  967. dprintf(" _dwTid %x\n",pEntry->_dwTid);
  968. dprintf(" _moxid\n");
  969. PrintIID(pEntry->_moxid);
  970. dprintf(" _mid %016x\n",pEntry->_mid);
  971. dprintf(" _ipidRundown\n");
  972. PrintIID(pEntry->_ipidRundown);
  973. dprintf(" _dwFlags %08x\n",pEntry->_dwFlags);
  974. dprintf(" _hServerSTA %p\n",pEntry->_hServerSTA);
  975. dprintf(" _pParentApt %p\n",pEntry->_pParentApt);
  976. dprintf(" _pRpc %p\n",pEntry->_pRpc);
  977. dprintf(" _pAuthId %p\n",pEntry->_pAuthId);
  978. dprintf(" _pBinding %p\n",pEntry->_pBinding);
  979. PrintDSA(pEntry->_pBinding);
  980. dprintf(" _dwAuthnHint %x\n",pEntry->_dwAuthnHint);
  981. dprintf(" _dwAuthnSvc %x\n",pEntry->_dwAuthnSvc);
  982. dprintf(" _pMIDEntry %p\n",pEntry->_pMIDEntry);
  983. dprintf(" _pRUSTA %p\n",pEntry->_pRUSTA);
  984. dprintf(" _cRefs %x\n",pEntry->_cRefs);
  985. dprintf(" _hComplete %x\n",pEntry->_hComplete);
  986. dprintf(" _cCalls %x\n",pEntry->_cCalls);
  987. dprintf(" _cResolverRef %x\n",pEntry->_cResolverRef);
  988. // _dwExpiredTime
  989. // _version
  990. // _ulMarshaledTargetInfoLength
  991. // _pMarshaledTargetInfo
  992. }
  993. DECLARE_API( goxid )
  994. {
  995. INIT_API();
  996. ULONG_PTR Addr = GetExpression("ole32!gOXIDTbl");
  997. if (NULL == Addr)
  998. {
  999. dprintf("unable to resolve ole32!gOXIDTbl\n");
  1000. return;
  1001. }
  1002. struct OxidTable
  1003. {
  1004. DWORD _cExpired;
  1005. OXIDEntry _InUseHead;
  1006. OXIDEntry _ExpireHead;
  1007. OXIDEntry _CleanupHead;
  1008. } _OxidTable;
  1009. if (ReadMemory(Addr,&_OxidTable,sizeof(_OxidTable),NULL))
  1010. {
  1011. OXIDEntry * pHead_OOP;
  1012. DWORD nEntry;
  1013. pHead_OOP = (OXIDEntry *)GetExpression("ole32!COXIDTable::_InUseHead");
  1014. nEntry = 0;
  1015. dprintf("ole32!gOXIDTbl:_InUseHead %p\n",pHead_OOP);
  1016. ULONG_PTR AddrToRead = (ULONG_PTR)pHead_OOP;
  1017. do
  1018. {
  1019. if (ReadMemory(AddrToRead,&_OxidTable._InUseHead,sizeof(OXIDEntry),NULL))
  1020. {
  1021. if (nEntry)
  1022. {
  1023. dprintf(" OXIDEntry %p - %d\n",AddrToRead,nEntry-1);
  1024. PrintOxid(&_OxidTable._InUseHead);
  1025. }
  1026. AddrToRead = (ULONG_PTR)_OxidTable._InUseHead._pNext;
  1027. }
  1028. else
  1029. {
  1030. dprintf("RM %p\n",AddrToRead);
  1031. }
  1032. nEntry++;
  1033. if (CheckControlC())
  1034. break;
  1035. }
  1036. while (pHead_OOP != _OxidTable._InUseHead._pNext);
  1037. pHead_OOP = (OXIDEntry *)GetExpression("ole32!COXIDTable::_ExpireHead");
  1038. nEntry = 0;
  1039. dprintf("ole32!gOXIDTbl:_ExpireHead %p\n",pHead_OOP);
  1040. AddrToRead = (ULONG_PTR)pHead_OOP;
  1041. do
  1042. {
  1043. if (ReadMemory(AddrToRead,&_OxidTable._InUseHead,sizeof(OXIDEntry),NULL))
  1044. {
  1045. if (nEntry)
  1046. {
  1047. dprintf(" OXIDEntry %p - %d\n",AddrToRead,nEntry-1);
  1048. PrintOxid(&_OxidTable._InUseHead);
  1049. }
  1050. AddrToRead = (ULONG_PTR)_OxidTable._InUseHead._pNext;
  1051. }
  1052. else
  1053. {
  1054. dprintf("RM %p\n",AddrToRead);
  1055. }
  1056. nEntry++;
  1057. if (CheckControlC())
  1058. break;
  1059. }
  1060. while (pHead_OOP != _OxidTable._InUseHead._pNext);
  1061. pHead_OOP = (OXIDEntry *)GetExpression("ole32!COXIDTable::_CleanupHead");
  1062. nEntry = 0;
  1063. dprintf("ole32!gOXIDTbl:_InUseHead %p\n",pHead_OOP);
  1064. AddrToRead = (ULONG_PTR)pHead_OOP;
  1065. do
  1066. {
  1067. if (ReadMemory(AddrToRead,&_OxidTable._InUseHead,sizeof(OXIDEntry),NULL))
  1068. {
  1069. if (nEntry)
  1070. {
  1071. dprintf(" OXIDEntry %p - %d\n",AddrToRead,nEntry-1);
  1072. PrintOxid(&_OxidTable._InUseHead);
  1073. }
  1074. AddrToRead = (ULONG_PTR)_OxidTable._InUseHead._pNext;
  1075. }
  1076. else
  1077. {
  1078. dprintf("RM %p\n",AddrToRead);
  1079. }
  1080. nEntry++;
  1081. if (CheckControlC())
  1082. break;
  1083. }
  1084. while (pHead_OOP != _OxidTable._InUseHead._pNext);
  1085. }
  1086. else
  1087. {
  1088. dprintf("RM %p\n",Addr);
  1089. }
  1090. }
  1091. DECLARE_API( ipidl )
  1092. {
  1093. INIT_API();
  1094. IPIDEntry IpId;
  1095. MEMORY_ADDRESS Addr = GetExpression(args);
  1096. if (Addr)
  1097. {
  1098. DWORD nCount=0;
  1099. while (Addr &&
  1100. ReadMemory(Addr,&IpId,sizeof(IpId),NULL))
  1101. {
  1102. dprintf(" -- %x\n",nCount);
  1103. DumpIPID(IpId);
  1104. Addr = (MEMORY_ADDRESS)IpId.pNextIPID;
  1105. nCount++;
  1106. if (CheckControlC())
  1107. break;
  1108. };
  1109. }
  1110. else
  1111. {
  1112. dprintf(" unable to resolve %s\n",args);
  1113. }
  1114. }
  1115. void PrintCLSID(GUID & CurrUUID){
  1116. WCHAR pszClsID[40];
  1117. StringFromGUID2(CurrUUID,pszClsID,40);
  1118. // look-up known
  1119. DWORD i;
  1120. for (i=0;i<g_nClsids;i++){
  1121. if(IsEqualGUID(CurrUUID,*g_ArrayCLSID[i].pClsid)){
  1122. dprintf(" CLSID %s\n",g_ArrayCLSID[i].pStrClsid);
  1123. break;
  1124. }
  1125. }
  1126. WCHAR pszFullPath[MAX_PATH];
  1127. lstrcpyW(pszFullPath,L"CLSID\\");
  1128. lstrcatW(pszFullPath,pszClsID);
  1129. char pDataA[MAX_PATH];
  1130. HKEY hKey;
  1131. LONG lRes;
  1132. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  1133. pszFullPath,
  1134. 0,
  1135. KEY_READ,
  1136. &hKey);
  1137. if (lRes == ERROR_SUCCESS){
  1138. DWORD dwType;
  1139. WCHAR pData[MAX_PATH];
  1140. DWORD dwSize=sizeof(pData);
  1141. lRes = RegQueryValueExW(hKey,
  1142. NULL, // default
  1143. NULL,
  1144. &dwType,
  1145. (BYTE *)pData,
  1146. &dwSize);
  1147. if (lRes == ERROR_SUCCESS) {
  1148. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  1149. dprintf(" ProgID %s\n",pDataA);
  1150. };
  1151. RegCloseKey(hKey);
  1152. // no open InProcServer32
  1153. WCHAR pszFullPathDll[MAX_PATH];
  1154. lstrcpyW(pszFullPathDll,pszFullPath);
  1155. lstrcatW(pszFullPathDll,L"\\InprocServer32");
  1156. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  1157. pszFullPathDll,
  1158. 0,
  1159. KEY_READ,
  1160. &hKey);
  1161. if (lRes == ERROR_SUCCESS){
  1162. dwSize = sizeof(pData);
  1163. lRes = RegQueryValueExW(hKey,
  1164. NULL, // default
  1165. NULL,
  1166. &dwType,
  1167. (BYTE *)pData,
  1168. &dwSize);
  1169. if (lRes == ERROR_SUCCESS) {
  1170. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  1171. dprintf(" Path: %s\n",pDataA);
  1172. };
  1173. RegCloseKey(hKey);
  1174. }
  1175. } else {
  1176. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  1177. dprintf(" CLSID %s\n",pDataA);
  1178. }
  1179. }
  1180. class CTableElement;
  1181. class CHashTable
  1182. {
  1183. private:
  1184. DWORD _cBuckets;
  1185. DWORD _cElements;
  1186. CTableElement **_buckets;
  1187. CTableElement *_last;
  1188. };
  1189. typedef int EnumEntryType;
  1190. typedef void CSharedLock;
  1191. typedef void CServerTable;
  1192. class CProcess;
  1193. class CServerList
  1194. {
  1195. public:
  1196. void * _first;
  1197. void * _last;
  1198. };
  1199. class CServerTableEntry{
  1200. private:
  1201. void * pvtable;
  1202. DWORD _references;
  1203. CServerTableEntry * _pnext;
  1204. //CLSID _GUID;
  1205. unsigned __int64 _id1;
  1206. unsigned __int64 _id2;
  1207. EnumEntryType _EntryType;
  1208. CSharedLock * _pParentTableLock;
  1209. CServerTable * _pParentTable;
  1210. LONG _lThreadToken;
  1211. DWORD _dwProcessId;
  1212. HANDLE _hProcess;
  1213. CProcess* _pProcess;
  1214. void * _pvRunAsHandle;
  1215. BOOL _bSuspendedClsid;
  1216. BOOL _bSuspendedApplication;
  1217. // the _bRetired flag exists per-running process/application
  1218. CServerList _ServerList;
  1219. //CSharedLock _ServerLock;
  1220. };
  1221. /*
  1222. 0:008> dt rpcss!CServerListEntry 000a2608
  1223. +0x008 _flink : (null)
  1224. +0x00c _blink : (null)
  1225. +0x000 __VFN_table : 0x757f3a58
  1226. +0x004 _references :
  1227. +0x010 _pServerTableEntry : 0x000a3e38
  1228. +0x014 _pServerProcess : 0x00092568
  1229. +0x018 _hRpc : (null)
  1230. +0x01c _ipid : _GUID {0000dc01-0304-0000-905a-1b00ffec5639}
  1231. +0x02c _Context : 0x2 ''
  1232. +0x02d _State : 0 ''
  1233. +0x02e _NumCalls : 0
  1234. +0x030 _RegistrationKey : 0x10
  1235. +0x034 _lThreadToken : 0
  1236. +0x038 _SubContext : 0 ''
  1237. +0x03c _lSingleUseStatus : 0
  1238. +0x040 _dwServerFaults : 0
  1239. */
  1240. struct CServerListEntry
  1241. {
  1242. void * pvtable;
  1243. DWORD _references;
  1244. void * _flink;
  1245. void * _blink;
  1246. void * _pServerTableEntry;
  1247. void * _pServerProcess;
  1248. void * _hRpc;
  1249. GUID _ipid;
  1250. };
  1251. /*
  1252. 0:002> dt rpcss!CServerTableEntry 6fb`ffcdb170
  1253. +0x000 __VFN_table : 0x00000000`702a2b60
  1254. +0x008 _references :
  1255. +0x010 _pnext : (null)
  1256. +0x018 _id : 0x11d0f196`61738644
  1257. +0x020 _id2 : 0xc119d94f`c0005399
  1258. +0x028 _EntryType : 0 ( ENTRY_TYPE_CLASS )
  1259. +0x030 _pParentTableLock : 0x000006fb`ffc9d590
  1260. +0x038 _pParentTable : 0x000006fb`ffc9d700
  1261. +0x040 _bComPlusProcess : 0
  1262. +0x044 _lThreadToken : 0
  1263. +0x048 _dwProcessId : 0
  1264. +0x050 _hProcess : (null)
  1265. +0x058 _pProcess : (null)
  1266. +0x060 _pvRunAsHandle : (null)
  1267. +0x068 _bSuspendedClsid : 0
  1268. +0x06c _bSuspendedApplication : 0
  1269. +0x070 _ServerList : CServerList
  1270. +0x080 _ServerLock : CSharedLock
  1271. */
  1272. DECLARE_API( rot )
  1273. {
  1274. INIT_API();
  1275. CHashTable * pChashTable;
  1276. MEMORY_ADDRESS Addr = GetExpression("rpcss!gpClassTable");
  1277. if (Addr)
  1278. {
  1279. CHashTable * pChashTable;
  1280. CHashTable MyHashTable;
  1281. if (ReadMemory(Addr,&pChashTable,sizeof(CHashTable *),0))
  1282. {
  1283. dprintf("CServerTable %p\n",pChashTable);
  1284. if (ReadMemory((ULONG_PTR)pChashTable,&MyHashTable,sizeof(CHashTable),NULL))
  1285. {
  1286. CTableElement ** StackArray = (CTableElement **)_alloca(MyHashTable._cBuckets * sizeof(CTableElement *));
  1287. ReadMemory((ULONG_PTR)MyHashTable._buckets,StackArray,MyHashTable._cBuckets * sizeof(CTableElement *),NULL);
  1288. DWORD i;
  1289. for (i=0;i<MyHashTable._cBuckets;i++)
  1290. {
  1291. CServerTableEntry * pEntry = (CServerTableEntry *)StackArray[i];
  1292. while (pEntry)
  1293. {
  1294. CheckControlC();
  1295. CServerTableEntry ClassEntry;
  1296. if (ReadMemory((ULONG_PTR)pEntry,&ClassEntry,sizeof(ClassEntry),NULL))
  1297. {
  1298. dprintf("CServerTableEntry %p\n",pEntry);
  1299. PrintCLSID(*(GUID *)(&(ClassEntry._id1)));
  1300. //dprintf(" _hProcess %x\n",ClassEntry._hProcess);
  1301. //dprintf(" _dwProcessId %d\n",ClassEntry._dwProcessId);
  1302. dprintf(" _ServerList %p %p\n",ClassEntry._ServerList._first,ClassEntry._ServerList._last);
  1303. CServerListEntry * pSrvListEntry = CONTAINING_RECORD(ClassEntry._ServerList._first,CServerListEntry,_flink);
  1304. while(pSrvListEntry)
  1305. {
  1306. CServerListEntry SrvListEntry;
  1307. if (ReadMemory((ULONG_PTR)pSrvListEntry,&SrvListEntry,sizeof(SrvListEntry),NULL))
  1308. {
  1309. dprintf(" CServerListEntry %p\n",pSrvListEntry);
  1310. dprintf(" _pServerTableEntry %p\n",SrvListEntry._pServerTableEntry);
  1311. dprintf(" _pServerProcess %p\n",SrvListEntry._pServerProcess);
  1312. dprintf(" _hRpc %p\n",SrvListEntry._hRpc);
  1313. WCHAR TmpGuid[64];
  1314. StringFromGUID2(SrvListEntry._ipid,TmpGuid,64);
  1315. dprintf(" _ipid %S\n",TmpGuid);
  1316. pSrvListEntry = (CServerListEntry *)SrvListEntry._flink;
  1317. }
  1318. else
  1319. {
  1320. dprintf("RM %p\n",pSrvListEntry);
  1321. pSrvListEntry = NULL;
  1322. }
  1323. }
  1324. pEntry = ClassEntry._pnext;
  1325. }
  1326. else
  1327. {
  1328. dprintf("RM %p\n",pEntry);
  1329. pEntry = NULL;
  1330. }
  1331. }
  1332. }
  1333. }
  1334. else
  1335. {
  1336. dprintf("RM %p\n",pChashTable);
  1337. }
  1338. }
  1339. else
  1340. {
  1341. dprintf("RM %p\n",Addr);
  1342. }
  1343. }
  1344. else
  1345. {
  1346. dprintf("unable to resolve rpcss!gpClassTable");
  1347. }
  1348. }
  1349. class CBList
  1350. {
  1351. public:
  1352. ULONG _ulmaxData;
  1353. ULONG _ulcElements;
  1354. PVOID *_data;
  1355. };
  1356. class CReferencedObject
  1357. {
  1358. public:
  1359. ULONG _references;
  1360. virtual ~CReferencedObject(){};
  1361. };
  1362. class CToken;
  1363. class ScmProcessReg;
  1364. class CList;
  1365. class CListElement
  1366. {
  1367. public:
  1368. CListElement *_flink;
  1369. CListElement *_blink;
  1370. };
  1371. class CClassReg : public CListElement
  1372. {
  1373. public :
  1374. GUID _Guid;
  1375. DWORD _Reg;
  1376. };
  1377. class CList
  1378. {
  1379. private:
  1380. CListElement *_first;
  1381. CListElement *_last;
  1382. };
  1383. class CProcess : public CReferencedObject
  1384. {
  1385. private:
  1386. DWORD _cClientReferences;
  1387. CToken *_pToken;
  1388. WCHAR *_pwszWinstaDesktop;
  1389. RPC_BINDING_HANDLE _hProcess;
  1390. BOOL _fCacheFree;
  1391. DUALSTRINGARRAY *_pdsaLocalBindings;
  1392. DUALSTRINGARRAY *_pdsaRemoteBindings;
  1393. ULONG _ulClasses;
  1394. ScmProcessReg *_pScmProcessReg;
  1395. DUALSTRINGARRAY *_pdsaCustomProtseqs;
  1396. void *_pvRunAsHandle;
  1397. DWORD _procID;
  1398. volatile DWORD _dwFlags;
  1399. void* _pSCMProcessInfo;
  1400. GUID _guidProcessIdentifier;
  1401. HANDLE _hProcHandle;
  1402. FILETIME _ftCreated;
  1403. DWORD64 _dwCurrentBindingsID;
  1404. DWORD _dwAsyncUpdatesOutstanding; // for debug purposes?
  1405. void *_pvFirstROTEntry;
  1406. BOOL _fReadCustomProtseqs;
  1407. CBList _blistOxids;
  1408. CBList _blistOids;
  1409. CList _listClasses;
  1410. DWORD _cDropTargets;
  1411. };
  1412. DECLARE_API(gpl)
  1413. {
  1414. INIT_API();
  1415. //dt rpcss!gpProcessList
  1416. ULONG_PTR Addr = GetExpression("rpcss!gpProcessList");
  1417. if (Addr)
  1418. {
  1419. CBList * pList_OOP;
  1420. if (ReadMemory(Addr,&pList_OOP,sizeof(ULONG_PTR),NULL))
  1421. {
  1422. CBList List;
  1423. if (ReadMemory((ULONG_PTR)pList_OOP,&List,sizeof(List),0))
  1424. {
  1425. PVOID * ppData = new PVOID[List._ulmaxData];
  1426. if (ppData)
  1427. {
  1428. if (ReadMemory((ULONG_PTR)List._data,ppData,sizeof(PVOID)*List._ulmaxData,NULL))
  1429. {
  1430. for (ULONG_PTR i=0;i<List._ulmaxData;i++)
  1431. {
  1432. CProcess * pProc = (CProcess *)ppData[i];
  1433. if (pProc)
  1434. {
  1435. CProcess Proc;
  1436. if (ReadMemory((ULONG_PTR)pProc,&Proc,sizeof(Proc),0))
  1437. {
  1438. dprintf(" CProcess %p\n",pProc);
  1439. dprintf(" _procID %08x BINDING_HANDLE %p\n",Proc._procID,Proc._hProcess);
  1440. CClassReg ClassRegInst;
  1441. CClassReg * pFirst = (CClassReg *)Proc._listClasses._first;
  1442. while(pFirst)
  1443. {
  1444. if (ReadMemory((ULONG_PTR)pFirst,&ClassRegInst,sizeof(ClassRegInst),0))
  1445. {
  1446. PrintCLSID(ClassRegInst._Guid);
  1447. pFirst = (CClassReg *)ClassRegInst._flink;
  1448. }
  1449. else
  1450. {
  1451. dprintf("RM %p\n",pFirst);
  1452. break;
  1453. }
  1454. }
  1455. }
  1456. else
  1457. {
  1458. dprintf("RM %p\n",pProc);
  1459. }
  1460. }
  1461. }
  1462. }
  1463. else
  1464. {
  1465. dprintf("RM %p\n",List._data);
  1466. }
  1467. delete [] ppData;
  1468. }
  1469. }
  1470. else
  1471. {
  1472. dprintf("RM %p\n",pList_OOP);
  1473. }
  1474. }
  1475. else
  1476. {
  1477. dprintf("RM %p\n",Addr);
  1478. }
  1479. }
  1480. else
  1481. {
  1482. dprintf("unable to resolve rpcss!gpProcessList");
  1483. }
  1484. }
  1485. typedef struct SHashChain
  1486. {
  1487. struct SHashChain *pNext; // ptr to next node in chain
  1488. struct SHashChain *pPrev; // ptr to prev node in chain
  1489. } SHashChain;
  1490. typedef struct SNameHashNode
  1491. {
  1492. SHashChain chain; // double linked list ptrs
  1493. DWORD dwHash; // hash value of the key
  1494. ULONG cRef; // count of references
  1495. IPID ipid; // ipid holding the reference
  1496. SECURITYBINDING sName; // user name
  1497. } SNameHashNode;
  1498. class COleStaticMutexSem;
  1499. class CStaticRWLock;
  1500. class CHashTable2
  1501. {
  1502. public:
  1503. virtual ~CHashTable2(){};
  1504. COleStaticMutexSem *_pExLock; // exclusive lock
  1505. CStaticRWLock *_pRWLock; // read-write lock
  1506. SHashChain *_buckets; // ptr to array of double linked lists
  1507. ULONG _cCurEntries; // current num entries in the table
  1508. ULONG _cMaxEntries; // max num entries in the table at 1 time
  1509. };
  1510. void PrintNameNode(SNameHashNode * pNode)
  1511. {
  1512. dprintf(" dwHash %08x\n",pNode->dwHash); // hash value of the key
  1513. dprintf(" cRef %08x\n",pNode->cRef); // count of references
  1514. dprintf(" ipid\n");
  1515. PrintIID(pNode->ipid); // ipid holding the reference
  1516. dprintf(" sName %S\n",&pNode->sName.aPrincName);
  1517. }
  1518. #define NUM_HASH_BUCKETS 23
  1519. DECLARE_API( srtbl )
  1520. {
  1521. INIT_API();
  1522. CHashTable2 * pChashTable;
  1523. MEMORY_ADDRESS Addr = GetExpression("ole32!gSRFTbl");
  1524. if (Addr)
  1525. {
  1526. dprintf("CNameHashTable %p\n",Addr);
  1527. CHashTable2 MyHashTable;
  1528. if (ReadMemory((ULONG_PTR)Addr,&MyHashTable,sizeof(CHashTable2),NULL))
  1529. {
  1530. SHashChain * StackArray = (SHashChain *)_alloca(NUM_HASH_BUCKETS * sizeof(SHashChain));
  1531. ReadMemory((ULONG_PTR)MyHashTable._buckets,StackArray,NUM_HASH_BUCKETS * sizeof(SHashChain),NULL);
  1532. DWORD i;
  1533. SHashChain * pEntry_OOP = (SHashChain *)MyHashTable._buckets;
  1534. for (i=0;i < NUM_HASH_BUCKETS;pEntry_OOP++,i++)
  1535. {
  1536. SHashChain * pEntry = StackArray[i].pNext;
  1537. //dprintf("%p %p\n",pEntry_OOP,pEntry);
  1538. while (pEntry != pEntry_OOP)
  1539. {
  1540. if (CheckControlC()) break;
  1541. struct _NameNode : SNameHashNode
  1542. {
  1543. WCHAR UserName[256];
  1544. } Node;
  1545. Node.UserName[0] = 0;
  1546. if (ReadMemory((ULONG_PTR)pEntry,&Node,sizeof(Node),NULL))
  1547. {
  1548. dprintf("SNameHashNode %p\n",pEntry);
  1549. PrintNameNode(&Node);
  1550. pEntry = Node.chain.pNext;
  1551. }
  1552. else
  1553. {
  1554. dprintf("RM %p\n");
  1555. break;
  1556. }
  1557. }
  1558. }
  1559. }
  1560. else
  1561. {
  1562. dprintf("RM %p\n",Addr);
  1563. }
  1564. }
  1565. else
  1566. {
  1567. dprintf("unable to resolve ole32!gSRFTbl");
  1568. }
  1569. }
  1570. /*
  1571. struct RTL_CRITICAL_SECTION_DEBUG {
  1572. USHORT Type; //: 0x0
  1573. USHORT CreatorBackTraceIndex; //: 0x0
  1574. CRITICAL_SECTION * CriticalSection; //: 0x77fcae40
  1575. LIST_ENTRY ProcessLocksList; //:
  1576. DWORD EntryCount; //: 0x0
  1577. DWORD ContentionCount; //: 0x0
  1578. DWORD Spare[2]; //:0x0
  1579. };
  1580. */
  1581. //
  1582. //
  1583. // CallBack for enumeration of critical section
  1584. //
  1585. //
  1586. /////////////////////////////////////////////////////////////
  1587. DWORD
  1588. EnumListCritSec(VOID * pStructure_OOP,
  1589. VOID * pLocalStructure)
  1590. {
  1591. RTL_CRITICAL_SECTION_DEBUG * pDebugInfo = (RTL_CRITICAL_SECTION_DEBUG *)pLocalStructure;
  1592. dprintf(" CS %p DI %p \n",pDebugInfo->CriticalSection,pStructure_OOP);
  1593. RTL_CRITICAL_SECTION CritSec;
  1594. if (ReadMemory((ULONG_PTR)pDebugInfo->CriticalSection,&CritSec,sizeof(RTL_CRITICAL_SECTION),NULL))
  1595. {
  1596. dprintf(" - %p %x %x %x\n",
  1597. CritSec.DebugInfo,
  1598. CritSec.LockCount,
  1599. CritSec.RecursionCount,
  1600. CritSec.OwningThread);
  1601. }
  1602. else
  1603. {
  1604. dprintf("RM %p\n",pDebugInfo->CriticalSection);
  1605. }
  1606. return 0;
  1607. }
  1608. #define ARRAY_TO_GO_BACK 16
  1609. DWORD
  1610. EnumListCritSec2(VOID * pStructure_OOP,
  1611. VOID * pLocalStructure)
  1612. {
  1613. RTL_CRITICAL_SECTION_DEBUG * pDebugInfo = (RTL_CRITICAL_SECTION_DEBUG *)pLocalStructure;
  1614. dprintf(" CS %p DI %p \n",pDebugInfo->CriticalSection,pStructure_OOP);
  1615. struct _TmpStr {
  1616. ULONG_PTR Array[ARRAY_TO_GO_BACK];
  1617. RTL_CRITICAL_SECTION CritSec;
  1618. } TmpStr;
  1619. if (ReadMemory(((ULONG_PTR)pDebugInfo->CriticalSection) - FIELD_OFFSET(_TmpStr,CritSec),&TmpStr,sizeof(_TmpStr),NULL))
  1620. {
  1621. dprintf(" - %p %x %x %x\n",
  1622. TmpStr.CritSec.DebugInfo,
  1623. TmpStr.CritSec.LockCount,
  1624. TmpStr.CritSec.RecursionCount,
  1625. TmpStr.CritSec.OwningThread);
  1626. for (int i=(ARRAY_TO_GO_BACK-1);i>=0;i--)
  1627. {
  1628. if (GetVTable((MEMORY_ADDRESS)TmpStr.Array[i]))
  1629. {
  1630. break; // don't be too verbose
  1631. }
  1632. }
  1633. }
  1634. else
  1635. {
  1636. dprintf("RM around %p\n",pDebugInfo->CriticalSection);
  1637. }
  1638. return 0;
  1639. }
  1640. DECLARE_API( cs )
  1641. {
  1642. INIT_API();
  1643. MEMORY_ADDRESS Addr = GetExpression("ntdll!RtlCriticalSectionList");
  1644. MEMORY_ADDRESS bGoAndFindVTable = TRUE;
  1645. if (!Addr)
  1646. {
  1647. Addr = GetExpression(args);
  1648. }
  1649. else
  1650. {
  1651. bGoAndFindVTable = GetExpression(args);
  1652. }
  1653. if (Addr)
  1654. {
  1655. if (bGoAndFindVTable)
  1656. {
  1657. EnumLinkedListCB((LIST_ENTRY *)Addr,
  1658. sizeof(RTL_CRITICAL_SECTION_DEBUG),
  1659. FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList),
  1660. EnumListCritSec2);
  1661. }
  1662. else
  1663. {
  1664. EnumLinkedListCB((LIST_ENTRY *)Addr,
  1665. sizeof(RTL_CRITICAL_SECTION_DEBUG),
  1666. FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList),
  1667. EnumListCritSec);
  1668. }
  1669. }
  1670. else
  1671. {
  1672. dprintf("unable to resolve ntdll!RtlCriticalSectionList\n");
  1673. }
  1674. }
  1675. BOOL
  1676. GetVTable(MEMORY_ADDRESS pThis_OOP){
  1677. MEMORY_ADDRESS pVTable;
  1678. ReadMemory(pThis_OOP,&pVTable,sizeof(pVTable),0);
  1679. BYTE pString[256];
  1680. pString[0]=0;
  1681. #ifdef KDEXT_64BIT
  1682. ULONG64 Displ;
  1683. #else
  1684. ULONG Displ;
  1685. #endif
  1686. GetSymbol(pVTable,(PCHAR)pString,&Displ);
  1687. if (lstrlenA((CHAR *)pString))
  1688. {
  1689. dprintf(" %s+%x\n",pString,Displ);
  1690. return TRUE;
  1691. }
  1692. else
  1693. {
  1694. return FALSE;
  1695. }
  1696. }
  1697. /*
  1698. kd> dt ntdll!RTL_CRITICAL_SECTION
  1699. +0x000 DebugInfo : Ptr64 _RTL_CRITICAL_SECTION_DEBUG
  1700. +0x008 LockCount : Int4B
  1701. +0x00c RecursionCount : Int4B
  1702. +0x010 OwningThread : Ptr64 Void
  1703. +0x018 LockSemaphore : Ptr64 Void
  1704. +0x020 SpinCount : Uint8B
  1705. kd> dt ntdll!_RTL_CRITICAL_SECTION_DEBUG
  1706. +0x000 Type : Uint2B
  1707. +0x002 CreatorBackTraceIndex : Uint2B
  1708. +0x008 CriticalSection : Ptr64 _RTL_CRITICAL_SECTION
  1709. +0x010 ProcessLocksList : _LIST_ENTRY
  1710. +0x020 EntryCount : Uint4B
  1711. +0x024 ContentionCount : Uint4B
  1712. +0x028 Spare : [2] Uint4B
  1713. kd>
  1714. */
  1715. #ifdef KDEXT_64BIT
  1716. struct _LIST_ENTRY_64
  1717. {
  1718. ULONG64 Flink;
  1719. ULONG64 Blink;
  1720. };
  1721. struct _RTL_CRITICAL_SECTION_64
  1722. {
  1723. ULONG64 DebugInfo;
  1724. DWORD LockCount;
  1725. DWORD RecursionCount;
  1726. ULONG64 OwningThread;
  1727. ULONG64 LockSemaphore;
  1728. ULONG64 SpinCount;
  1729. };
  1730. struct _RTL_CRITICAL_SECTION_DEBUG_64
  1731. {
  1732. WORD Type;
  1733. WORD CreatorBackTraceIndex;
  1734. ULONG64 CriticalSection;
  1735. _LIST_ENTRY_64 ProcessLocksList;
  1736. DWORD EntryCount;
  1737. DWORD ContentionCount;
  1738. DWORD Spare;
  1739. };
  1740. #endif /*KDEXT_64BIT*/
  1741. DECLARE_API(cs64)
  1742. {
  1743. INIT_API();
  1744. #ifdef KDEXT_64BIT
  1745. _RTL_CRITICAL_SECTION_DEBUG_64 DebugInfo;
  1746. _RTL_CRITICAL_SECTION_64 CritSec;
  1747. _LIST_ENTRY_64 ListEntry;
  1748. ULONG64 MemAddr = GetExpression(args);
  1749. if (MemAddr)
  1750. {
  1751. ULONG64 AddrHead = MemAddr;
  1752. if (ReadMemory(MemAddr,&ListEntry,sizeof(ListEntry),NULL))
  1753. {
  1754. DebugInfo.ProcessLocksList.Flink = ListEntry.Flink;
  1755. while (DebugInfo.ProcessLocksList.Flink != AddrHead)
  1756. {
  1757. if (CheckControlC())
  1758. break;
  1759. MemAddr = DebugInfo.ProcessLocksList.Flink - FIELD_OFFSET(_RTL_CRITICAL_SECTION_DEBUG_64,ProcessLocksList);
  1760. if (ReadMemory((MEMORY_ADDRESS)MemAddr,&DebugInfo,sizeof(DebugInfo),NULL))
  1761. {
  1762. dprintf(" C %p D %p\n",DebugInfo.CriticalSection,MemAddr);
  1763. if (ReadMemory((MEMORY_ADDRESS)DebugInfo.CriticalSection,&CritSec,sizeof(CritSec),NULL))
  1764. {
  1765. dprintf(" - CS %p %x %x %p\n",
  1766. CritSec.DebugInfo,
  1767. CritSec.LockCount,
  1768. CritSec.RecursionCount,
  1769. CritSec.OwningThread);
  1770. }
  1771. else
  1772. {
  1773. dprintf("RM %p\n",DebugInfo.CriticalSection);
  1774. }
  1775. }
  1776. else
  1777. {
  1778. break;
  1779. }
  1780. }
  1781. }
  1782. else
  1783. {
  1784. dprintf("RM %p\n",MemAddr);
  1785. }
  1786. }
  1787. else
  1788. {
  1789. dprintf("unable to resolve %s\n",args);
  1790. }
  1791. #endif /*KDEXT_64BIT*/
  1792. }