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.

671 lines
17 KiB

  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <memory.h>
  5. #include <nt.h>
  6. #include <ntrtl.h>
  7. #include <nturtl.h>
  8. #include <windows.h>
  9. #include <pviewp.h>
  10. #include <explode.h>
  11. #define DEFAULT_INCR (64*1024)
  12. LIST_ENTRY VaList;
  13. typedef struct _VAINFO {
  14. LIST_ENTRY Links;
  15. LIST_ENTRY AllocationBaseHead;
  16. MEMORY_BASIC_INFORMATION BasicInfo;
  17. } VAINFO, *PVAINFO;
  18. PVAINFO LastAllocationBase;
  19. SIZE_T CommitedBytes;
  20. SIZE_T ReservedBytes;
  21. SIZE_T FreeBytes;
  22. SIZE_T ImageCommitedBytes;
  23. SIZE_T ImageReservedBytes;
  24. SIZE_T ImageFreeBytes;
  25. #define NOACCESS 0
  26. #define READONLY 1
  27. #define READWRITE 2
  28. #define WRITECOPY 3
  29. #define EXECUTE 4
  30. #define EXECUTEREAD 5
  31. #define EXECUTEREADWRITE 6
  32. #define EXECUTEWRITECOPY 7
  33. #define MAXPROTECT 8
  34. ULONG_PTR MappedCommit[MAXPROTECT];
  35. ULONG_PTR PrivateCommit[MAXPROTECT];
  36. typedef struct _MODINFO {
  37. PVOID BaseAddress;
  38. SIZE_T VirtualSize;
  39. ANSI_STRING Name;
  40. ANSI_STRING FullName;
  41. ULONG_PTR CommitVector[MAXPROTECT];
  42. } MODINFO, *PMODINFO;
  43. #define MODINFO_SIZE 64
  44. ULONG ModInfoNext;
  45. MODINFO ModInfo[MODINFO_SIZE];
  46. MODINFO TotalModInfo;
  47. PMODINFO
  48. LocateModInfo(
  49. PVOID Address
  50. )
  51. {
  52. int i;
  53. for (i=0;i<(int)ModInfoNext;i++){
  54. if ( Address >= ModInfo[i].BaseAddress &&
  55. Address <= (PVOID)((ULONG_PTR)ModInfo[i].BaseAddress+ModInfo[i].VirtualSize) ) {
  56. return &ModInfo[i];
  57. }
  58. }
  59. return NULL;
  60. }
  61. VOID
  62. ComputeModInfo(
  63. HWND hDlg,
  64. HANDLE Process
  65. )
  66. {
  67. PPEB Peb;
  68. NTSTATUS Status;
  69. PROCESS_BASIC_INFORMATION BasicInfo;
  70. PLDR_DATA_TABLE_ENTRY LdrEntry;
  71. LDR_DATA_TABLE_ENTRY LdrEntryData;
  72. PLIST_ENTRY LdrHead,LdrNext;
  73. PPEB_LDR_DATA Ldr;
  74. UNICODE_STRING us;
  75. int i,nIndex;
  76. HWND ComboList;
  77. HANDLE hFile;
  78. HANDLE hMappedFile;
  79. PIMAGE_DOS_HEADER DosHeader;
  80. PIMAGE_NT_HEADERS FileHeader;
  81. LPSTR p;
  82. PVOID MappedAddress;
  83. for (i=0;i<(int)ModInfoNext;i++){
  84. if ( ModInfo[i].BaseAddress &&
  85. ModInfo[i].BaseAddress != (PVOID) (-1) &&
  86. ModInfo[i].Name.Buffer
  87. ) {
  88. RtlFreeAnsiString(&ModInfo[i].Name);
  89. }
  90. }
  91. ModInfoNext = 0;
  92. RtlZeroMemory(ModInfo,sizeof(ModInfo));
  93. RtlInitAnsiString(&TotalModInfo.Name," TotalImageCommit");
  94. ComboList = GetDlgItem(hDlg, PXPLODE_IMAGE_COMMIT);
  95. SendMessage(ComboList, CB_RESETCONTENT, 0, 0);
  96. SendMessage(ComboList, CB_SETITEMDATA, 0L, 0L);
  97. nIndex = (int)SendMessage(
  98. ComboList,
  99. CB_ADDSTRING,
  100. 0,
  101. (LPARAM)TotalModInfo.Name.Buffer
  102. );
  103. SendMessage(
  104. ComboList,
  105. CB_SETITEMDATA,
  106. nIndex,
  107. (LPARAM)&TotalModInfo
  108. );
  109. Status = NtQueryInformationProcess(
  110. Process,
  111. ProcessBasicInformation,
  112. &BasicInfo,
  113. sizeof(BasicInfo),
  114. NULL
  115. );
  116. if ( !NT_SUCCESS(Status) ) {
  117. if ( Status == STATUS_INFO_LENGTH_MISMATCH ) {
  118. Status = NtQueryInformationProcess(
  119. Process,
  120. ProcessBasicInformation,
  121. &BasicInfo,
  122. sizeof(BasicInfo)-4,
  123. NULL
  124. );
  125. if ( !NT_SUCCESS(Status) ) {
  126. return;
  127. }
  128. }
  129. else {
  130. return;
  131. }
  132. }
  133. Peb = BasicInfo.PebBaseAddress;
  134. //
  135. // Ldr = Peb->Ldr
  136. //
  137. Status = NtReadVirtualMemory(
  138. Process,
  139. &Peb->Ldr,
  140. &Ldr,
  141. sizeof(Ldr),
  142. NULL
  143. );
  144. if ( !NT_SUCCESS(Status) ) {
  145. return;
  146. }
  147. LdrHead = &Ldr->InMemoryOrderModuleList;
  148. //
  149. // LdrNext = Head->Flink;
  150. //
  151. Status = NtReadVirtualMemory(
  152. Process,
  153. &LdrHead->Flink,
  154. &LdrNext,
  155. sizeof(LdrNext),
  156. NULL
  157. );
  158. if ( !NT_SUCCESS(Status) ) {
  159. return;
  160. }
  161. while ( LdrNext != LdrHead ) {
  162. LdrEntry = CONTAINING_RECORD(LdrNext,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks);
  163. Status = NtReadVirtualMemory(
  164. Process,
  165. LdrEntry,
  166. &LdrEntryData,
  167. sizeof(LdrEntryData),
  168. NULL
  169. );
  170. if ( !NT_SUCCESS(Status) ) {
  171. return;
  172. }
  173. ModInfo[ModInfoNext].BaseAddress = LdrEntryData.DllBase;
  174. us.Length = LdrEntryData.BaseDllName.Length;
  175. us.MaximumLength = LdrEntryData.BaseDllName.MaximumLength;
  176. us.Buffer = LocalAlloc(LMEM_ZEROINIT,us.MaximumLength);
  177. if ( !us.Buffer ) {
  178. return;
  179. }
  180. Status = NtReadVirtualMemory(
  181. Process,
  182. LdrEntryData.BaseDllName.Buffer,
  183. us.Buffer,
  184. us.MaximumLength,
  185. NULL
  186. );
  187. if ( !NT_SUCCESS(Status) ) {
  188. return;
  189. }
  190. RtlUnicodeStringToAnsiString(
  191. &ModInfo[ModInfoNext].Name,
  192. &us,
  193. TRUE
  194. );
  195. LocalFree(us.Buffer);
  196. us.Length = LdrEntryData.FullDllName.Length;
  197. us.MaximumLength = LdrEntryData.FullDllName.MaximumLength;
  198. us.Buffer = LocalAlloc(LMEM_ZEROINIT,us.MaximumLength);
  199. if ( !us.Buffer ) {
  200. return;
  201. }
  202. Status = NtReadVirtualMemory(
  203. Process,
  204. LdrEntryData.FullDllName.Buffer,
  205. us.Buffer,
  206. us.MaximumLength,
  207. NULL
  208. );
  209. if ( !NT_SUCCESS(Status) ) {
  210. return;
  211. }
  212. RtlUnicodeStringToAnsiString(
  213. &ModInfo[ModInfoNext].FullName,
  214. &us,
  215. TRUE
  216. );
  217. LocalFree(us.Buffer);
  218. if ( p = strchr(ModInfo[ModInfoNext].FullName.Buffer,':') ) {
  219. ModInfo[ModInfoNext].FullName.Buffer = p - 1;
  220. }
  221. hFile = CreateFile(
  222. ModInfo[ModInfoNext].FullName.Buffer,
  223. GENERIC_READ,
  224. FILE_SHARE_READ,
  225. NULL,
  226. OPEN_EXISTING,
  227. 0,
  228. NULL
  229. );
  230. if ( hFile == INVALID_HANDLE_VALUE ) {
  231. return;
  232. }
  233. hMappedFile = CreateFileMapping(
  234. hFile,
  235. NULL,
  236. PAGE_READONLY,
  237. 0,
  238. 0,
  239. NULL
  240. );
  241. CloseHandle(hFile);
  242. if ( !hMappedFile ) {
  243. return;
  244. }
  245. MappedAddress = MapViewOfFile(
  246. hMappedFile,
  247. FILE_MAP_READ,
  248. 0,
  249. 0,
  250. 0
  251. );
  252. CloseHandle(hMappedFile);
  253. if ( !MappedAddress ) {
  254. UnmapViewOfFile(MappedAddress);
  255. return;
  256. }
  257. DosHeader = (PIMAGE_DOS_HEADER)MappedAddress;
  258. if ( DosHeader->e_magic != IMAGE_DOS_SIGNATURE ) {
  259. UnmapViewOfFile(MappedAddress);
  260. return;
  261. }
  262. FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
  263. if ( FileHeader->Signature != IMAGE_NT_SIGNATURE ) {
  264. UnmapViewOfFile(MappedAddress);
  265. return;
  266. }
  267. ModInfo[ModInfoNext].VirtualSize = FileHeader->OptionalHeader.SizeOfImage;
  268. UnmapViewOfFile(MappedAddress);
  269. nIndex = (int)SendMessage(
  270. ComboList,
  271. CB_ADDSTRING,
  272. 0,
  273. (LPARAM)ModInfo[ModInfoNext].Name.Buffer
  274. );
  275. SendMessage(
  276. ComboList,
  277. CB_SETITEMDATA,
  278. nIndex,
  279. (LPARAM)&ModInfo[ModInfoNext]
  280. );
  281. ModInfoNext++;
  282. ModInfo[ModInfoNext].BaseAddress = (PVOID) (-1);
  283. LdrNext = LdrEntryData.InMemoryOrderLinks.Flink;
  284. }
  285. SendMessage(ComboList, CB_SETCURSEL, 0, 0);
  286. }
  287. ProtectionToIndex(
  288. ULONG Protection
  289. )
  290. {
  291. Protection &= ~PAGE_GUARD;
  292. switch ( Protection ) {
  293. case PAGE_NOACCESS:
  294. return NOACCESS;
  295. case PAGE_READONLY:
  296. return READONLY;
  297. case PAGE_READWRITE:
  298. return READWRITE;
  299. case PAGE_WRITECOPY:
  300. return WRITECOPY;
  301. case PAGE_EXECUTE:
  302. return EXECUTE;
  303. case PAGE_EXECUTE_READ:
  304. return EXECUTEREAD;
  305. case PAGE_EXECUTE_READWRITE:
  306. return EXECUTEREADWRITE;
  307. case PAGE_EXECUTE_WRITECOPY:
  308. return EXECUTEWRITECOPY;
  309. default:
  310. printf("Unknown Protection 0x%lx\n",Protection);
  311. return 0;
  312. }
  313. }
  314. VOID
  315. DumpImageCommit(
  316. HWND hDlg,
  317. PULONG_PTR CommitVector
  318. )
  319. {
  320. SIZE_T TotalCommitCount;
  321. ULONG i;
  322. CHAR szTemp[80];
  323. TotalCommitCount = 0;
  324. for ( i=0;i<MAXPROTECT;i++){
  325. TotalCommitCount += CommitVector[i];
  326. }
  327. wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
  328. SetDlgItemText(
  329. hDlg,
  330. PXPLODE_TOTALIMAGE_COMMIT,
  331. szTemp
  332. );
  333. wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
  334. SetDlgItemText(
  335. hDlg,
  336. PXPLODE_IMAGE_NOACCESS,
  337. szTemp
  338. );
  339. wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
  340. SetDlgItemText(
  341. hDlg,
  342. PXPLODE_IMAGE_READONLY,
  343. szTemp
  344. );
  345. wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
  346. SetDlgItemText(
  347. hDlg,
  348. PXPLODE_IMAGE_READWRITE,
  349. szTemp
  350. );
  351. wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
  352. SetDlgItemText(
  353. hDlg,
  354. PXPLODE_IMAGE_WRITECOPY,
  355. szTemp
  356. );
  357. wsprintf(szTemp,"%d Kb",
  358. (CommitVector[EXECUTE] +
  359. CommitVector[EXECUTEREAD] +
  360. CommitVector[EXECUTEREADWRITE] +
  361. CommitVector[EXECUTEWRITECOPY])/1024);
  362. SetDlgItemText(
  363. hDlg,
  364. PXPLODE_IMAGE_EXECUTE,
  365. szTemp
  366. );
  367. }
  368. VOID
  369. DumpMappedCommit(
  370. HWND hDlg,
  371. PULONG_PTR CommitVector
  372. )
  373. {
  374. SIZE_T TotalCommitCount;
  375. ULONG i;
  376. CHAR szTemp[80];
  377. TotalCommitCount = 0;
  378. for ( i=0;i<MAXPROTECT;i++){
  379. TotalCommitCount += CommitVector[i];
  380. }
  381. wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
  382. SetDlgItemText(
  383. hDlg,
  384. PXPLODE_TOTALMAPPED_COMMIT,
  385. szTemp
  386. );
  387. wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
  388. SetDlgItemText(
  389. hDlg,
  390. PXPLODE_MAPPED_NOACCESS,
  391. szTemp
  392. );
  393. wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
  394. SetDlgItemText(
  395. hDlg,
  396. PXPLODE_MAPPED_READONLY,
  397. szTemp
  398. );
  399. wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
  400. SetDlgItemText(
  401. hDlg,
  402. PXPLODE_MAPPED_READWRITE,
  403. szTemp
  404. );
  405. wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
  406. SetDlgItemText(
  407. hDlg,
  408. PXPLODE_MAPPED_WRITECOPY,
  409. szTemp
  410. );
  411. wsprintf(szTemp,"%d Kb",
  412. (CommitVector[EXECUTE] +
  413. CommitVector[EXECUTEREAD] +
  414. CommitVector[EXECUTEREADWRITE] +
  415. CommitVector[EXECUTEWRITECOPY])/1024);
  416. SetDlgItemText(
  417. hDlg,
  418. PXPLODE_MAPPED_EXECUTE,
  419. szTemp
  420. );
  421. }
  422. VOID
  423. DumpPrivateCommit(
  424. HWND hDlg,
  425. PULONG_PTR CommitVector
  426. )
  427. {
  428. SIZE_T TotalCommitCount;
  429. ULONG i;
  430. CHAR szTemp[80];
  431. TotalCommitCount = 0;
  432. for ( i=0;i<MAXPROTECT;i++){
  433. TotalCommitCount += CommitVector[i];
  434. }
  435. wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
  436. SetDlgItemText(
  437. hDlg,
  438. PXPLODE_TOTALPRIVATE_COMMIT,
  439. szTemp
  440. );
  441. wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
  442. SetDlgItemText(
  443. hDlg,
  444. PXPLODE_PRIVATE_NOACCESS,
  445. szTemp
  446. );
  447. wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
  448. SetDlgItemText(
  449. hDlg,
  450. PXPLODE_PRIVATE_READONLY,
  451. szTemp
  452. );
  453. wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
  454. SetDlgItemText(
  455. hDlg,
  456. PXPLODE_PRIVATE_READWRITE,
  457. szTemp
  458. );
  459. wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
  460. SetDlgItemText(
  461. hDlg,
  462. PXPLODE_PRIVATE_WRITECOPY,
  463. szTemp
  464. );
  465. wsprintf(szTemp,"%d Kb",
  466. (CommitVector[EXECUTE] +
  467. CommitVector[EXECUTEREAD] +
  468. CommitVector[EXECUTEREADWRITE] +
  469. CommitVector[EXECUTEWRITECOPY])/1024);
  470. SetDlgItemText(
  471. hDlg,
  472. PXPLODE_PRIVATE_EXECUTE,
  473. szTemp
  474. );
  475. }
  476. VOID
  477. CaptureVaSpace(
  478. IN HANDLE Process
  479. )
  480. {
  481. NTSTATUS Status;
  482. PVOID BaseAddress;
  483. PVAINFO VaInfo;
  484. PMODINFO Mod;
  485. ULONG_PTR SystemRangeStart;
  486. Status = NtQuerySystemInformation(SystemRangeStartInformation,
  487. &SystemRangeStart,
  488. sizeof(SystemRangeStart),
  489. NULL);
  490. if (!NT_SUCCESS(Status)) {
  491. return;
  492. }
  493. BaseAddress = NULL;
  494. LastAllocationBase = NULL;
  495. InitializeListHead(&VaList);
  496. VaInfo = LocalAlloc(LMEM_ZEROINIT,sizeof(*VaInfo));
  497. while ( (ULONG_PTR)BaseAddress < SystemRangeStart ) {
  498. Status = NtQueryVirtualMemory(
  499. Process,
  500. BaseAddress,
  501. MemoryBasicInformation,
  502. &VaInfo->BasicInfo,
  503. sizeof(VaInfo->BasicInfo),
  504. NULL
  505. );
  506. if ( !NT_SUCCESS(Status) ) {
  507. LocalFree(VaInfo);
  508. return;
  509. }
  510. else {
  511. switch (VaInfo->BasicInfo.State ) {
  512. case MEM_COMMIT :
  513. if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) {
  514. TotalModInfo.CommitVector[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize;
  515. Mod = LocateModInfo(BaseAddress);
  516. if ( Mod ) {
  517. Mod->CommitVector[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize;
  518. }
  519. }
  520. else {
  521. if ( VaInfo->BasicInfo.Type == MEM_MAPPED ) {
  522. MappedCommit[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize;
  523. }
  524. else {
  525. PrivateCommit[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize;
  526. }
  527. }
  528. break;
  529. case MEM_RESERVE :
  530. if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) {
  531. ImageReservedBytes += VaInfo->BasicInfo.RegionSize;
  532. }
  533. else {
  534. ReservedBytes += VaInfo->BasicInfo.RegionSize;
  535. }
  536. break;
  537. case MEM_FREE :
  538. if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) {
  539. ImageFreeBytes += VaInfo->BasicInfo.RegionSize;
  540. }
  541. else {
  542. FreeBytes += VaInfo->BasicInfo.RegionSize;
  543. }
  544. break;
  545. }
  546. BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + VaInfo->BasicInfo.RegionSize);
  547. }
  548. }
  549. }
  550. BOOL
  551. ComputeVaSpace(
  552. HWND hDlg,
  553. HANDLE hProcess
  554. )
  555. {
  556. memset(TotalModInfo.CommitVector,0,sizeof(TotalModInfo.CommitVector));
  557. memset(MappedCommit,0,sizeof(MappedCommit));
  558. memset(PrivateCommit,0,sizeof(PrivateCommit));
  559. ComputeModInfo(hDlg,hProcess);
  560. if ( hProcess) {
  561. CaptureVaSpace(hProcess);
  562. }
  563. DumpImageCommit(hDlg,&TotalModInfo.CommitVector[0]);
  564. DumpMappedCommit(hDlg,MappedCommit);
  565. DumpPrivateCommit(hDlg,PrivateCommit);
  566. return TRUE;
  567. }
  568. VOID
  569. UpdateImageCommit(
  570. HWND hDlg
  571. )
  572. {
  573. HWND ComboList;
  574. int nIndex;
  575. PMODINFO ModInfo;
  576. ComboList = GetDlgItem(hDlg, PXPLODE_IMAGE_COMMIT);
  577. nIndex = (int)SendMessage(ComboList, CB_GETCURSEL, 0, 0);
  578. ModInfo = (PMODINFO)SendMessage(
  579. ComboList,
  580. CB_GETITEMDATA,
  581. nIndex,
  582. 0
  583. );
  584. if ( ModInfo ) {
  585. DumpImageCommit(hDlg,&ModInfo->CommitVector[0]);
  586. }
  587. }