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.

1817 lines
57 KiB

  1. #include <wmiexts.h>
  2. #include <utilfun.h>
  3. #include <malloc.h>
  4. #include <Sddl.h>
  5. void GetTeb(HANDLE hThread,TEB ** ppTeb)
  6. {
  7. NTSTATUS Status;
  8. ULONG Long;
  9. THREAD_BASIC_INFORMATION TBasicInfo;
  10. Status = NtQueryInformationThread(hThread,
  11. ThreadBasicInformation,
  12. &TBasicInfo,
  13. sizeof(TBasicInfo),
  14. &Long);
  15. if ( Status == 0 )
  16. {
  17. //dprintf(" %p %x.%x\n",TBasicInfo.TebBaseAddress,TBasicInfo.ClientId.UniqueProcess,TBasicInfo.ClientId.UniqueThread);
  18. if (ppTeb)
  19. {
  20. *ppTeb = TBasicInfo.TebBaseAddress;
  21. }
  22. }
  23. else
  24. {
  25. dprintf(" NtQueryInformationThread %08x\n",Status);
  26. }
  27. }
  28. void GetCid(HANDLE hThread,CLIENT_ID * pCid)
  29. {
  30. NTSTATUS Status;
  31. ULONG Long;
  32. THREAD_BASIC_INFORMATION TBasicInfo;
  33. Status = NtQueryInformationThread(hThread,
  34. ThreadBasicInformation,
  35. &TBasicInfo,
  36. sizeof(TBasicInfo),
  37. &Long);
  38. if ( Status == 0 )
  39. {
  40. //dprintf(" %p %x.%x\n",TBasicInfo.TebBaseAddress,TBasicInfo.ClientId.UniqueProcess,TBasicInfo.ClientId.UniqueThread);
  41. if (pCid)
  42. {
  43. memcpy(pCid,&TBasicInfo.ClientId, sizeof(CLIENT_ID));
  44. }
  45. }
  46. else
  47. {
  48. dprintf(" NtQueryInformationThread %08x\n",Status);
  49. }
  50. }
  51. void GetPeb(HANDLE hSourceProcess, PEB ** ppPeb, ULONG_PTR * pId)
  52. {
  53. NTSTATUS Status;
  54. ULONG Long;
  55. PROCESS_BASIC_INFORMATION PBasicInfo;
  56. Status = NtQueryInformationProcess(hSourceProcess,
  57. ProcessBasicInformation,
  58. &PBasicInfo,
  59. sizeof(PBasicInfo),
  60. &Long);
  61. if ( Status == 0 )
  62. {
  63. if (ppPeb)
  64. {
  65. *ppPeb = PBasicInfo.PebBaseAddress;
  66. }
  67. if (pId)
  68. {
  69. *pId = PBasicInfo.UniqueProcessId;
  70. }
  71. }
  72. else
  73. {
  74. dprintf(" NTSTATUS %08x\n",Status);
  75. }
  76. }
  77. //
  78. void PrintHandleBackTrace(HANDLE hHandle,WCHAR * pFileName)
  79. {
  80. WCHAR pPath[MAX_PATH+1];
  81. GetEnvironmentVariableW(L"windir",pPath,MAX_PATH);
  82. lstrcatW(pPath,L"\\system32\\");
  83. lstrcatW(pPath,pFileName);
  84. HANDLE hFile = NULL;
  85. hFile = CreateFileW(pPath,
  86. GENERIC_READ,
  87. FILE_SHARE_READ|FILE_SHARE_WRITE,
  88. NULL,
  89. OPEN_EXISTING,
  90. 0,NULL);
  91. if (INVALID_HANDLE_VALUE != hFile)
  92. {
  93. DWORD dwSize = GetFileSize(hFile,NULL);
  94. HANDLE hFileMap = CreateFileMapping(hFile,
  95. NULL,
  96. PAGE_READONLY,
  97. 0,
  98. dwSize,
  99. NULL);
  100. if (hFileMap)
  101. {
  102. HANDLE * pHandle = (HANDLE *)MapViewOfFile(hFileMap,
  103. FILE_MAP_READ,
  104. 0,0,0);
  105. if(pHandle)
  106. {
  107. //dprintf("hEvent %p dwSize %x\n",hEvent,dwSize);
  108. DWORD SizeRecord = 8*sizeof(HANDLE);
  109. DWORD nRecord = dwSize/SizeRecord;
  110. HANDLE * pThisHandle = NULL;
  111. DWORD i;
  112. if (hHandle)
  113. {
  114. for(i=0;i<nRecord;i++)
  115. {
  116. if (hHandle == pHandle[(SizeRecord/sizeof(HANDLE))*(nRecord-1-i)])
  117. {
  118. pThisHandle = &pHandle[(SizeRecord/sizeof(HANDLE))*(nRecord-1-i)];
  119. break;
  120. }
  121. else
  122. {
  123. //dprintf(" %d %p\n",nRecord-1-i,pHandle[(SizeRecord/sizeof(HANDLE))*(nRecord-1-i)]);
  124. }
  125. }
  126. if(pThisHandle)
  127. {
  128. dprintf(" found rec %x handle %p\n",nRecord-1-i,*pThisHandle);
  129. PrintStackTrace((ULONG_PTR)pThisHandle+sizeof(HANDLE),7,FALSE);
  130. }
  131. else
  132. {
  133. dprintf("handle %x not found\n",hHandle);
  134. }
  135. }
  136. else // print all of them
  137. {
  138. dprintf("all records\n");
  139. for(i=0;i<nRecord;i++)
  140. {
  141. pThisHandle = &pHandle[(SizeRecord/sizeof(HANDLE))*(nRecord-1-i)];
  142. dprintf(" ------ %p\n",*pThisHandle);
  143. PrintStackTrace((ULONG_PTR)pThisHandle+sizeof(HANDLE),7,FALSE);
  144. if (CheckControlC())
  145. break;
  146. }
  147. }
  148. UnmapViewOfFile(pHandle);
  149. }
  150. else
  151. {
  152. dprintf("MapViewOfFile %d\n",GetLastError());
  153. }
  154. CloseHandle(hFileMap);
  155. }
  156. else
  157. {
  158. dprintf("CreateFileMapping %d\n",GetLastError());
  159. };
  160. CloseHandle(hFile);
  161. }
  162. else
  163. {
  164. dprintf("CreateFile %S %d\n",pPath,GetLastError());
  165. }
  166. }
  167. //
  168. DECLARE_API( refcnt )
  169. {
  170. INIT_API();
  171. PrintHandleBackTrace(NULL,L"refcount.dat");
  172. }
  173. //
  174. DECLARE_API( evtst )
  175. {
  176. INIT_API();
  177. MEMORY_ADDRESS Addr = GetExpression(args);
  178. HANDLE hEvent = (HANDLE)Addr;
  179. if (hEvent)
  180. {
  181. PrintHandleBackTrace(hEvent,L"events.dat");
  182. }
  183. }
  184. #define INCREMENT_ALLOC (4*1024)
  185. char * g_HandleType[] =
  186. {
  187. "",
  188. "",
  189. "",
  190. "",
  191. "Token", // 4
  192. "Process", // 5
  193. "Thread", //6
  194. "",
  195. "",
  196. "Event", // 9
  197. "",
  198. "Mutant", // 11
  199. "",
  200. "Semaphore", // 13
  201. "",
  202. "", // 15
  203. "",
  204. "",
  205. "",
  206. "",
  207. "Key", // 20
  208. "Port", //21
  209. "WaitablePort", // 22
  210. "",
  211. "",
  212. "",
  213. "",
  214. "",
  215. "File", // 28
  216. "WmiGuid", // 29
  217. "",
  218. "",
  219. "",
  220. "",
  221. "",
  222. "",
  223. ""
  224. };
  225. DECLARE_API( tokens )
  226. {
  227. INIT_API();
  228. if (g_KD)
  229. {
  230. dprintf("user-mode support only\n");
  231. return;
  232. }
  233. NTSTATUS Status;
  234. SYSTEM_HANDLE_INFORMATION * pSysHandleInfo = NULL;
  235. DWORD dwSize = INCREMENT_ALLOC;
  236. DWORD nReturned;
  237. ULONG_PTR lProcId;
  238. GetPeb(hCurrentProcess,NULL,&lProcId);
  239. USHORT ProcId = (USHORT)lProcId;
  240. alloc_again:
  241. pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION *)HeapAlloc(GetProcessHeap(),0,dwSize);
  242. if (pSysHandleInfo)
  243. {
  244. Status = NtQuerySystemInformation(SystemHandleInformation,
  245. pSysHandleInfo,
  246. dwSize,
  247. &nReturned);
  248. }
  249. else
  250. {
  251. goto leave;
  252. }
  253. if (STATUS_INFO_LENGTH_MISMATCH == Status)
  254. {
  255. HeapFree(GetProcessHeap(),0,pSysHandleInfo);
  256. dwSize += INCREMENT_ALLOC;
  257. goto alloc_again;
  258. }
  259. else if (0 == Status)
  260. {
  261. // we have all the handles
  262. // SYSTEM_HANDLE_TABLE_ENTRY_INFO
  263. for (DWORD i=0; i < pSysHandleInfo->NumberOfHandles; i++)
  264. {
  265. if (ProcId == pSysHandleInfo->Handles[i].UniqueProcessId)
  266. {
  267. //dprintf("handle: %x type %x\n",
  268. // pSysHandleInfo->Handles[i].HandleValue,
  269. // pSysHandleInfo->Handles[i].ObjectTypeIndex);
  270. if (4 == pSysHandleInfo->Handles[i].ObjectTypeIndex)
  271. {
  272. HANDLE hToken;
  273. if (DuplicateHandle(hCurrentProcess,
  274. (HANDLE)pSysHandleInfo->Handles[i].HandleValue,
  275. GetCurrentProcess(),
  276. &hToken,
  277. TOKEN_QUERY,FALSE,0)) //TOKEN_QUERY
  278. {
  279. dprintf("Token: %x\n",pSysHandleInfo->Handles[i].HandleValue);
  280. struct Info : public _TOKEN_USER
  281. {
  282. BYTE m_[SECURITY_MAX_SID_SIZE];
  283. } Token_User_;
  284. DWORD dwLen = sizeof(Token_User_);
  285. if (GetTokenInformation(hToken,
  286. TokenUser,
  287. &Token_User_,
  288. dwLen,
  289. &dwLen))
  290. {
  291. LPTSTR pSidString;
  292. if (ConvertSidToStringSid(Token_User_.User.Sid,&pSidString))
  293. {
  294. dprintf(" Sid : %s\n",pSidString);
  295. LocalFree(pSidString);
  296. }
  297. }
  298. else
  299. {
  300. dprintf(" Sid : err %d\n",GetLastError());
  301. }
  302. TOKEN_TYPE TokenType_;
  303. dwLen = sizeof(TokenType_);
  304. if (GetTokenInformation(hToken,
  305. TokenType,
  306. &TokenType_,
  307. dwLen,
  308. &dwLen))
  309. {
  310. dprintf(" Type : %d\n",TokenType_);
  311. }
  312. else
  313. {
  314. dprintf(" Type : err %d\n",GetLastError());
  315. }
  316. SECURITY_IMPERSONATION_LEVEL ImpLevel;
  317. dwLen = sizeof(ImpLevel);
  318. if (GetTokenInformation(hToken,
  319. TokenImpersonationLevel,
  320. &ImpLevel,
  321. dwLen,
  322. &dwLen))
  323. {
  324. dprintf(" Level: %d\n",ImpLevel);
  325. }
  326. else
  327. {
  328. dprintf(" Level: <UNDEFINED>\n",GetLastError());
  329. }
  330. CloseHandle(hToken);
  331. }
  332. else
  333. {
  334. dprintf("DuplicateHandle %x err %d\n",pSysHandleInfo->Handles[i].HandleValue,GetLastError());
  335. }
  336. }
  337. }
  338. if (CheckControlC())
  339. break;
  340. }
  341. }
  342. else
  343. {
  344. dprintf("");
  345. }
  346. leave:
  347. if (pSysHandleInfo)
  348. {
  349. HeapFree(GetProcessHeap(),0,pSysHandleInfo);
  350. }
  351. return;
  352. }
  353. //
  354. //
  355. // Invoke a function in the remote process
  356. //
  357. //////////////////////////////////////////
  358. DECLARE_API( inv )
  359. {
  360. INIT_API();
  361. int Len = strlen(args);
  362. CHAR * pArgs = (CHAR *)_alloca((Len+1));
  363. lstrcpy(pArgs,(CHAR *)args);
  364. MEMORY_ADDRESS pFunction = 0;
  365. MEMORY_ADDRESS pArgument = 0;
  366. while (isspace(*pArgs))
  367. {
  368. pArgs++;
  369. }
  370. CHAR * pSaved = pArgs;
  371. while(!isspace(*pArgs)) pArgs++;
  372. // terminate string, if possible
  373. if (isspace(*pArgs))
  374. {
  375. *pArgs = 0;
  376. pArgs++;
  377. }
  378. else
  379. {
  380. pArgs = NULL;
  381. }
  382. pFunction = GetExpression(pSaved);
  383. if (pArgs)
  384. {
  385. pArgument = GetExpression(pArgs);
  386. }
  387. dprintf("invoking %s(%p) @ %p\n",pSaved,pArgument,pFunction);
  388. DWORD dwID;
  389. HANDLE hThread = CreateRemoteThread(hCurrentProcess,
  390. NULL,
  391. 0,
  392. (LPTHREAD_START_ROUTINE )pFunction,
  393. (LPVOID)pArgument,
  394. 0,
  395. &dwID);
  396. if (hThread)
  397. {
  398. CLIENT_ID Cid;
  399. GetCid(hThread,&Cid);
  400. DEBUG_EVENT de;
  401. BOOL bRet = FALSE;
  402. BOOL StatusRemoteThreadCreated = FALSE;
  403. wait_again:
  404. bRet = WaitForDebugEvent(&de,INFINITE);
  405. if (bRet)
  406. {
  407. switch(de.dwDebugEventCode)
  408. {
  409. case OUTPUT_DEBUG_STRING_EVENT:
  410. {
  411. OUTPUT_DEBUG_STRING_INFO * pDbgStr = &de.u.DebugString;
  412. WCHAR * pData = new WCHAR[pDbgStr->nDebugStringLength+1];
  413. if(pDbgStr->fUnicode)
  414. {
  415. ReadMemory((ULONG_PTR)pDbgStr->lpDebugStringData,pData,pDbgStr->nDebugStringLength*sizeof(WCHAR),NULL);
  416. dprintf("%S",pData);
  417. }
  418. else
  419. {
  420. ReadMemory((ULONG_PTR)pDbgStr->lpDebugStringData,pData,pDbgStr->nDebugStringLength*sizeof(CHAR),NULL);
  421. dprintf("%s",pData);
  422. }
  423. delete [] pData;
  424. }
  425. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_CONTINUE);
  426. if (bRet)
  427. {
  428. goto wait_again;
  429. }
  430. break;
  431. case CREATE_THREAD_DEBUG_EVENT:
  432. if ((DWORD)((DWORD_PTR)Cid.UniqueProcess) == de.dwProcessId &&
  433. (DWORD)((DWORD_PTR)Cid.UniqueThread) == de.dwThreadId)
  434. {
  435. if (!StatusRemoteThreadCreated)
  436. {
  437. StatusRemoteThreadCreated = TRUE;
  438. }
  439. }
  440. else
  441. {
  442. dprintf("%x.%x != %x.%x\n",
  443. de.dwProcessId,de.dwThreadId,
  444. (DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread));
  445. }
  446. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_CONTINUE);
  447. if (bRet)
  448. {
  449. goto wait_again;
  450. };
  451. break;
  452. case CREATE_PROCESS_DEBUG_EVENT:
  453. case EXIT_PROCESS_DEBUG_EVENT:
  454. //dprintf("DebugEventCode %08x for %x.%x\n",de.dwDebugEventCode,de.dwProcessId,de.dwThreadId);
  455. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_CONTINUE);
  456. if (bRet)
  457. {
  458. goto wait_again;
  459. };
  460. break;
  461. case EXCEPTION_DEBUG_EVENT:
  462. {
  463. EXCEPTION_DEBUG_INFO * pExcDebug = &de.u.Exception;
  464. dprintf("%08x %08x FIRST? %d\n",
  465. pExcDebug->ExceptionRecord.ExceptionCode,
  466. pExcDebug->ExceptionRecord.ExceptionAddress,
  467. pExcDebug->dwFirstChance);
  468. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_TERMINATE_THREAD);
  469. if (bRet)
  470. {
  471. goto wait_again;
  472. }
  473. }
  474. break;
  475. case EXIT_THREAD_DEBUG_EVENT:
  476. if ((DWORD)((DWORD_PTR)Cid.UniqueProcess) == de.dwProcessId &&
  477. (DWORD)((DWORD_PTR)Cid.UniqueThread) == de.dwThreadId)
  478. {
  479. if (StatusRemoteThreadCreated)
  480. {
  481. // ok
  482. }
  483. else
  484. {
  485. dprintf("EXIT_THREAD_DEBUG_EVENT %x.%x =?= %x.%x\n",
  486. de.dwProcessId,de.dwThreadId,(DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread));
  487. }
  488. //
  489. // we are done
  490. //
  491. }
  492. else
  493. {
  494. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_CONTINUE);
  495. if (bRet)
  496. {
  497. goto wait_again;
  498. }
  499. }
  500. break;
  501. case LOAD_DLL_DEBUG_EVENT:
  502. case UNLOAD_DLL_DEBUG_EVENT:
  503. //dprintf("DebugEventCode %08x for %x.%x CONTINUE\n",de.dwDebugEventCode,de.dwProcessId,de.dwThreadId);
  504. bRet = ContinueDebugEvent((DWORD)((DWORD_PTR)Cid.UniqueProcess),(DWORD)((DWORD_PTR)Cid.UniqueThread),DBG_CONTINUE);
  505. if (bRet)
  506. {
  507. goto wait_again;
  508. }
  509. break;
  510. default:
  511. dprintf("DebugEventCode %08x\n ?????",de.dwDebugEventCode);
  512. //ContinueDebugEvent((DWORD)Cid.UniqueProcess,(DWORD)Cid.UniqueThread,DBG_TERMINATE_THREAD);
  513. }
  514. }
  515. else
  516. {
  517. dprintf("WaitForDebugEvent err: %d\n",GetLastError());
  518. }
  519. CloseHandle(hThread);
  520. }
  521. else
  522. {
  523. dprintf("CreateRemoteThread %d\n",GetLastError());
  524. }
  525. }
  526. //
  527. //
  528. //
  529. ////////////////////////////////////////////////////////////
  530. struct ContextParam {
  531. LIST_ENTRY * pHeadOutParam;
  532. ULONG Offset_Cid;
  533. ULONG Offset_Image;
  534. };
  535. struct PidResolution {
  536. LIST_ENTRY Entry;
  537. BYTE Image[20];
  538. DWORD Pid;
  539. };
  540. DWORD
  541. EnumListProcess(VOID * pStructure_OOP,
  542. VOID * pLocalStructure,
  543. VOID * Context)
  544. {
  545. //dprintf("%p %p %p\n",pStructure_OOP,pLocalStructure,Context);
  546. ContextParam * pContext = (ContextParam *)Context;
  547. PidResolution * pRes = (PidResolution *)HeapAlloc(GetProcessHeap(),0,sizeof(PidResolution));
  548. //dprintf("%p\n",pRes);
  549. if (pRes)
  550. {
  551. InsertTailList(pContext->pHeadOutParam,&pRes->Entry);
  552. memcpy(pRes->Image,(BYTE *)pLocalStructure+pContext->Offset_Image,16);
  553. pRes->Image[16] = 0;
  554. pRes->Pid = *(DWORD *)((BYTE *)pLocalStructure+pContext->Offset_Cid);
  555. }
  556. //dprintf("EPROCESS %p Cid: %x image %s\n",pStructure_OOP,pRes->Pid,pRes->Image);
  557. return 0;
  558. }
  559. DWORD GetProcList(LIST_ENTRY * pHeadOut)
  560. {
  561. //dprintf("GetProcList\n");
  562. MEMORY_ADDRESS pProcessEntry = GetExpression("nt!PsActiveProcessHead");
  563. ULONG Offset_Entry = 0;
  564. ULONG Offset_Cid = 0;
  565. ULONG Offset_Image = 0;
  566. if (!(0 == GetFieldOffset("nt!_EPROCESS","ActiveProcessLinks",&Offset_Entry) &&
  567. 0 == GetFieldOffset("nt!_EPROCESS","UniqueProcessId",&Offset_Cid) &&
  568. 0 == GetFieldOffset("nt!_EPROCESS","ImageFileName",&Offset_Image)))
  569. {
  570. dprintf("bad symbols\n");
  571. }
  572. if (pProcessEntry)
  573. {
  574. ContextParam Context_ = {pHeadOut,Offset_Cid,Offset_Image};
  575. EnumLinkedListCB((LIST_ENTRY *)pProcessEntry,
  576. Offset_Image + 16, // sizeof(EPROCESS)
  577. Offset_Entry, // FILED_OFFSET(ActiveProcessLinks)
  578. (pfnCallBack2)EnumListProcess,
  579. &Context_);
  580. }
  581. else
  582. {
  583. dprintf("unable to obtain %s\n","nt!PsActiveProcessHead");
  584. }
  585. return 0;
  586. }
  587. DWORD FreeProcList(LIST_ENTRY * HeadProcess)
  588. {
  589. while (!IsListEmpty(HeadProcess))
  590. {
  591. LIST_ENTRY * pEntry = HeadProcess->Flink;
  592. RemoveEntryList(pEntry);
  593. HeapFree(GetProcessHeap(),0,pEntry);
  594. }
  595. return 0;
  596. }
  597. PidResolution * FindProcList(LIST_ENTRY * HeadProcess,DWORD Cid)
  598. {
  599. for (LIST_ENTRY * pEntry = HeadProcess->Flink;pEntry != HeadProcess;pEntry = pEntry->Flink)
  600. {
  601. PidResolution * pRes = CONTAINING_RECORD(pEntry,PidResolution,Entry);
  602. if (Cid == pRes->Pid)
  603. return pRes;
  604. }
  605. return 0;
  606. }
  607. DECLARE_API( tcp_ports )
  608. {
  609. INIT_API();
  610. if (!g_KD)
  611. {
  612. dprintf("KD support only\n");
  613. return;
  614. }
  615. MEMORY_ADDRESS pTable = GetExpression("tcpip!AddrObjTable");
  616. MEMORY_ADDRESS pNumEntry = GetExpression("tcpip!AddrObjTableSize");
  617. ULONG Offset_next = 0;
  618. ULONG Offset_addr = 0;
  619. ULONG Offset_port = 0;
  620. ULONG Offset_owningpid = 0;
  621. ULONG Offset_proto = 0;
  622. if (!(0 == GetFieldOffset("tcpip!AddrObj","ao_next",&Offset_next) &&
  623. 0 == GetFieldOffset("tcpip!AddrObj","ao_port",&Offset_port) &&
  624. 0 == GetFieldOffset("tcpip!AddrObj","ao_owningpid",&Offset_owningpid) &&
  625. 0 == GetFieldOffset("tcpip!AddrObj","ao_addr",&Offset_addr) &&
  626. 0 == GetFieldOffset("tcpip!AddrObj","ao_prot",&Offset_proto) ))
  627. {
  628. dprintf("bad symbols\n");
  629. return;
  630. }
  631. LIST_ENTRY HeadProcess = {&HeadProcess,&HeadProcess};
  632. GetProcList(&HeadProcess);
  633. if (pTable)
  634. {
  635. ULONG_PTR TableAddr;
  636. if (ReadMemory(pTable,&TableAddr,sizeof(TableAddr),NULL))
  637. {
  638. DWORD NumEntry;
  639. if (ReadMemory(pNumEntry,&NumEntry,sizeof(NumEntry),NULL))
  640. {
  641. ULONG_PTR * pArray = (ULONG_PTR *)_alloca(NumEntry*sizeof(ULONG_PTR));
  642. if (ReadMemory(TableAddr,pArray,NumEntry*sizeof(ULONG_PTR),NULL))
  643. {
  644. BYTE * pStorage = (BYTE *)_alloca(Offset_owningpid + sizeof(DWORD));
  645. for(DWORD i=0;i<NumEntry;i++)
  646. {
  647. //dprintf(" - bucket %x\n",i);
  648. ULONG_PTR pAddObj_OOP = pArray[i];
  649. while (pAddObj_OOP)
  650. {
  651. //dprintf(" AddrObj %p\n",pAddObj_OOP);
  652. if (ReadMemory(pAddObj_OOP,pStorage,Offset_owningpid + sizeof(DWORD),NULL))
  653. {
  654. pAddObj_OOP = *(ULONG_PTR *)(pStorage+Offset_next);
  655. WORD Port = *(WORD *)(pStorage+Offset_port);
  656. DWORD Process = *(DWORD *)(pStorage+Offset_owningpid);
  657. BYTE Protocol = *(BYTE *)(pStorage+Offset_proto);
  658. PidResolution * pRes = FindProcList(&HeadProcess,Process);
  659. if (pRes)
  660. {
  661. dprintf(" Cid: %x image %s\n",pRes->Pid,pRes->Image);
  662. }
  663. BYTE AddrByte[4];
  664. memcpy(AddrByte,pStorage+Offset_addr,4);
  665. // ntohs
  666. WORD Port2 = ((Port & 0xFF) <<8);
  667. WORD Port3 = ((Port & 0xFF00) >> 8);
  668. Port = Port2 | Port3;
  669. dprintf(" addr: %d.%d.%d.%d port: %d proto: %x \n",
  670. AddrByte[0],
  671. AddrByte[1],
  672. AddrByte[2],
  673. AddrByte[3],Port,Protocol);
  674. }
  675. else
  676. {
  677. pAddObj_OOP = 0;
  678. dprintf("RM %p\n",pTable);
  679. }
  680. }
  681. }
  682. }
  683. else
  684. {
  685. dprintf("RM %p\n",pTable);
  686. }
  687. }
  688. else
  689. {
  690. dprintf("RM %p\n",pTable);
  691. }
  692. }
  693. else
  694. {
  695. dprintf("RM %p\n",pTable);
  696. }
  697. }
  698. else
  699. {
  700. dprintf("unable to get %s\n","tcpip!AddrObjTable");
  701. }
  702. FreeProcList(&HeadProcess);
  703. }
  704. //
  705. // prototype here
  706. //
  707. BOOL GetVTable(MEMORY_ADDRESS pThis_OOP);
  708. //
  709. //
  710. // Dumps the thread list with some info on OLE and RPC
  711. //
  712. //
  713. typedef enum tagOLETLSFLAGS
  714. {
  715. OLETLS_LOCALTID = 0x01, // This TID is in the current process.
  716. OLETLS_UUIDINITIALIZED = 0x02, // This Logical thread is init'd.
  717. OLETLS_INTHREADDETACH = 0x04, // This is in thread detach. Needed
  718. // due to NT's special thread detach
  719. // rules.
  720. OLETLS_CHANNELTHREADINITIALZED = 0x08,// This channel has been init'd
  721. OLETLS_WOWTHREAD = 0x10, // This thread is a 16-bit WOW thread.
  722. OLETLS_THREADUNINITIALIZING = 0x20, // This thread is in CoUninitialize.
  723. OLETLS_DISABLE_OLE1DDE = 0x40, // This thread can't use a DDE window.
  724. OLETLS_APARTMENTTHREADED = 0x80, // This is an STA apartment thread
  725. OLETLS_MULTITHREADED = 0x100, // This is an MTA apartment thread
  726. OLETLS_IMPERSONATING = 0x200, // This thread is impersonating
  727. OLETLS_DISABLE_EVENTLOGGER = 0x400, // Prevent recursion in event logger
  728. OLETLS_INNEUTRALAPT = 0x800, // This thread is in the NTA
  729. OLETLS_DISPATCHTHREAD = 0x1000, // This is a dispatch thread
  730. OLETLS_HOSTTHREAD = 0x2000, // This is a host thread
  731. OLETLS_ALLOWCOINIT = 0x4000, // This thread allows inits
  732. OLETLS_PENDINGUNINIT = 0x8000, // This thread has pending uninit
  733. OLETLS_FIRSTMTAINIT = 0x10000,// First thread to attempt an MTA init
  734. OLETLS_FIRSTNTAINIT = 0x20000,// First thread to attempt an NTA init
  735. OLETLS_APTINITIALIZING = 0x40000 // Apartment Object is initializing
  736. } OLETLSFLAGS;
  737. void PrintOleFlags(DWORD dwFlags)
  738. {
  739. if (dwFlags & OLETLS_LOCALTID) dprintf("OLETLS_LOCALTID ");
  740. if (dwFlags & OLETLS_WOWTHREAD) dprintf("OLETLS_WOWTHREAD ");
  741. if (dwFlags & OLETLS_THREADUNINITIALIZING ) dprintf("OLETLS_THREADUNINITIALIZING ");
  742. if (dwFlags & OLETLS_DISABLE_OLE1DDE) dprintf("OLETLS_DISABLE_OLE1DDE ");
  743. if (dwFlags & OLETLS_APARTMENTTHREADED) dprintf("OLETLS_APARTMENTTHREADED ");
  744. if (dwFlags & OLETLS_MULTITHREADED) dprintf("OLETLS_MULTITHREADED ");
  745. if (dwFlags & OLETLS_IMPERSONATING) dprintf("OLETLS_IMPERSONATING ");
  746. if (dwFlags & OLETLS_DISABLE_EVENTLOGGER) dprintf("OLETLS_DISABLE_EVENTLOGGER ");
  747. if (dwFlags & OLETLS_INNEUTRALAPT ) dprintf("OLETLS_INNEUTRALAPT ");
  748. if (dwFlags & OLETLS_DISPATCHTHREAD) dprintf("OLETLS_DISPATCHTHREAD ");
  749. if (dwFlags & OLETLS_HOSTTHREAD) dprintf("OLETLS_HOSTTHREAD ");
  750. if (dwFlags & OLETLS_ALLOWCOINIT ) dprintf("OLETLS_ALLOWCOINIT ");
  751. if (dwFlags & OLETLS_PENDINGUNINIT ) dprintf("OLETLS_PENDINGUNINIT ");
  752. if (dwFlags & OLETLS_FIRSTMTAINIT) dprintf("OLETLS_FIRSTMTAINIT ");
  753. if (dwFlags & OLETLS_FIRSTNTAINIT) dprintf("OLETLS_FIRSTNTAINIT ");
  754. if (dwFlags & OLETLS_APTINITIALIZING) dprintf("OLETLS_APTINITIALIZING ");
  755. }
  756. //
  757. //
  758. // rpcrt4!THREAD
  759. // ole32!SOleTlsData
  760. //
  761. void
  762. DumpRpcOle(ULONG_PTR pRpc,ULONG_PTR pOle)
  763. {
  764. if (pRpc)
  765. {
  766. ULONG OffsetContext;
  767. ULONG_PTR pRpcLRPC = 0;
  768. if (0 != GetFieldOffset("rpcrt4!THREAD","Context",&OffsetContext))
  769. {
  770. #ifdef _WIN64
  771. OffsetContext = 0x18;
  772. #else
  773. OffsetContext = 0x10;
  774. #endif
  775. }
  776. ReadMemory(pRpc+OffsetContext,&pRpcLRPC,sizeof(ULONG_PTR),0);
  777. ULONG_PTR pFirstVoid = 0;
  778. ReadMemory((ULONG_PTR)pRpcLRPC,&pFirstVoid,sizeof(ULONG_PTR),0);
  779. BYTE pString[256];
  780. pString[0]=0;
  781. #ifdef KDEXT_64BIT
  782. ULONG64 Displ;
  783. #else
  784. ULONG Displ;
  785. #endif
  786. if (pFirstVoid)
  787. GetSymbol(pFirstVoid,(PCHAR)pString,&Displ);
  788. if (lstrlenA((CHAR *)pString))
  789. {
  790. dprintf(" %s+%x %p\n",pString,Displ,pRpcLRPC);
  791. if (strstr((const char *)pString,"LRPC_SCALL"))
  792. {
  793. ULONG OffsetCID;
  794. if (0 != GetFieldOffset("rpcrt4!LRPC_SCALL","ClientId",&OffsetCID))
  795. {
  796. #ifdef _WIN64
  797. OffsetCID = 0x100;
  798. #else
  799. OffsetCID = 0xa0;
  800. #endif
  801. }
  802. CLIENT_ID CID;
  803. ReadMemory(pRpcLRPC+OffsetCID,&CID,sizeof(CLIENT_ID),NULL);
  804. dprintf(" - - - - called from: %x.%x\n",CID.UniqueProcess,CID.UniqueThread);
  805. }
  806. }
  807. else
  808. {
  809. dprintf(" rpcrt4!THREAD.Context %p\n",pRpcLRPC);
  810. }
  811. }
  812. if (pOle)
  813. {
  814. ULONG OffsetCallContext;
  815. ULONG_PTR pCallCtx = 0;
  816. if (0 != GetFieldOffset("ole32!SOleTlsData","pCallContext",&OffsetCallContext))
  817. {
  818. #ifdef _WIN64
  819. OffsetCallContext = 0x88;
  820. #else
  821. OffsetCallContext = 0x54;
  822. #endif
  823. }
  824. ULONG OffsetdwFlags;
  825. DWORD dwFlags;
  826. if (0 != GetFieldOffset("ole32!SOleTlsData","dwFlags",&OffsetdwFlags))
  827. {
  828. #ifdef _WIN64
  829. OffsetdwFlags = 0x14;
  830. #else
  831. OffsetdwFlags = 0xc;
  832. #endif
  833. }
  834. ReadMemory(pOle+OffsetCallContext,&pCallCtx,sizeof(ULONG_PTR),0);
  835. ReadMemory(pOle+OffsetdwFlags,&dwFlags,sizeof(DWORD),0);
  836. dprintf(" ole32!SOleTlsData::pCallContext %p\n",pCallCtx);
  837. if (pCallCtx)
  838. GetVTable(pCallCtx);
  839. dprintf(" ");
  840. PrintOleFlags(dwFlags);
  841. dprintf("\n");
  842. }
  843. }
  844. //
  845. //
  846. // call HeapFree(GetProcessHeap) on the OUT pointers
  847. //
  848. //////////////////////////////////////////////////////
  849. DWORD
  850. GetThreadArrays(HANDLE hCurrentProcess,
  851. DWORD * pdwThreads,
  852. SYSTEM_EXTENDED_THREAD_INFORMATION ** ppExtThreadInfo,
  853. TEB *** pppTebs)
  854. {
  855. if (!pdwThreads || !ppExtThreadInfo || !pppTebs)
  856. {
  857. return ERROR_INVALID_PARAMETER;
  858. };
  859. NTSTATUS Status;
  860. DWORD dwInc = 8*1024;
  861. DWORD dwSize = dwInc;
  862. VOID * pData = NULL;
  863. DWORD dwReturned;
  864. loop_realloc:
  865. pData = HeapAlloc(GetProcessHeap(),0,dwSize);
  866. if (!pData)
  867. {
  868. return ERROR_OUTOFMEMORY;
  869. }
  870. Status = NtQuerySystemInformation(SystemExtendedProcessInformation,
  871. pData,
  872. dwSize,
  873. &dwReturned);
  874. if (STATUS_INFO_LENGTH_MISMATCH == Status)
  875. {
  876. HeapFree(GetProcessHeap(),0,pData);
  877. dwSize += dwInc;
  878. goto loop_realloc;
  879. }
  880. else if (STATUS_SUCCESS == Status)
  881. {
  882. // here we have the snapshot:parse it
  883. SYSTEM_PROCESS_INFORMATION * pProcInfo = (SYSTEM_PROCESS_INFORMATION *)pData;
  884. SYSTEM_EXTENDED_THREAD_INFORMATION * pThreadInfo;
  885. // get the process id;
  886. ULONG_PTR IdProc;
  887. GetPeb(hCurrentProcess,NULL,&IdProc);
  888. while (TRUE)
  889. {
  890. //dprintf(" process %p curr %p\n",pProcInfo->UniqueProcessId,IdProc);
  891. if (IdProc == (ULONG_PTR)pProcInfo->UniqueProcessId)
  892. {
  893. DWORD Threads = pProcInfo->NumberOfThreads;
  894. *pdwThreads = Threads;
  895. DWORD i;
  896. pThreadInfo = (SYSTEM_EXTENDED_THREAD_INFORMATION *)((ULONG_PTR)pProcInfo+sizeof(SYSTEM_PROCESS_INFORMATION));
  897. SYSTEM_EXTENDED_THREAD_INFORMATION * pOutThreadInfo = NULL;
  898. TEB ** ppOutTebs = NULL;
  899. pOutThreadInfo = (SYSTEM_EXTENDED_THREAD_INFORMATION *)HeapAlloc(GetProcessHeap(),0,Threads*sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION));
  900. if (pOutThreadInfo)
  901. {
  902. ppOutTebs = (TEB **)HeapAlloc(GetProcessHeap(),0,Threads*sizeof(TEB *));
  903. if (!ppOutTebs)
  904. {
  905. HeapFree(GetProcessHeap(),0,pOutThreadInfo);
  906. Status = ERROR_OUTOFMEMORY;
  907. Threads = 0; // to stop loop
  908. }
  909. else
  910. {
  911. memcpy(pOutThreadInfo,pThreadInfo,Threads*sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION));
  912. }
  913. }
  914. else
  915. {
  916. Status = ERROR_OUTOFMEMORY;
  917. Threads = 0; // to stop loop
  918. }
  919. for (i=0;i<Threads;i++)
  920. {
  921. //dprintf(" %x.%x\n",pThreadInfo->ThreadInfo.ClientId.UniqueProcess,pThreadInfo->ThreadInfo.ClientId.UniqueThread);
  922. NTSTATUS StatusThread;
  923. HANDLE hThread;
  924. OBJECT_ATTRIBUTES Obja = {sizeof( OBJECT_ATTRIBUTES ), 0, 0, 0 ,0 };
  925. StatusThread = NtOpenThread(&hThread,THREAD_QUERY_INFORMATION,&Obja,&(pThreadInfo->ThreadInfo.ClientId));
  926. if (((NTSTATUS)0L) == StatusThread)
  927. {
  928. TEB * pTeb = NULL;
  929. GetTeb(hThread,&pTeb);
  930. ppOutTebs[i] = pTeb;
  931. CloseHandle(hThread);
  932. }
  933. else
  934. {
  935. dprintf("NtOpenThread %d\n",StatusThread);
  936. }
  937. pThreadInfo++;
  938. }
  939. // once found our process,
  940. // don't bother with the others
  941. *pppTebs = ppOutTebs;
  942. *ppExtThreadInfo = pOutThreadInfo;
  943. Status = NO_ERROR;
  944. break;
  945. }
  946. if (0 == pProcInfo->NextEntryOffset)
  947. {
  948. break;
  949. }
  950. else
  951. {
  952. pProcInfo = (SYSTEM_PROCESS_INFORMATION *)((ULONG_PTR)pProcInfo+pProcInfo->NextEntryOffset);
  953. }
  954. }
  955. }
  956. else // other cases
  957. {
  958. dprintf("NtQuerySystemInformation %08x\n",Status);
  959. return Status;
  960. }
  961. return Status;
  962. }
  963. DECLARE_API(t)
  964. {
  965. INIT_API();
  966. DWORD dwThreads;
  967. TEB ** ppTebs = NULL;
  968. SYSTEM_EXTENDED_THREAD_INFORMATION * pSysThreadInfo = NULL;
  969. // get the offsets only once
  970. ULONG OffsetRPC;
  971. ULONG_PTR pRpcThread;
  972. if (0 != GetFieldOffset("ntdll!TEB","ReservedForNtRpc",&OffsetRPC))
  973. {
  974. #ifdef _WIN64
  975. OffsetRPC = 0x1698;
  976. #else
  977. OffsetRPC = 0xf1c;
  978. #endif
  979. }
  980. ULONG OffsetOLE;
  981. ULONG_PTR pOleThread;
  982. if (0 != GetFieldOffset("ntdll!TEB","ReservedForOle",&OffsetOLE))
  983. {
  984. #ifdef _WIN64
  985. OffsetOLE = 0x1758;
  986. #else
  987. OffsetOLE = 0xf80;
  988. #endif
  989. }
  990. DWORD dwErr;
  991. MEMORY_ADDRESS pCurrentTEB = GetExpression(args);
  992. dwErr = GetThreadArrays(hCurrentProcess,&dwThreads,
  993. &pSysThreadInfo,&ppTebs);
  994. if (NO_ERROR == dwErr)
  995. {
  996. for (DWORD i=0;i<dwThreads;i++)
  997. {
  998. TEB * pTeb = ppTebs[i];
  999. if (pCurrentTEB)
  1000. {
  1001. if (pTeb != (TEB *)pCurrentTEB)
  1002. continue;
  1003. }
  1004. SYSTEM_EXTENDED_THREAD_INFORMATION * pThreadInfo = &pSysThreadInfo[i];
  1005. if (ReadMemory((ULONG_PTR)pTeb+OffsetOLE,&pOleThread,sizeof(ULONG_PTR),0) &&
  1006. ReadMemory((ULONG_PTR)pTeb+OffsetRPC,&pRpcThread,sizeof(ULONG_PTR),0))
  1007. {
  1008. NT_TIB NtTib;
  1009. ReadMemory((ULONG_PTR)pTeb,&NtTib,sizeof(NT_TIB),NULL);
  1010. dprintf(" %03d %x.%x Addr: %p TEB: %p FiberData %p\n"
  1011. " limit %p base %p\n"
  1012. " RPC %p OLE %p\n",
  1013. i,
  1014. pThreadInfo->ThreadInfo.ClientId.UniqueProcess,pThreadInfo->ThreadInfo.ClientId.UniqueThread,
  1015. pThreadInfo->Win32StartAddress,
  1016. pTeb,NtTib.FiberData,
  1017. NtTib.StackLimit,NtTib.StackBase,
  1018. pRpcThread,
  1019. pOleThread);
  1020. #ifdef _WIN64
  1021. // +0x1788 DeallocationBStore : (null)
  1022. // +0x1790 BStoreLimit : 0x000006fb`faba2000
  1023. ULONG_PTR lDeAlloc;
  1024. ULONG_PTR lBPLimit;
  1025. ULONG Offset_DeallocationBStore = 0x1788;
  1026. ReadMemory((ULONG_PTR)pTeb+Offset_DeallocationBStore,&lDeAlloc,sizeof(ULONG_PTR),0);
  1027. ULONG Offset_BStoreLimit = 0x1790;
  1028. ReadMemory((ULONG_PTR)pTeb+Offset_BStoreLimit,&lBPLimit,sizeof(ULONG_PTR),0);
  1029. dprintf(" DAll %p BStL %p\n",lDeAlloc,lBPLimit);
  1030. #endif
  1031. DumpRpcOle(pRpcThread,pOleThread);
  1032. }
  1033. else
  1034. {
  1035. dprintf("RM %p %p\n",(ULONG_PTR)pTeb+OffsetOLE,(ULONG_PTR)pTeb+OffsetRPC);
  1036. }
  1037. }
  1038. }
  1039. if (ppTebs)
  1040. HeapFree(GetProcessHeap(),0,ppTebs);
  1041. if (pSysThreadInfo)
  1042. HeapFree(GetProcessHeap(),0,pSysThreadInfo);
  1043. }
  1044. DECLARE_API(srt)
  1045. {
  1046. INIT_API();
  1047. DWORD dwThreads;
  1048. TEB ** ppTebs;
  1049. SYSTEM_EXTENDED_THREAD_INFORMATION * pSysThreadInfo;
  1050. MEMORY_ADDRESS Addr = GetExpression(args);
  1051. ULONG_PTR * ThreadMem = NULL;
  1052. ULONG_PTR Size = 0;
  1053. if (NO_ERROR == GetThreadArrays(hCurrentProcess,&dwThreads,
  1054. &pSysThreadInfo,&ppTebs))
  1055. {
  1056. for (DWORD i=0;i<dwThreads;i++)
  1057. {
  1058. TEB * pTeb = ppTebs[i];
  1059. SYSTEM_EXTENDED_THREAD_INFORMATION * pThreadInfo = &pSysThreadInfo[i];
  1060. TEB Teb;
  1061. ReadMemory((ULONG_PTR)pTeb,&Teb,sizeof(TEB),NULL);
  1062. #ifndef _IA64_
  1063. ULONG_PTR Base = (ULONG_PTR)Teb.NtTib.StackBase;
  1064. #else
  1065. ULONG_PTR Base = (ULONG_PTR)Teb.BStoreLimit;
  1066. #endif
  1067. ULONG_PTR Limit = (ULONG_PTR)Teb.NtTib.StackLimit;
  1068. ULONG_PTR CurrSize = Base-Limit;
  1069. //dprintf("searching %p between %p and %p\n",Addr,Limit,Base);
  1070. if (CurrSize > Size)
  1071. {
  1072. Size = CurrSize;
  1073. if (ThreadMem)
  1074. {
  1075. HeapFree(GetProcessHeap(),0,ThreadMem);
  1076. ThreadMem = NULL;
  1077. }
  1078. ThreadMem = (ULONG_PTR *)HeapAlloc(GetProcessHeap(),0,Size);
  1079. }
  1080. if (ThreadMem)
  1081. {
  1082. if (ReadMemory(Limit,ThreadMem,(ULONG)CurrSize,NULL))
  1083. {
  1084. for(DWORD j=0;j<CurrSize/sizeof(ULONG_PTR);j++)
  1085. {
  1086. if (Addr == ThreadMem[j])
  1087. {
  1088. dprintf(" %x.%x %p\n",
  1089. pThreadInfo->ThreadInfo.ClientId.UniqueProcess,pThreadInfo->ThreadInfo.ClientId.UniqueThread,
  1090. Limit+((ULONG_PTR)&ThreadMem[j]-(ULONG_PTR)ThreadMem));
  1091. }
  1092. }
  1093. }
  1094. };
  1095. }
  1096. HeapFree(GetProcessHeap(),0,ppTebs);
  1097. HeapFree(GetProcessHeap(),0,pSysThreadInfo);
  1098. }
  1099. if (ThreadMem)
  1100. HeapFree(GetProcessHeap(),0,ThreadMem);
  1101. }
  1102. #if defined(_X86_)
  1103. #ifndef PAGE_SIZE
  1104. #define PAGE_SIZE 0x1000
  1105. #endif
  1106. #define USER_ALIGNMENT 8
  1107. #elif defined(_IA64_)
  1108. #ifndef PAGE_SIZE
  1109. #define PAGE_SIZE 0x2000
  1110. #endif
  1111. #define USER_ALIGNMENT 16
  1112. #elif defined(_AMD64_)
  1113. #ifndef PAGE_SIZE
  1114. #define PAGE_SIZE 0x1000
  1115. #endif
  1116. #define USER_ALIGNMENT 16
  1117. #else
  1118. #error // platform not defined
  1119. #endif
  1120. BYTE s_Prolog[] = { 0x8b, 0xd0 };
  1121. // repeat this
  1122. BYTE s_Body[] = {
  1123. 0xb8, 0xFF, 0xFF, 0xFF, 0xFF,
  1124. 0x8b, 0x48, 0x04,
  1125. 0x8b, 0x58, 0x08,
  1126. 0x3b, 0xcb,
  1127. 0x74, 0x07,
  1128. 0x8b, 0x03,
  1129. 0x83, 0xc3, 0x04,
  1130. 0xeb, 0xf5,
  1131. };
  1132. // stop repeat
  1133. BYTE s_Epilog[] = {
  1134. 0x8b, 0xc2,
  1135. 0xcc,
  1136. 0xba, 0xEE, 0xEE, 0xEE, 0xEE,
  1137. 0xff, 0xe2,
  1138. 0x90,
  1139. 0x90,
  1140. };
  1141. DECLARE_API(ksrt)
  1142. {
  1143. INIT_API();
  1144. if (!g_KD)
  1145. {
  1146. dprintf("KD support only\n");
  1147. return;
  1148. }
  1149. char * pArgs = (char *)args;
  1150. while(isspace(*pArgs)) pArgs++;
  1151. MEMORY_ADDRESS EProcess = GetExpression(pArgs);
  1152. while(!isspace(*pArgs)) pArgs++;
  1153. while(isspace(*pArgs)) pArgs++;
  1154. char * pValue = pArgs;
  1155. MEMORY_ADDRESS SearchFor = GetExpression(pValue);
  1156. while(!isspace(*pArgs)) pArgs++;
  1157. while(isspace(*pArgs)) pArgs++;
  1158. MEMORY_ADDRESS PrintPageIn = 0;
  1159. if (pArgs != pValue+strlen(pValue))
  1160. {
  1161. PrintPageIn = GetExpression(pArgs);
  1162. }
  1163. dprintf("[DBG] %p %p %p\n",EProcess,SearchFor,PrintPageIn );
  1164. ULONG OffsetProcessThreadList;
  1165. if (0 != GetFieldOffset("nt!_KPROCESS","ThreadListHead",&OffsetProcessThreadList))
  1166. {
  1167. #ifdef _WIN64
  1168. OffsetProcessThreadList = 0x088;
  1169. #else
  1170. OffsetProcessThreadList = 0x050;
  1171. #endif
  1172. }
  1173. ULONG OffsetThreadThreadList;
  1174. if (0 != GetFieldOffset("nt!_KTHREAD","ThreadListEntry",&OffsetThreadThreadList))
  1175. {
  1176. #ifdef _WIN64
  1177. OffsetThreadThreadList = 0x320;
  1178. #else
  1179. OffsetThreadThreadList = 0x1b0;
  1180. #endif
  1181. }
  1182. ULONG OffsetThreadTEB;
  1183. if (0 != GetFieldOffset("nt!_KTHREAD","Teb",&OffsetThreadTEB))
  1184. {
  1185. #ifdef _WIN64
  1186. OffsetThreadTEB = 0x070;
  1187. #else
  1188. OffsetThreadTEB = 0x020;
  1189. #endif
  1190. }
  1191. if (EProcess)
  1192. {
  1193. #ifdef _X86_
  1194. BYTE * pMemory = NULL;
  1195. BYTE * pNext;
  1196. if (PrintPageIn)
  1197. {
  1198. pMemory = (BYTE *)HeapAlloc(GetProcessHeap(),0,4*1024);
  1199. pNext = pMemory;
  1200. if (NULL == pMemory)
  1201. {
  1202. PrintPageIn = 0;
  1203. }
  1204. else
  1205. {
  1206. memset(pMemory,0x90,4*1024);
  1207. memcpy(pMemory,s_Prolog,sizeof(s_Prolog));
  1208. pNext+=sizeof(s_Prolog);
  1209. }
  1210. }
  1211. dprintf("pMemory %p\n",pMemory);
  1212. #endif
  1213. LIST_ENTRY HeadList;
  1214. LIST_ENTRY * pListEntry = &HeadList;
  1215. EProcess += OffsetProcessThreadList;
  1216. DWORD SizeToRead = max(OffsetThreadTEB,OffsetThreadThreadList)+sizeof(LIST_ENTRY);
  1217. ULONG_PTR KThreadAddr;
  1218. ULONG_PTR Teb;
  1219. ULONG_PTR * pKTHREAD = (ULONG_PTR *)_alloca(SizeToRead);
  1220. if (ReadMemory(EProcess,&HeadList,sizeof(LIST_ENTRY),NULL))
  1221. {
  1222. DWORD i = 0;
  1223. while ((LIST_ENTRY *)EProcess != pListEntry->Flink)
  1224. {
  1225. //dprintf("pListEntry->Flink %p\n",pListEntry->Flink);
  1226. KThreadAddr = (ULONG_PTR)pListEntry->Flink - (ULONG_PTR)OffsetThreadThreadList;
  1227. if (ReadMemory((ULONG_PTR)KThreadAddr,pKTHREAD,SizeToRead,NULL))
  1228. {
  1229. // do useful work
  1230. Teb = *((ULONG_PTR *)((BYTE *)pKTHREAD+OffsetThreadTEB));
  1231. dprintf(" %d - _KTHREAD %p TEB %p\n",i++,KThreadAddr,Teb);
  1232. if (PrintPageIn)
  1233. {
  1234. #ifdef _X86_
  1235. memcpy(pNext,s_Body,sizeof(s_Body));
  1236. *(ULONG_PTR *)(pNext+1) = Teb;
  1237. pNext+=sizeof(s_Body);
  1238. #endif
  1239. }
  1240. else
  1241. {
  1242. NT_TIB ThreadTib;
  1243. if (ReadMemory(Teb,&ThreadTib,sizeof(NT_TIB),NULL))
  1244. {
  1245. dprintf(" EL %p B %p L %p F %p\n",ThreadTib.ExceptionList,ThreadTib.StackBase,ThreadTib.StackLimit,ThreadTib.FiberData);
  1246. ULONG_PTR Current = (ULONG_PTR)ThreadTib.StackLimit;
  1247. ULONG_PTR nPages = (ULONG_PTR)ThreadTib.StackBase-(ULONG_PTR)ThreadTib.StackLimit;
  1248. nPages /= PAGE_SIZE;
  1249. ULONG_PTR j;
  1250. for (j=0;j<nPages;j++)
  1251. {
  1252. ULONG_PTR pPage[PAGE_SIZE/sizeof(ULONG_PTR)];
  1253. if (ReadMemory(Current,pPage,sizeof(pPage),NULL))
  1254. {
  1255. for(DWORD k=0;k<(PAGE_SIZE/sizeof(ULONG_PTR));k++)
  1256. {
  1257. if(SearchFor == pPage[k])
  1258. {
  1259. dprintf(" %p\n",Current+k*sizeof(ULONG_PTR));
  1260. }
  1261. if (CheckControlC())
  1262. break;
  1263. }
  1264. }
  1265. else
  1266. {
  1267. dprintf(" page @ %p not paged-in\n",Current);
  1268. }
  1269. Current += PAGE_SIZE;
  1270. if (CheckControlC())
  1271. break;
  1272. }
  1273. }
  1274. else
  1275. {
  1276. dprintf(" RM Teb %p\n",Teb);
  1277. }
  1278. }
  1279. // equivalent of i++
  1280. pListEntry = (LIST_ENTRY *)((BYTE *)pKTHREAD+OffsetThreadThreadList);
  1281. }
  1282. else
  1283. {
  1284. dprintf("RM %p\n",KThreadAddr);
  1285. break;
  1286. }
  1287. if (CheckControlC())
  1288. break;
  1289. }
  1290. }
  1291. else
  1292. {
  1293. dprintf("RM %p\n",EProcess);
  1294. }
  1295. #ifdef _X86_
  1296. if (pMemory)
  1297. {
  1298. memcpy(pNext,s_Epilog,sizeof(s_Epilog));
  1299. pNext+=sizeof(s_Epilog);
  1300. ULONG_PTR nDW = (ULONG_PTR)pNext-(ULONG_PTR)pMemory;
  1301. dprintf("writing %p bytes to %p\n",nDW,PrintPageIn);
  1302. WriteMemory(PrintPageIn,pMemory,nDW,NULL);
  1303. /*
  1304. nDW/=sizeof(DWORD);
  1305. DWORD * pDW = (DWORD *) pMemory;
  1306. for (ULONG_PTR i =0;i<(nDW+1);i++)
  1307. {
  1308. if (0 == i%8)
  1309. dprintf("\n");
  1310. dprintf("%08x ",pDW[i]);
  1311. }
  1312. dprintf("\n");
  1313. */
  1314. // dprintf the whole content
  1315. HeapFree(GetProcessHeap(),0,pMemory);
  1316. }
  1317. #endif
  1318. }
  1319. else
  1320. {
  1321. dprintf("unable to resolve %s\n",args);
  1322. }
  1323. }
  1324. #ifdef i386
  1325. #define MAGIC_START (16+2)
  1326. #endif
  1327. char *
  1328. GetCall(ULONG_PTR Addr, BOOL pPrint = TRUE)
  1329. {
  1330. static char pBuff[1024];
  1331. #ifdef KDEXT_64BIT
  1332. ULONG64 ThisAddr = Addr-2;
  1333. #else
  1334. ULONG_PTR ThisAddr = Addr-2;
  1335. #endif
  1336. Disasm(&ThisAddr,pBuff,FALSE);
  1337. if (strstr(pBuff,"call"))
  1338. {
  1339. if (pPrint)
  1340. dprintf(" %s\n",pBuff);
  1341. return pBuff;
  1342. }
  1343. ThisAddr = Addr-3;
  1344. Disasm(&ThisAddr,pBuff,FALSE);
  1345. if (strstr(pBuff,"call"))
  1346. {
  1347. if (pPrint)
  1348. dprintf(" %s\n",pBuff);
  1349. return pBuff;
  1350. }
  1351. ThisAddr = Addr-5;
  1352. Disasm(&ThisAddr,pBuff,FALSE);
  1353. if (strstr(pBuff,"call"))
  1354. {
  1355. if (pPrint)
  1356. dprintf(" %s\n",pBuff);
  1357. return pBuff;
  1358. }
  1359. ThisAddr = Addr-6;
  1360. Disasm(&ThisAddr,pBuff,FALSE);
  1361. if (strstr(pBuff,"call"))
  1362. {
  1363. if (pPrint)
  1364. dprintf(" %s\n",pBuff);
  1365. return pBuff;
  1366. }
  1367. return NULL;
  1368. }
  1369. DECLARE_API(bs0)
  1370. {
  1371. #ifdef i386
  1372. INIT_API();
  1373. MEMORY_ADDRESS pTeb = GetExpression(args);
  1374. if (pTeb)
  1375. {
  1376. NT_TIB Tib;
  1377. ReadMemory(pTeb,&Tib,sizeof(Tib),NULL);
  1378. dprintf(" exception %p base %p limit %p\n",
  1379. Tib.ExceptionList,Tib.StackBase,Tib.StackLimit);
  1380. ULONG_PTR dwSize = (ULONG_PTR)Tib.StackBase-(ULONG_PTR)Tib.StackLimit;
  1381. BYTE * pStack = new BYTE[dwSize];
  1382. ULONG_PTR OldEBP = 0;
  1383. if (pStack)
  1384. {
  1385. ULONG_PTR * pBase = (ULONG_PTR *)(pStack+dwSize);
  1386. ULONG_PTR * pLimit = (ULONG_PTR *)pStack;
  1387. if (ReadMemory((ULONG_PTR)Tib.StackLimit,pStack,(ULONG_PTR)Tib.StackBase-(ULONG_PTR)Tib.StackLimit,NULL))
  1388. {
  1389. ULONG_PTR EBP = (ULONG_PTR)(Tib.StackBase)-(MAGIC_START*sizeof(ULONG_PTR));
  1390. ULONG_PTR * pEBP = (ULONG_PTR *)pBase-MAGIC_START;
  1391. BOOL bGoOn = TRUE;
  1392. BOOL bRpcRt4Fix = FALSE;
  1393. while(bGoOn)
  1394. {
  1395. dprintf("%p %p\n",pEBP[0],pEBP[1]);
  1396. char * pFunction = GetCall(pEBP[1]);
  1397. BOOL bFound = FALSE;
  1398. if (pFunction)
  1399. {
  1400. if (strstr(pFunction,"ComInvokeWithLockAndIPID"))
  1401. {
  1402. EBP -= 0x70;
  1403. }
  1404. }
  1405. else // try to move back
  1406. {
  1407. pEBP--;
  1408. EBP = OldEBP;
  1409. }
  1410. dprintf("looking for %p = cmp %p \n",EBP,pEBP[0]);
  1411. if (!bRpcRt4Fix)
  1412. {
  1413. if (pEBP[0] < (ULONG_PTR)Tib.StackLimit || pEBP[0] > (ULONG_PTR)Tib.StackBase)
  1414. {
  1415. bRpcRt4Fix = TRUE;
  1416. // rpcrt4 call_stack fix
  1417. EBP = (ULONG_PTR)(Tib.StackBase) - 0x6c;
  1418. }
  1419. }
  1420. dprintf("looking for %p\n",EBP);
  1421. while ((ULONG_PTR)pEBP > (ULONG_PTR)pLimit){
  1422. if (*pEBP-- == EBP){
  1423. bFound = TRUE;
  1424. break;
  1425. }
  1426. }
  1427. if (bFound)
  1428. {
  1429. pEBP++;
  1430. OldEBP = EBP;
  1431. EBP = (ULONG_PTR)(Tib.StackBase)-((ULONG_PTR)pBase-(ULONG_PTR)pEBP);
  1432. }
  1433. else
  1434. {
  1435. bGoOn = FALSE;
  1436. }
  1437. }
  1438. }
  1439. delete [] pStack;
  1440. }
  1441. }
  1442. else
  1443. {
  1444. dprintf("%s cannot be interpreted\b",args);
  1445. }
  1446. #endif
  1447. }
  1448. DECLARE_API(bs)
  1449. {
  1450. #ifdef i386
  1451. INIT_API();
  1452. char * pArgs = (char *)args;
  1453. MEMORY_ADDRESS pTeb = GetExpression(args);
  1454. while (isspace(*pArgs)) pArgs++; // skip leading spaces
  1455. while (!isspace(*pArgs)) pArgs++; // skip the TEB
  1456. while (isspace(*pArgs)) pArgs++; // skip other spaces
  1457. MEMORY_ADDRESS pCurrentESP = GetExpression(pArgs);
  1458. if (pTeb)
  1459. {
  1460. NT_TIB Tib;
  1461. ReadMemory(pTeb,&Tib,sizeof(Tib),NULL);
  1462. dprintf(" exception %p base %p limit %p\n",
  1463. Tib.ExceptionList,Tib.StackBase,Tib.StackLimit);
  1464. ULONG_PTR dwSize = (ULONG_PTR)Tib.StackBase-(ULONG_PTR)Tib.StackLimit;
  1465. BYTE * pStack = new BYTE[dwSize];
  1466. if (pStack)
  1467. {
  1468. ULONG_PTR * pBase = (ULONG_PTR *)(pStack+dwSize);
  1469. ULONG_PTR * pLimit = (ULONG_PTR *)pStack;
  1470. if (ReadMemory((ULONG_PTR)Tib.StackLimit,pStack,(ULONG_PTR)Tib.StackBase-(ULONG_PTR)Tib.StackLimit,NULL))
  1471. {
  1472. dwSize = dwSize/sizeof(ULONG_PTR);
  1473. ULONG_PTR * pStack2 = (ULONG_PTR *)pStack;
  1474. ULONG_PTR i = (dwSize-1);
  1475. while(i)
  1476. {
  1477. char * pInstr = GetCall(pLimit[i],FALSE);
  1478. if (pInstr)
  1479. {
  1480. if (strstr(pInstr,"__SEH_"))
  1481. {
  1482. // skip those
  1483. }
  1484. else
  1485. {
  1486. if ((ULONG_PTR)Tib.StackBase > pLimit[i-1] && pLimit[i-1] > (ULONG_PTR)Tib.StackLimit)
  1487. {
  1488. dprintf(" ");
  1489. GetVTable((MEMORY_ADDRESS)((ULONG_PTR)Tib.StackLimit+i*sizeof(ULONG_PTR)));
  1490. pInstr = strstr(pInstr,"call");
  1491. dprintf("[%p] %p %p - %s",
  1492. (ULONG_PTR)Tib.StackLimit+(i-1)*sizeof(ULONG_PTR),
  1493. pLimit[i-1],
  1494. pLimit[i],
  1495. pInstr);
  1496. }
  1497. }
  1498. }
  1499. i--;
  1500. if (pCurrentESP) // the user specified a end address
  1501. {
  1502. if (((ULONG_PTR)Tib.StackLimit+(i-1)*sizeof(ULONG_PTR)) < pCurrentESP)
  1503. break;
  1504. }
  1505. }
  1506. }
  1507. else
  1508. {
  1509. dprintf("RM %p\n",Tib.StackLimit);
  1510. }
  1511. delete [] pStack;
  1512. }
  1513. }
  1514. else
  1515. {
  1516. dprintf("cannot interpret,%s\b",args);
  1517. }
  1518. #endif
  1519. }
  1520. //
  1521. // given the TEB, prints the ExceptionList
  1522. //
  1523. struct _C9_REGISTRATION_RECORD
  1524. {
  1525. _C9_REGISTRATION_RECORD * prev;
  1526. void * handler;
  1527. void * scopetable;
  1528. void * trylevel;
  1529. void * pSpare0;
  1530. void * pSpare1;
  1531. };
  1532. //
  1533. // _C9_REGISTRATION_RECORD.scopetable points to an array of _SCOPETABLE_ENTRY
  1534. //
  1535. struct _SCOPETABLE_ENTRY {
  1536. ULONG_PTR enclosing_level;
  1537. VOID * filter;
  1538. VOID * specific_handler;
  1539. };
  1540. DECLARE_API(el)
  1541. {
  1542. INIT_API();
  1543. #ifndef _X86_
  1544. dprintf("unsupported on this platform\n");
  1545. return;
  1546. #endif
  1547. MEMORY_ADDRESS pTeb = GetExpression(args);
  1548. if (pTeb)
  1549. {
  1550. NT_TIB Tib;
  1551. if (ReadMemory(pTeb,&Tib,sizeof(Tib),NULL))
  1552. {
  1553. //Tib.ExceptionList,Tib.StackBase,Tib.StackLimit);
  1554. _C9_REGISTRATION_RECORD ExRegRec;
  1555. ExRegRec.prev = (_C9_REGISTRATION_RECORD *)Tib.ExceptionList;
  1556. do
  1557. {
  1558. _C9_REGISTRATION_RECORD * pThis = ExRegRec.prev;
  1559. if (ReadMemory((MEMORY_ADDRESS)pThis,&ExRegRec,sizeof(ExRegRec),NULL))
  1560. {
  1561. dprintf(" %p (%p %p %p %p)\n",pThis,ExRegRec.prev,ExRegRec.handler,ExRegRec.scopetable,ExRegRec.trylevel);
  1562. #ifdef KDEXT_64BIT
  1563. ULONG64 Displ;
  1564. #else
  1565. ULONG Displ;
  1566. #endif
  1567. char pString[256];
  1568. pString[0]=0;
  1569. GetSymbol((ULONG_PTR)ExRegRec.handler,(PCHAR)pString,&Displ);
  1570. if (lstrlenA((CHAR *)pString))
  1571. dprintf(" %s+%x\n",pString,Displ);
  1572. if (!GetCall((ULONG_PTR)ExRegRec.pSpare1))
  1573. {
  1574. GetCall((ULONG_PTR)ExRegRec.pSpare0);
  1575. }
  1576. }
  1577. else
  1578. {
  1579. dprintf("RM %p\n",Tib.ExceptionList);
  1580. break;
  1581. }
  1582. } while((ULONG_PTR)(-1) != (ULONG_PTR)ExRegRec.prev);
  1583. }
  1584. else
  1585. {
  1586. dprintf("RM %p\n",pTeb);
  1587. }
  1588. }
  1589. else
  1590. {
  1591. dprintf("invalid TEB %s\n",args);
  1592. }
  1593. }