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.

291 lines
6.4 KiB

  1. #include "precomp.h"
  2. #include <tlhelp32.h>
  3. #ifndef MYASSERT
  4. #define MYASSERT(x)
  5. #endif
  6. typedef HANDLE (WINAPI * CREATETOOLHELP32SNAPSHOT)(DWORD Flags, DWORD ProcessId);
  7. typedef BOOL (WINAPI * MODULE32FIRST)(HANDLE Snapshot, LPMODULEENTRY32 lpme);
  8. typedef BOOL (WINAPI * MODULE32NEXT)(HANDLE Snapshot, LPMODULEENTRY32 lpme);
  9. BOOL
  10. pIsLegalPage (
  11. IN DWORD Protect
  12. )
  13. {
  14. //
  15. // Page must be actually in memory to protect it, and it
  16. // cannot be any type of write-copy.
  17. //
  18. if ((Protect & PAGE_GUARD) ||
  19. (Protect == PAGE_NOACCESS) ||
  20. (Protect == PAGE_WRITECOPY) ||
  21. (Protect == PAGE_EXECUTE_WRITECOPY)
  22. ) {
  23. return FALSE;
  24. }
  25. return TRUE;
  26. }
  27. BOOL
  28. pIsKnownSection (
  29. IN const IMAGE_SECTION_HEADER *Section,
  30. IN const IMAGE_NT_HEADERS *NtHeaders
  31. )
  32. {
  33. //
  34. // Return TRUE if section is code or code data
  35. //
  36. if (Section->Characteristics & (IMAGE_SCN_MEM_EXECUTE|
  37. IMAGE_SCN_MEM_DISCARDABLE|
  38. IMAGE_SCN_MEM_WRITE|
  39. IMAGE_SCN_MEM_READ)
  40. ) {
  41. return TRUE;
  42. }
  43. //
  44. // Return TRUE if section is resources
  45. //
  46. if (NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress ==
  47. Section->VirtualAddress
  48. ) {
  49. return TRUE;
  50. }
  51. //
  52. // Unknown section
  53. //
  54. return FALSE;
  55. }
  56. VOID
  57. pPutRegionInSwapFile (
  58. IN PVOID Address,
  59. IN DWORD Size
  60. )
  61. {
  62. MEMORY_BASIC_INFORMATION mbi;
  63. DWORD PageSize;
  64. PVOID EndPtr;
  65. PVOID RegionEnd;
  66. DWORD d;
  67. DWORD OldPermissions;
  68. volatile DWORD *v;
  69. SYSTEM_INFO si;
  70. //
  71. // Get system virtual page size
  72. //
  73. GetSystemInfo(&si);
  74. PageSize = si.dwPageSize;
  75. //
  76. // Compute the pointer to the end of the region
  77. //
  78. EndPtr = (PBYTE) Address + Size;
  79. //
  80. // For each page in the region, mark it as e/r/w, modify it, and restore the permissions
  81. //
  82. while (Address < EndPtr) {
  83. d = (DWORD)VirtualQuery (Address, &mbi, sizeof(mbi));
  84. if (d == sizeof(mbi)) {
  85. //
  86. // We assume the module wasn't loaded with one of the following
  87. // conditions (which break as a result of VirtualProtect)
  88. //
  89. RegionEnd = (PBYTE) mbi.BaseAddress + mbi.RegionSize;
  90. if (RegionEnd > EndPtr) {
  91. RegionEnd = EndPtr;
  92. }
  93. if (mbi.State == MEM_COMMIT && pIsLegalPage (mbi.Protect)) {
  94. //
  95. // Switch to e/r/w
  96. //
  97. if (VirtualProtect (
  98. mbi.BaseAddress,
  99. (PBYTE) RegionEnd - (PBYTE) mbi.BaseAddress,
  100. PAGE_EXECUTE_READWRITE,
  101. &OldPermissions
  102. )) {
  103. //
  104. // Touch every page in the region.
  105. //
  106. for (Address = mbi.BaseAddress; Address < RegionEnd ; Address = (PBYTE) Address + PageSize) {
  107. v = Address;
  108. *v = *v;
  109. }
  110. //
  111. // Switch back
  112. //
  113. VirtualProtect (
  114. mbi.BaseAddress,
  115. (PBYTE) RegionEnd - (PBYTE) mbi.BaseAddress,
  116. OldPermissions,
  117. &d
  118. );
  119. }
  120. }
  121. Address = RegionEnd;
  122. } else {
  123. MYASSERT (FALSE);
  124. break;
  125. }
  126. }
  127. }
  128. VOID
  129. pProtectModule (
  130. HANDLE Module
  131. )
  132. {
  133. TCHAR Path[MAX_PATH];
  134. BOOL IsNetDrive;
  135. const IMAGE_DOS_HEADER *DosHeader;
  136. const IMAGE_NT_HEADERS *NtHeaders;
  137. const IMAGE_SECTION_HEADER *SectHeader;
  138. UINT u;
  139. IsNetDrive = FALSE;
  140. //
  141. // Get module info
  142. //
  143. if( MyGetModuleFileName (Module, Path, MAX_PATH)){
  144. //
  145. // Determine if the module is running on the net
  146. //
  147. if (Path[0] == TEXT('\\')) {
  148. IsNetDrive = TRUE;
  149. } else if (GetDriveType (Path) == DRIVE_REMOTE) {
  150. IsNetDrive = TRUE;
  151. }
  152. }
  153. if (!IsNetDrive) {
  154. return;
  155. }
  156. //
  157. // Enumerate all sections in the PE header
  158. //
  159. DosHeader = (const IMAGE_DOS_HEADER *) Module;
  160. NtHeaders = (const IMAGE_NT_HEADERS *) ((PBYTE) Module + DosHeader->e_lfanew);
  161. for (u = 0 ; u < NtHeaders->FileHeader.NumberOfSections ; u++) {
  162. SectHeader = IMAGE_FIRST_SECTION (NtHeaders) + u;
  163. if (pIsKnownSection (SectHeader, NtHeaders)) {
  164. pPutRegionInSwapFile (
  165. (PBYTE) Module + SectHeader->VirtualAddress,
  166. SectHeader->Misc.VirtualSize
  167. );
  168. }
  169. }
  170. }
  171. VOID
  172. ProtectAllModules (
  173. VOID
  174. )
  175. {
  176. HANDLE Library;
  177. HANDLE Snapshot;
  178. MODULEENTRY32 me32;
  179. CREATETOOLHELP32SNAPSHOT fnCreateToolhelp32Snapshot;
  180. MODULE32FIRST fnModule32First;
  181. MODULE32NEXT fnModule32Next;
  182. //
  183. // Load toohelp dynamically (for NT 4, NT 3.51 compatibility)
  184. //
  185. Library = LoadLibrary (TEXT("toolhelp.dll"));
  186. if (!Library) {
  187. return;
  188. }
  189. (FARPROC) fnCreateToolhelp32Snapshot = GetProcAddress (Library, "CreateToolhelp32Snapshot");
  190. (FARPROC) fnModule32First = GetProcAddress (Library, "Module32First");
  191. (FARPROC) fnModule32Next = GetProcAddress (Library, "Module32Next");
  192. if (!fnCreateToolhelp32Snapshot || !fnModule32First || !fnModule32Next) {
  193. FreeLibrary (Library);
  194. return;
  195. }
  196. //
  197. // Protect each loaded module
  198. //
  199. Snapshot = fnCreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
  200. MYASSERT (Snapshot != INVALID_HANDLE_VALUE);
  201. if (Snapshot == INVALID_HANDLE_VALUE) {
  202. return;
  203. }
  204. me32.dwSize = sizeof (me32);
  205. if (fnModule32First (Snapshot, &me32)) {
  206. do {
  207. pProtectModule (me32.hModule);
  208. } while (fnModule32Next (Snapshot, &me32));
  209. }
  210. //
  211. // Done
  212. //
  213. CloseHandle (Snapshot);
  214. FreeLibrary (Library);
  215. }