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.

324 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ptov.c
  5. Abstract:
  6. Kernel debugger extension for dumping all physical to
  7. virtual translations for a given process.
  8. Author:
  9. John Vert (jvert) 25-Jul-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. BOOL
  14. ReadPhysicalPage(
  15. IN ULONG64 PageNumber,
  16. OUT PVOID Buffer
  17. );
  18. DECLARE_API( ptov )
  19. /*++
  20. Routine Description:
  21. Dumps all physical to virtual translations for a given process
  22. Arguments:
  23. args - supplies physical address of PDE
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. ULONG64 PdeAddress=0;
  29. ULONG ActualRead;
  30. PCHAR PageDirectory;
  31. PCHAR PageTable;
  32. ULONG i,j;
  33. ULONG64 VirtualPage=0;
  34. ULONG SizeOfHwPte;
  35. ULONG Flags = 1;
  36. ULONG ValidOff, ValidSize, PfnOff, PfnSz;
  37. HRESULT Hr = S_OK;
  38. if (sscanf(args, "%I64lx %lx", &PdeAddress, &Flags) < 1 || PdeAddress == 0) {
  39. dprintf("usage: ptov PFNOfPDE\n");
  40. return E_INVALIDARG;
  41. }
  42. if (PageSize == 0){
  43. dprintf("Cpuld not get PageSize\n");
  44. return E_INVALIDARG;
  45. }
  46. PageDirectory = LocalAlloc(LMEM_FIXED, PageSize);
  47. if (PageDirectory == NULL) {
  48. dprintf("Couldn't allocate %d bytes for page directory\n",PageSize);
  49. return E_OUTOFMEMORY;
  50. }
  51. PageTable = LocalAlloc(LMEM_FIXED, PageSize);
  52. if (PageTable == NULL) {
  53. dprintf("Couldn't allocate %d bytes for page table\n",PageSize);
  54. LocalFree(PageDirectory);
  55. return E_OUTOFMEMORY;
  56. }
  57. SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE");
  58. GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize);
  59. GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz);
  60. __try {
  61. if (ReadPhysicalPage(PdeAddress,PageDirectory)) {
  62. for (i=0;i<PageSize/SizeOfHwPte;i++) {
  63. ULONG64 thisPageDir;
  64. ULONG64 PageFrameNumber;
  65. if (SizeOfHwPte == 4) {
  66. thisPageDir = *((PULONG)PageDirectory + i);
  67. } else {
  68. thisPageDir = *((PULONG64)PageDirectory + i);
  69. }
  70. if (CheckControlC()) {
  71. Hr = E_ABORT;
  72. __leave;
  73. }
  74. PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz);
  75. if (((thisPageDir >> ValidOff) & 1) &&
  76. ReadPhysicalPage(PageFrameNumber,PageTable)) {
  77. for (j=0;j<PageSize/SizeOfHwPte;j++) {
  78. ULONG64 thisPageTable;
  79. if (SizeOfHwPte == 4) {
  80. thisPageTable = *((PULONG)PageTable + j);
  81. } else {
  82. thisPageTable = *((PULONG64)PageTable + j);
  83. }
  84. if ( CheckControlC() ) {
  85. Hr = E_INVALIDARG;
  86. __leave;
  87. }
  88. if ((thisPageTable >> ValidOff) & 1) {
  89. dprintf("%I64lx %I64lx\n",GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,VirtualPage);
  90. }
  91. VirtualPage+=PageSize;
  92. }
  93. } else {
  94. VirtualPage += PageSize * (PageSize/SizeOfHwPte);
  95. }
  96. }
  97. }
  98. } __finally {
  99. LocalFree(PageDirectory);
  100. LocalFree(PageTable);
  101. }
  102. return Hr;
  103. }
  104. ULONG
  105. DBG_GET_PAGE_SHIFT (
  106. VOID
  107. );
  108. BOOL
  109. ReadPhysicalPage(
  110. IN ULONG64 PageNumber,
  111. OUT PVOID Buffer
  112. )
  113. {
  114. ULONG i;
  115. ULONG64 Address;
  116. //
  117. // do the read 1k at a time to avoid overflowing the packet maximum.
  118. //
  119. Address = PageNumber << DBG_GET_PAGE_SHIFT();
  120. if (!IsPtr64()) {
  121. // Address = (ULONG64) (LONG64) (LONG) Address;
  122. }
  123. // dprintf("Pg no %I64lx shft by %d, PhyAddr %I64lx\n", PageNumber, DBG_GET_PAGE_SHIFT(), Address);
  124. for (i=0; i<PageSize/1024; i++) {
  125. ULONG ActualRead = 0;
  126. ReadPhysical(Address, Buffer, 1024, &ActualRead);
  127. if (ActualRead != 1024) {
  128. dprintf("physical read at %p failed\n",Address);
  129. return(FALSE);
  130. }
  131. Address += 1024;
  132. Buffer = (PVOID)((PUCHAR)Buffer + 1024);
  133. }
  134. return(TRUE);
  135. }
  136. ULONG64
  137. DBG_GET_MM_SESSION_SPACE_DEFAULT (
  138. VOID
  139. );
  140. DECLARE_API( vtop )
  141. /*++
  142. Routine Description:
  143. Dumps the virtual to physical translation for a page
  144. Arguments:
  145. args - supplies physical address of PDE
  146. Return Value:
  147. None.
  148. --*/
  149. {
  150. ULONG ActualRead;
  151. ULONG i,j;
  152. PUCHAR PageDirectory;
  153. PUCHAR PageTable;
  154. ULONG64 PdeAddress = 0;
  155. ULONG64 VirtualPage= 0;//DBG_GET_MM_SESSION_SPACE_DEFAULT();
  156. ULONG PageShift,SizeOfHwPte;
  157. ULONG ValidOff, ValidSize, PfnOff, PfnSz, TransOff, TransSize;
  158. HRESULT Hr;
  159. if (!sscanf(args,"%I64lx %I64lx", &PdeAddress,&VirtualPage)) {
  160. // Do not use GetExpression - physical addresses
  161. // VirtualPage = GetExpression(args);
  162. PdeAddress = 0;
  163. VirtualPage = 0;
  164. }
  165. if (!(SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE")) ) {
  166. dprintf("Cannot find HARDWARE_PTE\n");
  167. return E_INVALIDARG;
  168. }
  169. PageShift = DBG_GET_PAGE_SHIFT();
  170. if ((PdeAddress == 0) && (VirtualPage == 0)) {
  171. dprintf("usage: vtop PFNOfPDE VA\n");
  172. return E_INVALIDARG;
  173. } else if (VirtualPage)
  174. {
  175. ULONG64 Process;
  176. Process = GetExpression("@$proc");
  177. if (GetFieldValue(Process, "nt!_KPROCESS", "DirectoryTableBase[0]", PdeAddress) != S_OK)
  178. {
  179. dprintf("Cannot read DirectoryTableBase for currect process\n");
  180. return E_FAIL;
  181. }
  182. }
  183. // Common mistake, typed in full 32 bit address, not pfn
  184. if( PdeAddress & ~((1 << (32-PageShift)) - 1) ) {
  185. PdeAddress >>= PageShift;
  186. }
  187. PageDirectory = LocalAlloc(LMEM_FIXED, PageSize);
  188. if (PageDirectory == NULL) {
  189. dprintf("Couldn't allocate %d bytes for page directory\n",PageSize);
  190. return E_INVALIDARG;
  191. }
  192. PageTable = LocalAlloc(LMEM_FIXED, PageSize);
  193. if (PageTable == NULL) {
  194. dprintf("Couldn't allocate %d bytes for page table\n",PageSize);
  195. LocalFree(PageDirectory);
  196. return E_INVALIDARG;
  197. }
  198. __try {
  199. i =(ULONG) ( VirtualPage / (PageSize*(PageSize/ SizeOfHwPte)));
  200. j = (ULONG) ((VirtualPage % (PageSize*(PageSize/ SizeOfHwPte))) / PageSize);
  201. dprintf("Pdi %x Pti %x\n",i,j);
  202. GetBitFieldOffset("nt!_MMPTE", "u.Soft.Transition", &TransOff, &TransSize);
  203. GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize);
  204. GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz);
  205. if (ReadPhysicalPage(PdeAddress,PageDirectory)) {
  206. ULONG64 thisPageDir;
  207. if (SizeOfHwPte == 4) {
  208. thisPageDir = *((PULONG)PageDirectory + i);
  209. } else {
  210. thisPageDir = *((PULONG64)PageDirectory + i);
  211. }
  212. if (CheckControlC()) {
  213. Hr = E_INVALIDARG;
  214. __leave;
  215. }
  216. if ((thisPageDir >> ValidOff) & 1) {
  217. ULONG64 PageFrameNumber;
  218. ULONG64 thisPageTable;
  219. PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz);
  220. if (!ReadPhysicalPage(PageFrameNumber,PageTable)) {
  221. Hr = E_INVALIDARG;
  222. __leave;
  223. }
  224. if (SizeOfHwPte == 4) {
  225. thisPageTable = *((PULONG)PageTable + j);
  226. } else {
  227. thisPageTable = *((PULONG64)PageTable + j);
  228. }
  229. if ((thisPageTable >> ValidOff) & 1) {
  230. dprintf("%08I64lx %08I64lx pfn(%05I64lx)\n",
  231. VirtualPage,
  232. GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,
  233. GetBits(thisPageTable, PfnOff, PfnSz)
  234. );
  235. }
  236. else {
  237. if ((thisPageTable >> TransOff) & 1) {
  238. dprintf("%08I64lx Transition %08I64lx (%05I64lx)\n",
  239. VirtualPage,
  240. GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,
  241. GetBits(thisPageTable, PfnOff, PfnSz)
  242. );
  243. }
  244. else {
  245. dprintf("%08I64lx Not present (%p)\n",VirtualPage,thisPageTable);
  246. }
  247. }
  248. }
  249. else {
  250. dprintf("PageDirectory Entry %u not valid, try another process\n",i);
  251. }
  252. }
  253. } __finally {
  254. LocalFree(PageDirectory);
  255. LocalFree(PageTable);
  256. }
  257. return Hr;
  258. }