Windows NT 4.0 source code leak
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.

245 lines
5.9 KiB

4 years ago
  1. #include <string.h>
  2. #include <xxsetjmp.h>
  3. #include "ntsdp.h"
  4. #include "ntreg.h"
  5. #include <ntos.h>
  6. #define PMMPTE ULONG
  7. #define PDE_BASE ((ULONG)0xC0300000)
  8. #define PTE_BASE ((ULONG)0xC0000000)
  9. #define PDE_TOP 0xC03FFFFF
  10. #define MM_PTE_PROTOTYPE_MASK 0x400
  11. #define MM_PTE_TRANSITION_MASK 0x800
  12. #define MiGetPdeAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE))
  13. #define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))
  14. NTSTATUS TaskGate2TrapFrame(USHORT TaskRegister, PKTRAP_FRAME TrapFrame, PULONG off)
  15. /**
  16. Reads the requested task gate and returns it as a trap frame
  17. structure
  18. **/
  19. {
  20. DESCRIPTOR_TABLE_ENTRY desc;
  21. NTSTATUS status;
  22. ULONG bytesread;
  23. struct { // intel's TSS format
  24. ULONG r1[8];
  25. ULONG Eip;
  26. ULONG EFlags;
  27. ULONG Eax;
  28. ULONG Ecx;
  29. ULONG Edx;
  30. ULONG Ebx;
  31. ULONG Esp;
  32. ULONG Ebp;
  33. ULONG Esi;
  34. ULONG Edi;
  35. ULONG Es;
  36. ULONG Cs;
  37. ULONG Ss;
  38. ULONG Ds;
  39. ULONG Fs;
  40. ULONG Gs;
  41. } TaskState;
  42. //
  43. // Lookup task register
  44. //
  45. desc.Selector = TaskRegister;
  46. status = DbgKdLookupSelector(NtsdCurrentProcessor, &desc);
  47. if (status != STATUS_SUCCESS) {
  48. return status;
  49. }
  50. if (desc.Descriptor.HighWord.Bits.Type != 9 &&
  51. desc.Descriptor.HighWord.Bits.Type != 0xb) {
  52. // not a 32bit task descriptor
  53. return(STATUS_UNSUCCESSFUL);
  54. }
  55. //
  56. // Read in Task State Segment
  57. //
  58. *off = ((ULONG)desc.Descriptor.BaseLow +
  59. ((ULONG)desc.Descriptor.HighWord.Bytes.BaseMid << 16) +
  60. ((ULONG)desc.Descriptor.HighWord.Bytes.BaseHi << 24) );
  61. status = DbgKdReadVirtualMemory (
  62. (PVOID) *off,
  63. &TaskState,
  64. sizeof (TaskState),
  65. &bytesread);
  66. if (bytesread != sizeof(TaskState)) {
  67. return(STATUS_UNSUCCESSFUL);
  68. }
  69. //
  70. // Move fields from Task State Segment to TrapFrame
  71. //
  72. TrapFrame->Eip = TaskState.Eip;
  73. TrapFrame->EFlags = TaskState.EFlags;
  74. TrapFrame->Eax = TaskState.Eax;
  75. TrapFrame->Ecx = TaskState.Ecx;
  76. TrapFrame->Edx = TaskState.Edx;
  77. TrapFrame->Ebx = TaskState.Ebx;
  78. TrapFrame->Ebp = TaskState.Ebp;
  79. TrapFrame->Esi = TaskState.Esi;
  80. TrapFrame->Edi = TaskState.Edi;
  81. TrapFrame->SegEs = TaskState.Es;
  82. TrapFrame->SegCs = TaskState.Cs;
  83. TrapFrame->SegDs = TaskState.Ds;
  84. TrapFrame->SegFs = TaskState.Fs;
  85. TrapFrame->SegGs = TaskState.Gs;
  86. TrapFrame->HardwareEsp = TaskState.Esp;
  87. TrapFrame->HardwareSegSs = TaskState.Ss;
  88. return status;
  89. }
  90. NTSTATUS ReadTrapFrame (
  91. IN ULONG VirtualAddress,
  92. OUT PKTRAP_FRAME TrapFrame
  93. )
  94. {
  95. ULONG bytesread;
  96. NTSTATUS status;
  97. status = DbgKdReadVirtualMemory (
  98. (PVOID)VirtualAddress,
  99. TrapFrame,
  100. sizeof (*TrapFrame),
  101. &bytesread );
  102. if (!NT_SUCCESS(status))
  103. return status;
  104. if (bytesread < sizeof(*TrapFrame)) {
  105. if (bytesread < sizeof(*TrapFrame) - 20) {
  106. //
  107. // shorter then the smallest possible frame type
  108. //
  109. return(STATUS_UNSUCCESSFUL);
  110. }
  111. if ((TrapFrame->SegCs & 1) && bytesread < sizeof(*TrapFrame) - 16 ) {
  112. //
  113. // too small for inter-ring frame
  114. //
  115. return(STATUS_UNSUCCESSFUL);
  116. }
  117. if (TrapFrame->EFlags & EFLAGS_V86_MASK) {
  118. //
  119. // too small for V86 frame
  120. //
  121. return(STATUS_UNSUCCESSFUL);
  122. }
  123. }
  124. return STATUS_SUCCESS;
  125. }
  126. BOOLEAN KdConvertToPhysicalAddr (
  127. IN PVOID uAddress,
  128. OUT PPHYSICAL_ADDRESS PhysicalAddress
  129. )
  130. /*++
  131. Routine Description:
  132. Convert a virtual address to a physical one.
  133. Note: that this function is called from within the virtual memory
  134. cache code. This function can read from the virtual memory cache
  135. so long as it only read's PDE's and PTE's and so long as it fails
  136. to convert a PDE or PTE virtual address.
  137. Arguments:
  138. uAddress - address to convert
  139. PhysicalAddress - returned physical address
  140. Return Value:
  141. TRUE - physical address was returned
  142. otherwise, FALSE
  143. --*/
  144. {
  145. ULONG Address;
  146. PMMPTE Pte;
  147. PMMPTE Pde;
  148. ULONG PdeContents;
  149. ULONG PteContents;
  150. NTSTATUS status;
  151. ULONG result;
  152. Address = (ULONG) uAddress;
  153. if (Address >= PTE_BASE && Address < PDE_TOP) {
  154. //
  155. // The address is the address of a PTE, rather than
  156. // a virtual address. DO NOT CONVERT IT.
  157. //
  158. return FALSE;
  159. }
  160. Pde = MiGetPdeAddress (Address);
  161. Pte = MiGetPteAddress (Address);
  162. status = DbgKdReadVirtualMemory((PVOID)Pde,
  163. &PdeContents,
  164. sizeof(ULONG),
  165. &result);
  166. if ((status != STATUS_SUCCESS) || (result < sizeof(ULONG))) {
  167. return FALSE;
  168. }
  169. if (!(PdeContents & 0x1)) {
  170. return FALSE;
  171. }
  172. status = DbgKdReadVirtualMemory((PVOID)Pte,
  173. &PteContents,
  174. sizeof(ULONG),
  175. &result);
  176. if ((status != STATUS_SUCCESS) || (result < sizeof(ULONG))) {
  177. return FALSE;
  178. }
  179. if (!(PteContents & 0x1)) {
  180. if ( (PteContents & MM_PTE_PROTOTYPE_MASK) ||
  181. !(PteContents & MM_PTE_TRANSITION_MASK)) {
  182. return FALSE;
  183. }
  184. }
  185. //
  186. // This is a page which is either present or in transition.
  187. // Return the physical address for the request virtual address.
  188. //
  189. PhysicalAddress->LowPart = (PteContents & ~(0xFFF)) | (Address & 0xFFF);
  190. PhysicalAddress->HighPart = 0;
  191. return TRUE;
  192. }