Source code of Windows XP (NT5)
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.

1403 lines
37 KiB

  1. #include <wmiexts.h>
  2. #include <malloc.h>
  3. #include <objbase.h>
  4. //IID_IStdIdentity {0000001B-0000-0000-C000-000000000046}
  5. const GUID IID_IStdIdentity = {0x0000001B,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  6. #include <data.h>
  7. #include <utilfun.h>
  8. DECLARE_API(iid) {
  9. INIT_API();
  10. GUID CurrUUID;
  11. ULONG_PTR pUUID = 0;
  12. pUUID = GetExpression(args);
  13. if (pUUID){
  14. ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0);
  15. WCHAR pszClsID[40];
  16. StringFromGUID2(CurrUUID,pszClsID,40);
  17. WCHAR pszFullPath[MAX_PATH];
  18. lstrcpyW(pszFullPath,L"Interface\\");
  19. lstrcatW(pszFullPath,pszClsID);
  20. char pDataA[MAX_PATH];
  21. HKEY hKey;
  22. LONG lRes;
  23. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  24. pszFullPath,
  25. 0,
  26. KEY_READ,
  27. &hKey);
  28. if (lRes == ERROR_SUCCESS){
  29. DWORD dwType;
  30. WCHAR pData[MAX_PATH];
  31. DWORD dwSize=sizeof(pData);
  32. lRes = RegQueryValueExW(hKey,
  33. NULL, // default
  34. NULL,
  35. &dwType,
  36. (BYTE *)pData,
  37. &dwSize);
  38. if (lRes == ERROR_SUCCESS) {
  39. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  40. dprintf(" IID_%s\n",pDataA);
  41. }
  42. RegCloseKey(hKey);
  43. } else {
  44. if (IsEqualGUID(CurrUUID,IID_IMarshal)){
  45. dprintf(" IID_IMarshal\n");
  46. } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) {
  47. dprintf(" IID_IStdIdentity\n");
  48. } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) {
  49. dprintf(" IID_ICallFactory\n");
  50. } else {
  51. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  52. dprintf("unable to open key %s\n",pDataA);
  53. }
  54. }
  55. } else {
  56. dprintf("unable to resolve %s\n",args);
  57. }
  58. }
  59. extern ArrayCLSID g_ArrayCLSID[];
  60. DECLARE_API(clsid) {
  61. INIT_API();
  62. GUID CurrUUID;
  63. ULONG_PTR pUUID = 0;
  64. pUUID = GetExpression(args);
  65. if (pUUID){
  66. ReadMemory(pUUID,&CurrUUID,sizeof(GUID),0);
  67. WCHAR pszClsID[40];
  68. StringFromGUID2(CurrUUID,pszClsID,40);
  69. // look-up known
  70. DWORD i;
  71. for (i=0;i<g_nClsids;i++){
  72. if(IsEqualGUID(CurrUUID,*g_ArrayCLSID[i].pClsid)){
  73. dprintf(" CLSID : %s\n",g_ArrayCLSID[i].pStrClsid);
  74. break;
  75. }
  76. }
  77. WCHAR pszFullPath[MAX_PATH];
  78. lstrcpyW(pszFullPath,L"CLSID\\");
  79. lstrcatW(pszFullPath,pszClsID);
  80. char pDataA[MAX_PATH];
  81. HKEY hKey;
  82. LONG lRes;
  83. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  84. pszFullPath,
  85. 0,
  86. KEY_READ,
  87. &hKey);
  88. if (lRes == ERROR_SUCCESS){
  89. DWORD dwType;
  90. WCHAR pData[MAX_PATH];
  91. DWORD dwSize=sizeof(pData);
  92. lRes = RegQueryValueExW(hKey,
  93. NULL, // default
  94. NULL,
  95. &dwType,
  96. (BYTE *)pData,
  97. &dwSize);
  98. if (lRes == ERROR_SUCCESS) {
  99. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  100. dprintf(" ProgID %s\n",pDataA);
  101. };
  102. RegCloseKey(hKey);
  103. // no open InProcServer32
  104. WCHAR pszFullPathDll[MAX_PATH];
  105. lstrcpyW(pszFullPathDll,pszFullPath);
  106. lstrcatW(pszFullPathDll,L"\\InprocServer32");
  107. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  108. pszFullPathDll,
  109. 0,
  110. KEY_READ,
  111. &hKey);
  112. if (lRes == ERROR_SUCCESS){
  113. dwSize = sizeof(pData);
  114. lRes = RegQueryValueExW(hKey,
  115. NULL, // default
  116. NULL,
  117. &dwType,
  118. (BYTE *)pData,
  119. &dwSize);
  120. if (lRes == ERROR_SUCCESS) {
  121. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  122. dprintf(" Path: %s\n",pDataA);
  123. };
  124. RegCloseKey(hKey);
  125. }
  126. } else {
  127. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  128. dprintf("unable to open key %s\n",pDataA);
  129. }
  130. } else {
  131. dprintf("unable to resolve %s\n",args);
  132. }
  133. }
  134. //
  135. //
  136. // Dumps a SAFE_ARRAY
  137. //
  138. //
  139. DECLARE_API(sa) {
  140. INIT_API();
  141. SAFEARRAY SA;
  142. ULONG_PTR pSA = 0;
  143. pSA = GetExpression(args);
  144. if (pSA){
  145. ReadMemory(pSA,&SA,sizeof(SA),0);
  146. dprintf(" cDims %d cbElements %d pvData %08x\n",SA.cDims,SA.cbElements,SA.pvData);
  147. dprintf("rgsabound.cElements %d lLbound %d\n",SA.rgsabound[0].cElements,SA.rgsabound[0].lLbound);
  148. } else {
  149. dprintf("invalid address %s\n",args);
  150. }
  151. }
  152. //
  153. // help for the extension
  154. // may commands are not listed here
  155. //
  156. //
  157. DECLARE_API(help) {
  158. INIT_API();
  159. dprintf(" WMI debugger extension\n");
  160. dprintf(" iid : print the human readable IID_xxx\n");
  161. dprintf(" clsid : print the human readable CLSID_xxx\n");
  162. dprintf(" rot : print the human readable rpcss!gpClassTable\n");
  163. dprintf(" ipidl : print the list of IPIDEntry");
  164. dprintf(" llc : print linked list count\n");
  165. dprintf(" cs : print the list of CRITICAL_SECTION\n");
  166. dprintf(" std_map : print the first 3 DWORD of a std::map<K,V>\n");
  167. dprintf(" std_queue: print the first ULONG_PTR of a std::queue<V>\n");
  168. dprintf(" mapobj : print a std::map<IUnk,bool>\n");
  169. dprintf(" -------- HEAP family\n");
  170. dprintf(" he : print the HEAP_ENTRY\n");
  171. dprintf(" hef : walks the HEAP_ENTRY list forward\n");
  172. dprintf(" hef : walks the HEAP_ENTRY list backward\n");
  173. dprintf(" hs : print the HEAP_SEGMENT\n");
  174. dprintf(" hp : print the HEAP\n");
  175. dprintf(" hps : print a summary for all the HEAP in the process\n");
  176. dprintf(" shp : <HEAP> <ADDR> search heap HEAP for address ADDR\n");
  177. dprintf(" rllc : <ADDR> prints the free list in reverse order\n");
  178. dprintf(" hpf : <HEAP> prints the free list of the heap at HEAP\n");
  179. dprintf(" php : <HEAP> [s ADDR] prints the pageheap and searches\n");
  180. dprintf(" -------- FASTPROX family\n");
  181. dprintf(" wc : print the human readable WbemClass\n");
  182. dprintf(" wi : print the human readable WbemClass\n");
  183. dprintf(" blob : ADDR [size] print (part of) the ClassObject BLOB\n");
  184. dprintf(" datap : ADDR print the WBEMDATA marshaling BLOB\n");
  185. dprintf(" cp : print the human readable CClassPart\n");
  186. dprintf(" cvar : print the CVar\n");
  187. dprintf(" -------- WBEMCORE\n");
  188. dprintf(" q : print wbemcore!g_pAsyncSvcQueue\n");
  189. dprintf(" arb : print wbemcore!CWmiArbitrator__m_pArb\n");
  190. dprintf(" -------- REPDRVFS\n");
  191. dprintf(" tmpall : print the Allocators in repdrvfs\n");
  192. dprintf(" forestc : [Addr] print the repdrvfs!CForestCache at Addr\n");
  193. dprintf(" filec : [Addr] print repdrvfs!CFileCache at Addr\n");
  194. dprintf(" fmap : \\fs\\[objects|index].map dumps the .MAP file from disk \n");
  195. dprintf(" btr : dumps the index.btr/index.map file from disk \n");
  196. dprintf(" varobj : dumps part of objects.data file from disk \n");
  197. dprintf(" -------- THREAD family\n");
  198. dprintf(" t : print RPC and OLE data for each thread\n");
  199. dprintf(" inv : <addr> [param] invokes a function in the remote thread\n");
  200. dprintf(" bs : <teb> rebuilds the stack from the info in the TEB\n");
  201. dprintf(" st : <addr> <num> prints the num DWORD saved by RtlCaptureStackBackTrace\n");
  202. dprintf(" lpp : print linked list and unassemble backtrace\n");
  203. dprintf(" vq : -a <addr> | -f Flag : calls VirtualQuery on the addr\n");
  204. dprintf(" srt : <addr> searches the stacks of all threads for addr\n");
  205. dprintf(" ksrt : <addr> searches the stacks of all threads for addr - KD only\n");
  206. dprintf(" el : <TEB> prints the exception list of the current thread x86 only\n");
  207. dprintf(" -------- ESS\n");
  208. dprintf(" ess : print wbemcore!g_pNewESS\n");
  209. dprintf(" -------- PROVSS\n");
  210. dprintf(" pc : print wbemcore!CCoreServices__m_pProvSS\n");
  211. dprintf(" pf : print CServerObject_BindingFactory\n");
  212. dprintf(" -------- 32-K-64\n");
  213. dprintf(" hef64 : <addr> HEAP_ENTRY list forward\n");
  214. dprintf(" heb64 : <addr> HEAP_ENTRY list backward\n");
  215. dprintf(" hps64 : print heap summary\n");
  216. dprintf(" cs64 : print CritSec list\n");
  217. }
  218. void
  219. EnumLinkedListCB(IN LIST_ENTRY * pListHead,
  220. IN DWORD cbSizeOfStructure,
  221. IN DWORD cbListEntryOffset,
  222. IN pfnCallBack2 CallBack)
  223. {
  224. LIST_ENTRY ListHead;
  225. LIST_ENTRY * pListEntry;
  226. DWORD cItems = 0;
  227. void * pStorage = (void *)_alloca(cbSizeOfStructure);
  228. LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset);
  229. if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL))
  230. {
  231. if (CallBack)
  232. {
  233. }
  234. else
  235. {
  236. dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink);
  237. }
  238. for ( pListEntry = ListHead.Flink;
  239. pListEntry != pListHead;)
  240. {
  241. if (CheckControlC())
  242. break;
  243. ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset);
  244. // make a local copy of the debuggee structure
  245. if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL))
  246. {
  247. if (CallBack)
  248. {
  249. CallBack((VOID *)pStructure_OOP,pStorage);
  250. }
  251. else
  252. {
  253. dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP);
  254. }
  255. pListEntry = pListEntryLocal->Flink;
  256. cItems++;
  257. }
  258. else
  259. {
  260. dprintf("RM %p\n",pStructure_OOP);
  261. break;
  262. }
  263. }
  264. dprintf( "%d entries traversed\n", cItems );
  265. }
  266. else
  267. {
  268. dprintf("RM %p\n",pListHead);
  269. }
  270. }
  271. void
  272. EnumReverseLinkedListCB(IN LIST_ENTRY * pListHead,
  273. IN DWORD cbSizeOfStructure,
  274. IN DWORD cbListEntryOffset,
  275. IN pfnCallBack2 CallBack)
  276. {
  277. LIST_ENTRY ListHead;
  278. LIST_ENTRY * pListEntry;
  279. DWORD cItems = 0;
  280. void * pStorage = (void *)_alloca(cbSizeOfStructure);
  281. LIST_ENTRY * pListEntryLocal = (LIST_ENTRY *)((BYTE *)pStorage + cbListEntryOffset);
  282. if (ReadMemory((ULONG_PTR)pListHead,&ListHead,sizeof(LIST_ENTRY),NULL))
  283. {
  284. if (CallBack)
  285. {
  286. }
  287. else
  288. {
  289. dprintf(" H %p -> %p <-\n",ListHead.Flink,ListHead.Blink);
  290. }
  291. for ( pListEntry = ListHead.Blink;
  292. pListEntry != pListHead;)
  293. {
  294. if (CheckControlC())
  295. break;
  296. ULONG_PTR pStructure_OOP = (ULONG_PTR)((BYTE *) pListEntry - cbListEntryOffset);
  297. // make a local copy of the debuggee structure
  298. if (ReadMemory(pStructure_OOP,pStorage,cbSizeOfStructure,NULL))
  299. {
  300. if (CallBack)
  301. {
  302. CallBack((VOID *)pStructure_OOP,pStorage);
  303. }
  304. else
  305. {
  306. dprintf(" %p -> %p <- - %p\n",pListEntryLocal->Flink,pListEntryLocal->Blink,pStructure_OOP);
  307. }
  308. pListEntry = pListEntryLocal->Blink;
  309. cItems++;
  310. }
  311. else
  312. {
  313. dprintf("RM %p\n",pStructure_OOP);
  314. break;
  315. }
  316. }
  317. dprintf( "%d entries traversed\n", cItems );
  318. }
  319. else
  320. {
  321. dprintf("RM %p\n",pListHead);
  322. }
  323. }
  324. //
  325. //
  326. // NO-OP callback just for getting the number of items
  327. //
  328. ///////////////////////////////////////////////////////////
  329. DWORD
  330. CallBackListCount(VOID * pStructure_OOP,
  331. VOID * pLocalCopy)
  332. {
  333. return 0;
  334. }
  335. DECLARE_API( llc )
  336. {
  337. INIT_API();
  338. ULONG_PTR Addr = GetExpression(args);
  339. if (Addr)
  340. {
  341. EnumLinkedListCB((LIST_ENTRY *)Addr,sizeof(LIST_ENTRY),0,CallBackListCount);
  342. }
  343. else
  344. {
  345. dprintf("cannot resolve %s\n",args);
  346. }
  347. }
  348. void
  349. PrintStackTrace(ULONG_PTR ArrayAddr_OOP,DWORD dwNum,BOOL bOOP)
  350. {
  351. ULONG_PTR * pArray;
  352. BOOL bRet = FALSE;
  353. if (bOOP)
  354. {
  355. pArray = ( ULONG_PTR *)_alloca(dwNum*sizeof(ULONG_PTR));
  356. bRet = ReadMemory(ArrayAddr_OOP,pArray,dwNum*sizeof(ULONG_PTR),NULL);
  357. }
  358. else
  359. {
  360. pArray = (ULONG_PTR *)ArrayAddr_OOP;
  361. bRet = TRUE;
  362. }
  363. if (bRet)
  364. {
  365. DWORD i;
  366. for (i=0;i<dwNum;i++)
  367. {
  368. BYTE pString[256];
  369. pString[0] = 0;
  370. #ifdef KDEXT_64BIT
  371. ULONG64 Displ = 0;
  372. #else
  373. ULONG Displ = 0;
  374. #endif
  375. if (pArray[i])
  376. {
  377. GetSymbol(pArray[i],(PCHAR)pString,&Displ);
  378. pString[255] = 0;
  379. dprintf(" %s+%x\n",pString,Displ);
  380. }
  381. }
  382. }
  383. }
  384. //
  385. // printf stack trace
  386. //
  387. DECLARE_API( st )
  388. {
  389. INIT_API();
  390. int Len = strlen(args);
  391. CHAR * pArgs = (CHAR *)_alloca((Len+1));
  392. lstrcpy(pArgs,(CHAR *)args);
  393. ULONG_PTR NumInst = 6;
  394. ULONG_PTR pAddr = 0;
  395. while (isspace(*pArgs))
  396. {
  397. pArgs++;
  398. }
  399. CHAR * pFirst = pArgs;
  400. while(!isspace(*pArgs)) pArgs++;
  401. // terminate string, if possible
  402. if (isspace(*pArgs))
  403. {
  404. *pArgs = 0;
  405. pArgs++;
  406. }
  407. else
  408. {
  409. pArgs = NULL;
  410. }
  411. pAddr = GetExpression(pFirst);
  412. if (pArgs)
  413. {
  414. NumInst = GetExpression(pArgs);
  415. }
  416. if (pAddr)
  417. {
  418. dprintf("StackTrace @ %p num %d\n",pAddr,NumInst);
  419. PrintStackTrace(pAddr,(DWORD)NumInst,TRUE);
  420. }
  421. else
  422. {
  423. dprintf("usage: address num\n");
  424. }
  425. }
  426. //
  427. //
  428. // this is the CallBack called by the enumerator
  429. // of a Double-Liked list of objects with
  430. // struct _Instrument
  431. // {
  432. // LIST_ENTRY ListEntry;
  433. // ULONG_PTR ArrayFuncts[32];
  434. // }
  435. //
  436. //////////////////////////////////////////////////////////
  437. DWORD
  438. CallBackCreateStacks(VOID * pStructure_OOP,
  439. VOID * pLocalStructure)
  440. {
  441. dprintf(" ----- %p \n",pStructure_OOP);
  442. PrintStackTrace((ULONG_PTR)((BYTE *)pLocalStructure+sizeof(LIST_ENTRY)),6,FALSE);
  443. return 0;
  444. }
  445. DECLARE_API( lpp )
  446. {
  447. INIT_API();
  448. ULONG_PTR Addr = GetExpression(args);
  449. if (Addr)
  450. {
  451. EnumLinkedListCB((LIST_ENTRY *)Addr,
  452. sizeof(LIST_ENTRY)+32*sizeof(ULONG_PTR),
  453. 0,
  454. CallBackCreateStacks);
  455. }
  456. else
  457. {
  458. dprintf("cannot resolve %s\n",args);
  459. }
  460. }
  461. // left parent right
  462. BOOL
  463. IsNil(_BRN * pNode){
  464. _BRN_HEAD BRN;
  465. ReadMemory((ULONG_PTR)pNode,&BRN,sizeof(_BRN_HEAD),NULL);
  466. return ((BRN._Left == NULL) &&
  467. (BRN._Right == NULL));
  468. }
  469. void
  470. PrintTree(_BRN * pNode,
  471. DWORD * pNum,
  472. BOOL Verbose,
  473. ULONG_PTR Size,
  474. pfnCallBack2 CallBack){
  475. //dprintf(" Node %p\n",pNode);
  476. _BRN BRN;
  477. if (ReadMemory((ULONG_PTR)pNode,&BRN,sizeof(_BRN),NULL))
  478. {
  479. if (!IsNil(BRN._Left)){
  480. PrintTree(BRN._Left,pNum,Verbose,Size,CallBack);
  481. };
  482. if (CheckControlC())
  483. return;
  484. if (pNum){
  485. (*pNum)++;
  486. }
  487. if (*pNum > Size)
  488. {
  489. dprintf("invalid tree\n");
  490. return;
  491. }
  492. if (Verbose) {
  493. dprintf(" %p %p (%p,%p,%p) - %p %p %p\n",
  494. (*pNum)-1,
  495. pNode,
  496. BRN._Left,BRN._Parent,BRN._Right,
  497. BRN.Values[0],
  498. BRN.Values[1],
  499. BRN.Values[2]);
  500. if (CallBack)
  501. {
  502. //dprintf("CAllBack\n");
  503. CallBack((VOID *)BRN.Values[0],(VOID *)BRN.Values[1]);
  504. }
  505. }
  506. if (!IsNil(BRN._Right)){
  507. PrintTree(BRN._Right,pNum,Verbose,Size,CallBack);
  508. };
  509. }
  510. else
  511. {
  512. dprintf(" RM %p err %d\n",pNode,GetLastError());
  513. }
  514. }
  515. void
  516. PrintMapCB(_Map * pMap,BOOL Verbose, pfnCallBack2 CallBack)
  517. {
  518. _Map MAP;
  519. if (ReadMemory((ULONG_PTR)pMap,&MAP,sizeof(_Map),NULL))
  520. {
  521. if (MAP.pQm)
  522. {
  523. dprintf(" std::map at %p : size %p\n",pMap,MAP.Size);
  524. _QM QM;
  525. if (ReadMemory((ULONG_PTR)MAP.pQm,&QM,sizeof(QM),NULL))
  526. {
  527. if (QM._Parent && !IsNil(QM._Parent))
  528. {
  529. DWORD Num = 0;
  530. PrintTree(QM._Parent,&Num,Verbose,MAP.Size,CallBack);
  531. dprintf(" traversed %d nodes\n",Num);
  532. }
  533. }
  534. else
  535. {
  536. dprintf("RM %p err %d\n",MAP.pQm,GetLastError());
  537. }
  538. } else {
  539. dprintf("empty tree\n");
  540. }
  541. }
  542. else
  543. {
  544. dprintf("RM %p\n",pMap);
  545. }
  546. }
  547. //
  548. //
  549. // prints a generic std::map
  550. //
  551. ////////////////////////////////////
  552. DECLARE_API( std_map )
  553. {
  554. INIT_API();
  555. _Map * pMap = (_Map *)GetExpression( args );
  556. if (pMap){
  557. PrintMapCB(pMap,TRUE,NULL);
  558. } else {
  559. dprintf("invalid address %s\n",args);
  560. }
  561. }
  562. void
  563. PrintListCB(_List * pList_OOP, pfnCallBack1 CallBack)
  564. {
  565. _List List;
  566. if (ReadMemory((ULONG_PTR)pList_OOP,&List,sizeof(_List),NULL))
  567. {
  568. dprintf(" std::queue @ %p _Allocator %p _Head %p _Size %p\n",pList_OOP,List._Allocator,List._Head,List._Size);
  569. _Node_List NodeList;
  570. if (ReadMemory((ULONG_PTR)List._Head,&NodeList,sizeof(_Node_List),NULL))
  571. {
  572. _Node_List * pNodeList = NodeList._Next;
  573. DWORD i = 0;
  574. while (pNodeList != List._Head)
  575. {
  576. if (CheckControlC())
  577. break;
  578. if (ReadMemory((ULONG_PTR)pNodeList,&NodeList,sizeof(_Node_List),NULL))
  579. {
  580. dprintf(" %x %p (%p, %p) - %p\n",i++,pNodeList,NodeList._Next,NodeList._Prev,NodeList._Value);
  581. if (CallBack)
  582. {
  583. CallBack(NodeList._Value);
  584. }
  585. pNodeList = NodeList._Next;
  586. }
  587. else
  588. {
  589. dprintf("RM %p\n",pNodeList);
  590. }
  591. }
  592. }
  593. else
  594. {
  595. dprintf("RM %p\n",List._Head);
  596. }
  597. }
  598. else
  599. {
  600. dprintf("RM %p\n",pList_OOP);
  601. }
  602. }
  603. //
  604. //
  605. // prints a generic std::list
  606. //
  607. //////////////////////////////////////
  608. DECLARE_API( std_queue)
  609. {
  610. INIT_API();
  611. _List * pList = (_List *)GetExpression( args );
  612. if (pList){
  613. PrintListCB(pList,NULL);
  614. } else {
  615. dprintf("invalid address %s\n",args);
  616. }
  617. }
  618. //
  619. //
  620. // this is for Pat
  621. // he has a std::map<pObject,BOOL>
  622. //
  623. //////////////////////////////////////////////////
  624. DWORD
  625. CallBackObj(void * pKey, void * pValue)
  626. {
  627. GetVTable((MEMORY_ADDRESS)pKey);
  628. return 0;
  629. }
  630. DECLARE_API( mapobj )
  631. {
  632. INIT_API();
  633. _Map * pMap = (_Map *)GetExpression( args );
  634. if (pMap){
  635. PrintMapCB(pMap,TRUE,CallBackObj);
  636. } else {
  637. dprintf("invalid address %s\n",args);
  638. }
  639. }
  640. void PrintIID(GUID & CurrUUID){
  641. WCHAR pszClsID[40];
  642. StringFromGUID2(CurrUUID,pszClsID,40);
  643. WCHAR pszFullPath[MAX_PATH];
  644. lstrcpyW(pszFullPath,L"Interface\\");
  645. lstrcatW(pszFullPath,pszClsID);
  646. char pDataA[MAX_PATH];
  647. HKEY hKey;
  648. LONG lRes;
  649. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  650. pszFullPath,
  651. 0,
  652. KEY_READ,
  653. &hKey);
  654. if (lRes == ERROR_SUCCESS){
  655. DWORD dwType;
  656. WCHAR pData[MAX_PATH];
  657. DWORD dwSize=sizeof(pData);
  658. lRes = RegQueryValueExW(hKey,
  659. NULL, // default
  660. NULL,
  661. &dwType,
  662. (BYTE *)pData,
  663. &dwSize);
  664. if (lRes == ERROR_SUCCESS) {
  665. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  666. dprintf(" IID_%s\n",pDataA);
  667. }
  668. RegCloseKey(hKey);
  669. } else {
  670. if (IsEqualGUID(CurrUUID,IID_IMarshal)){
  671. dprintf(" IID_IMarshal\n");
  672. } else if (IsEqualGUID(CurrUUID,IID_IStdIdentity)) {
  673. dprintf(" IID_IStdIdentity\n");
  674. } else if (IsEqualGUID(CurrUUID,IID_ICallFactory)) {
  675. dprintf(" IID_ICallFactory\n");
  676. } else {
  677. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  678. dprintf(" %s\n",pDataA);
  679. }
  680. }
  681. }
  682. class OXIDEntry;
  683. class CCtxComChnl;
  684. class IRCEntry;
  685. typedef GUID IPID;
  686. typedef struct tagIPIDEntry
  687. {
  688. struct tagIPIDEntry *pNextIPID; // next IPIDEntry for same object
  689. // WARNING: next 6 fields must remain in their respective locations
  690. // and in the same format as the IPIDTmp structure above.
  691. DWORD dwFlags; // flags (see IPIDFLAGS)
  692. ULONG cStrongRefs; // strong reference count
  693. ULONG cWeakRefs; // weak reference count
  694. ULONG cPrivateRefs; // private reference count
  695. void *pv; // real interface pointer
  696. IUnknown *pStub; // proxy or stub pointer
  697. OXIDEntry *pOXIDEntry; // ptr to OXIDEntry in OXID Table
  698. // WARNING: previous 7 fields must remain in their respective locations
  699. // and in the same format as the IPIDTmp structure above.
  700. IPID ipid; // interface pointer identifier
  701. IID iid; // interface iid
  702. CCtxComChnl *pChnl; // channel pointer
  703. IRCEntry *pIRCEntry; // reference cache line
  704. struct tagIPIDEntry *pOIDFLink; // In use OID list
  705. struct tagIPIDEntry *pOIDBLink;
  706. } IPIDEntry;
  707. DECLARE_API( ipidl )
  708. {
  709. INIT_API();
  710. IPIDEntry IpId;
  711. ULONG_PTR Addr = GetExpression(args);
  712. if (Addr)
  713. {
  714. DWORD nCount=0;
  715. while (Addr &&
  716. ReadMemory(Addr,&IpId,sizeof(IpId),NULL))
  717. {
  718. dprintf(" -- %x\n",nCount);
  719. dprintf(" pNextIPID %p\n",IpId.pNextIPID);
  720. dprintf(" dwFlags %08x\n",IpId.dwFlags);
  721. dprintf(" cStrongRefs %08x\n",IpId.cStrongRefs);
  722. dprintf(" cWeakRefs %08x\n",IpId.cWeakRefs);
  723. dprintf(" cPrivateRefs %08x\n",IpId.cPrivateRefs);
  724. dprintf(" pv %p\n",IpId.pv);
  725. dprintf(" pStub %p\n",IpId.pStub);
  726. dprintf(" pOXIDEntry %p\n",IpId.pOXIDEntry);
  727. PrintIID(IpId.ipid);
  728. PrintIID(IpId.iid);
  729. dprintf(" pChnl %p\n",IpId.pChnl);
  730. dprintf(" pIRCEntry %p\n",IpId.pIRCEntry);
  731. dprintf(" pOIDFLink %p\n",IpId.pOIDFLink);
  732. dprintf(" pOIDBLink %p\n",IpId.pOIDBLink);
  733. Addr = (ULONG_PTR)IpId.pNextIPID;
  734. nCount++;
  735. if (CheckControlC())
  736. break;
  737. };
  738. }
  739. else
  740. {
  741. dprintf(" unable to resolve %s\n",args);
  742. }
  743. }
  744. void PrintCLSID(GUID & CurrUUID){
  745. WCHAR pszClsID[40];
  746. StringFromGUID2(CurrUUID,pszClsID,40);
  747. // look-up known
  748. DWORD i;
  749. for (i=0;i<g_nClsids;i++){
  750. if(IsEqualGUID(CurrUUID,*g_ArrayCLSID[i].pClsid)){
  751. dprintf(" CLSID : %s\n",g_ArrayCLSID[i].pStrClsid);
  752. break;
  753. }
  754. }
  755. WCHAR pszFullPath[MAX_PATH];
  756. lstrcpyW(pszFullPath,L"CLSID\\");
  757. lstrcatW(pszFullPath,pszClsID);
  758. char pDataA[MAX_PATH];
  759. HKEY hKey;
  760. LONG lRes;
  761. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  762. pszFullPath,
  763. 0,
  764. KEY_READ,
  765. &hKey);
  766. if (lRes == ERROR_SUCCESS){
  767. DWORD dwType;
  768. WCHAR pData[MAX_PATH];
  769. DWORD dwSize=sizeof(pData);
  770. lRes = RegQueryValueExW(hKey,
  771. NULL, // default
  772. NULL,
  773. &dwType,
  774. (BYTE *)pData,
  775. &dwSize);
  776. if (lRes == ERROR_SUCCESS) {
  777. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  778. dprintf(" ProgID %s\n",pDataA);
  779. };
  780. RegCloseKey(hKey);
  781. // no open InProcServer32
  782. WCHAR pszFullPathDll[MAX_PATH];
  783. lstrcpyW(pszFullPathDll,pszFullPath);
  784. lstrcatW(pszFullPathDll,L"\\InprocServer32");
  785. lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  786. pszFullPathDll,
  787. 0,
  788. KEY_READ,
  789. &hKey);
  790. if (lRes == ERROR_SUCCESS){
  791. dwSize = sizeof(pData);
  792. lRes = RegQueryValueExW(hKey,
  793. NULL, // default
  794. NULL,
  795. &dwType,
  796. (BYTE *)pData,
  797. &dwSize);
  798. if (lRes == ERROR_SUCCESS) {
  799. WideCharToMultiByte(CP_ACP,0,pData,-1,pDataA,sizeof(pDataA),NULL,NULL);
  800. dprintf(" Path: %s\n",pDataA);
  801. };
  802. RegCloseKey(hKey);
  803. }
  804. } else {
  805. WideCharToMultiByte(CP_ACP,0,pszClsID,-1,pDataA,sizeof(pDataA),NULL,NULL);
  806. dprintf("unable to open key %s\n",pDataA);
  807. }
  808. }
  809. class CTableElement;
  810. class CHashTable
  811. {
  812. private:
  813. DWORD _cBuckets;
  814. DWORD _cElements;
  815. CTableElement **_buckets;
  816. CTableElement *_last;
  817. };
  818. typedef int EnumEntryType;
  819. typedef void CSharedLock;
  820. typedef void CServerTable;
  821. typedef void CProcess;
  822. class CServerTableEntry{
  823. private:
  824. void * pvtable;
  825. DWORD _references;
  826. CServerTableEntry * _pnext;
  827. //DWORD padding;
  828. //CLSID _GUID;
  829. unsigned __int64 _id1;
  830. unsigned __int64 _id2;
  831. EnumEntryType _EntryType;
  832. CSharedLock * _pParentTableLock;
  833. CServerTable * _pParentTable;
  834. BOOL _bComPlusProcess;
  835. LONG _lThreadToken;
  836. DWORD _dwProcessId;
  837. HANDLE _hProcess;
  838. CProcess* _pProcess;
  839. void * _pvRunAsHandle;
  840. BOOL _bSuspendedClsid;
  841. BOOL _bSuspendedApplication;
  842. // the _bRetired flag exists per-running process/application
  843. //CServerList _ServerList;
  844. //CSharedLock _ServerLock;
  845. };
  846. /*
  847. 0:002> dt rpcss!CServerTableEntry 6fb`ffcdb170
  848. +0x000 __VFN_table : 0x00000000`702a2b60
  849. +0x008 _references :
  850. +0x010 _pnext : (null)
  851. +0x018 _id : 0x11d0f196`61738644
  852. +0x020 _id2 : 0xc119d94f`c0005399
  853. +0x028 _EntryType : 0 ( ENTRY_TYPE_CLASS )
  854. +0x030 _pParentTableLock : 0x000006fb`ffc9d590
  855. +0x038 _pParentTable : 0x000006fb`ffc9d700
  856. +0x040 _bComPlusProcess : 0
  857. +0x044 _lThreadToken : 0
  858. +0x048 _dwProcessId : 0
  859. +0x050 _hProcess : (null)
  860. +0x058 _pProcess : (null)
  861. +0x060 _pvRunAsHandle : (null)
  862. +0x068 _bSuspendedClsid : 0
  863. +0x06c _bSuspendedApplication : 0
  864. +0x070 _ServerList : CServerList
  865. +0x080 _ServerLock : CSharedLock
  866. */
  867. DECLARE_API( rot )
  868. {
  869. INIT_API();
  870. CHashTable * pChashTable;
  871. ULONG_PTR Addr = GetExpression("rpcss!gpClassTable");
  872. if (Addr)
  873. {
  874. CHashTable * pChashTable;
  875. ReadMemory(Addr,&pChashTable,sizeof(CHashTable *),0);
  876. CHashTable MyHashTable;
  877. if (pChashTable)
  878. {
  879. dprintf("CServerTable %p\n",pChashTable);
  880. ReadMemory((ULONG_PTR)pChashTable,&MyHashTable,sizeof(CHashTable),NULL);
  881. CTableElement ** StackArray = (CTableElement **)_alloca(MyHashTable._cBuckets * sizeof(CTableElement *));
  882. ReadMemory((ULONG_PTR)MyHashTable._buckets,StackArray,MyHashTable._cBuckets * sizeof(CTableElement *),NULL);
  883. DWORD i;
  884. for (i=0;i<MyHashTable._cBuckets;i++)
  885. {
  886. CServerTableEntry * pEntry = (CServerTableEntry *)StackArray[i];
  887. while (pEntry){
  888. CheckControlC();
  889. CServerTableEntry ClassEntry;
  890. ReadMemory((ULONG_PTR)pEntry,&ClassEntry,sizeof(ClassEntry),NULL);
  891. dprintf("CServerTableEntry %p\n",pEntry);
  892. PrintCLSID(*(GUID *)(&(ClassEntry._id1)));
  893. pEntry = ClassEntry._pnext;
  894. }
  895. }
  896. }
  897. }
  898. else
  899. {
  900. dprintf("unable to resolve rpcss!gpClassTable");
  901. }
  902. }
  903. /*
  904. struct RTL_CRITICAL_SECTION_DEBUG {
  905. USHORT Type; //: 0x0
  906. USHORT CreatorBackTraceIndex; //: 0x0
  907. CRITICAL_SECTION * CriticalSection; //: 0x77fcae40
  908. LIST_ENTRY ProcessLocksList; //:
  909. DWORD EntryCount; //: 0x0
  910. DWORD ContentionCount; //: 0x0
  911. DWORD Spare[2]; //:0x0
  912. };
  913. */
  914. //
  915. //
  916. // CallBack for enumeration of critical section
  917. //
  918. //
  919. /////////////////////////////////////////////////////////////
  920. DWORD
  921. EnumListCritSec(VOID * pStructure_OOP,
  922. VOID * pLocalStructure)
  923. {
  924. RTL_CRITICAL_SECTION_DEBUG * pDebugInfo = (RTL_CRITICAL_SECTION_DEBUG *)pLocalStructure;
  925. dprintf(" CS %p DI %p \n",pDebugInfo->CriticalSection,pStructure_OOP);
  926. RTL_CRITICAL_SECTION CritSec;
  927. if (ReadMemory((ULONG_PTR)pDebugInfo->CriticalSection,&CritSec,sizeof(RTL_CRITICAL_SECTION),NULL))
  928. {
  929. dprintf(" - %p %x %x %x\n",
  930. CritSec.DebugInfo,
  931. CritSec.LockCount,
  932. CritSec.RecursionCount,
  933. CritSec.OwningThread);
  934. }
  935. else
  936. {
  937. dprintf("RM %p\n",pDebugInfo->CriticalSection);
  938. }
  939. return 0;
  940. }
  941. #define ARRAY_TO_GO_BACK 16
  942. DWORD
  943. EnumListCritSec2(VOID * pStructure_OOP,
  944. VOID * pLocalStructure)
  945. {
  946. RTL_CRITICAL_SECTION_DEBUG * pDebugInfo = (RTL_CRITICAL_SECTION_DEBUG *)pLocalStructure;
  947. dprintf(" CS %p DI %p \n",pDebugInfo->CriticalSection,pStructure_OOP);
  948. struct _TmpStr {
  949. ULONG_PTR Array[ARRAY_TO_GO_BACK];
  950. RTL_CRITICAL_SECTION CritSec;
  951. } TmpStr;
  952. if (ReadMemory(((ULONG_PTR)pDebugInfo->CriticalSection) - FIELD_OFFSET(_TmpStr,CritSec),&TmpStr,sizeof(_TmpStr),NULL))
  953. {
  954. dprintf(" - %p %x %x %x\n",
  955. TmpStr.CritSec.DebugInfo,
  956. TmpStr.CritSec.LockCount,
  957. TmpStr.CritSec.RecursionCount,
  958. TmpStr.CritSec.OwningThread);
  959. for (int i=(ARRAY_TO_GO_BACK-1);i>=0;i--)
  960. {
  961. if (GetVTable((MEMORY_ADDRESS)TmpStr.Array[i]))
  962. {
  963. break; // don't be too verbose
  964. }
  965. }
  966. }
  967. else
  968. {
  969. dprintf("RM around %p\n",pDebugInfo->CriticalSection);
  970. }
  971. return 0;
  972. }
  973. DECLARE_API( cs )
  974. {
  975. INIT_API();
  976. ULONG_PTR Addr = GetExpression("ntdll!RtlCriticalSectionList");
  977. ULONG_PTR bGoAndFindVTable = TRUE;
  978. if (!Addr)
  979. {
  980. Addr = GetExpression(args);
  981. }
  982. else
  983. {
  984. bGoAndFindVTable = GetExpression(args);
  985. }
  986. if (Addr)
  987. {
  988. if (bGoAndFindVTable)
  989. {
  990. EnumLinkedListCB((LIST_ENTRY *)Addr,
  991. sizeof(RTL_CRITICAL_SECTION_DEBUG),
  992. FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList),
  993. EnumListCritSec2);
  994. }
  995. else
  996. {
  997. EnumLinkedListCB((LIST_ENTRY *)Addr,
  998. sizeof(RTL_CRITICAL_SECTION_DEBUG),
  999. FIELD_OFFSET(RTL_CRITICAL_SECTION_DEBUG,ProcessLocksList),
  1000. EnumListCritSec);
  1001. }
  1002. }
  1003. else
  1004. {
  1005. dprintf("unable to resolve ntdll!RtlCriticalSectionList\n");
  1006. }
  1007. }
  1008. BOOL
  1009. GetVTable(MEMORY_ADDRESS pThis_OOP){
  1010. MEMORY_ADDRESS pVTable;
  1011. ReadMemory(pThis_OOP,&pVTable,sizeof(pVTable),0);
  1012. BYTE pString[256];
  1013. pString[0]=0;
  1014. #ifdef KDEXT_64BIT
  1015. ULONG64 Displ;
  1016. #else
  1017. ULONG Displ;
  1018. #endif
  1019. GetSymbol(pVTable,(PCHAR)pString,&Displ);
  1020. if (lstrlenA((CHAR *)pString))
  1021. {
  1022. dprintf(" %s+%x\n",pString,Displ);
  1023. return TRUE;
  1024. }
  1025. else
  1026. {
  1027. return FALSE;
  1028. }
  1029. }
  1030. /*
  1031. kd> dt ntdll!RTL_CRITICAL_SECTION
  1032. +0x000 DebugInfo : Ptr64 _RTL_CRITICAL_SECTION_DEBUG
  1033. +0x008 LockCount : Int4B
  1034. +0x00c RecursionCount : Int4B
  1035. +0x010 OwningThread : Ptr64 Void
  1036. +0x018 LockSemaphore : Ptr64 Void
  1037. +0x020 SpinCount : Uint8B
  1038. kd> dt ntdll!_RTL_CRITICAL_SECTION_DEBUG
  1039. +0x000 Type : Uint2B
  1040. +0x002 CreatorBackTraceIndex : Uint2B
  1041. +0x008 CriticalSection : Ptr64 _RTL_CRITICAL_SECTION
  1042. +0x010 ProcessLocksList : _LIST_ENTRY
  1043. +0x020 EntryCount : Uint4B
  1044. +0x024 ContentionCount : Uint4B
  1045. +0x028 Spare : [2] Uint4B
  1046. kd>
  1047. */
  1048. #ifdef KDEXT_64BIT
  1049. struct _LIST_ENTRY_64
  1050. {
  1051. ULONG64 Flink;
  1052. ULONG64 Blink;
  1053. };
  1054. struct _RTL_CRITICAL_SECTION_64
  1055. {
  1056. ULONG64 DebugInfo;
  1057. DWORD LockCount;
  1058. DWORD RecursionCount;
  1059. ULONG64 OwningThread;
  1060. ULONG64 LockSemaphore;
  1061. ULONG64 SpinCount;
  1062. };
  1063. struct _RTL_CRITICAL_SECTION_DEBUG_64
  1064. {
  1065. WORD Type;
  1066. WORD CreatorBackTraceIndex;
  1067. ULONG64 CriticalSection;
  1068. _LIST_ENTRY_64 ProcessLocksList;
  1069. DWORD EntryCount;
  1070. DWORD ContentionCount;
  1071. DWORD Spare;
  1072. };
  1073. #endif /*KDEXT_64BIT*/
  1074. DECLARE_API(cs64)
  1075. {
  1076. INIT_API();
  1077. #ifdef KDEXT_64BIT
  1078. _RTL_CRITICAL_SECTION_DEBUG_64 DebugInfo;
  1079. _RTL_CRITICAL_SECTION_64 CritSec;
  1080. _LIST_ENTRY_64 ListEntry;
  1081. ULONG64 MemAddr = GetExpression(args);
  1082. if (MemAddr)
  1083. {
  1084. ULONG64 AddrHead = MemAddr;
  1085. if (ReadMemory(MemAddr,&ListEntry,sizeof(ListEntry),NULL))
  1086. {
  1087. DebugInfo.ProcessLocksList.Flink = ListEntry.Flink;
  1088. while (DebugInfo.ProcessLocksList.Flink != AddrHead)
  1089. {
  1090. if (CheckControlC())
  1091. break;
  1092. MemAddr = DebugInfo.ProcessLocksList.Flink - FIELD_OFFSET(_RTL_CRITICAL_SECTION_DEBUG_64,ProcessLocksList);
  1093. if (ReadMemory((MEMORY_ADDRESS)MemAddr,&DebugInfo,sizeof(DebugInfo),NULL))
  1094. {
  1095. dprintf(" C %p D %p\n",DebugInfo.CriticalSection,MemAddr);
  1096. if (ReadMemory((MEMORY_ADDRESS)DebugInfo.CriticalSection,&CritSec,sizeof(CritSec),NULL))
  1097. {
  1098. dprintf(" - CS %p %x %x %p\n",
  1099. CritSec.DebugInfo,
  1100. CritSec.LockCount,
  1101. CritSec.RecursionCount,
  1102. CritSec.OwningThread);
  1103. }
  1104. else
  1105. {
  1106. dprintf("RM %p\n",DebugInfo.CriticalSection);
  1107. }
  1108. }
  1109. else
  1110. {
  1111. break;
  1112. }
  1113. }
  1114. }
  1115. else
  1116. {
  1117. dprintf("RM %p\n",MemAddr);
  1118. }
  1119. }
  1120. else
  1121. {
  1122. dprintf("unable to resolve %s\n",args);
  1123. }
  1124. #endif /*KDEXT_64BIT*/
  1125. }