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.

244 lines
4.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. KingsQuestMask.cpp
  5. Abstract:
  6. The app calls UnmapViewOfFile with a bogus address - an address that wasn't obtained
  7. from MapViewOfFile. We validate the address before calling UnmapViewOfFile.
  8. History:
  9. 11/20/2000 maonis Created
  10. --*/
  11. #include "precomp.h"
  12. typedef BOOL (WINAPI *_pfn_UnmapViewOfFile)(LPCVOID lpBaseAddress);
  13. IMPLEMENT_SHIM_BEGIN(KingsQuestMask)
  14. #include "ShimHookMacro.h"
  15. APIHOOK_ENUM_BEGIN
  16. APIHOOK_ENUM_ENTRY(MapViewOfFile)
  17. APIHOOK_ENUM_ENTRY(UnmapViewOfFile)
  18. APIHOOK_ENUM_END
  19. // Link list of base addresses
  20. struct MAPADDRESS
  21. {
  22. MAPADDRESS *next;
  23. LPCVOID pBaseAddress;
  24. };
  25. MAPADDRESS *g_pBaseAddressList;
  26. /*++
  27. Function Description:
  28. Add a base address to the linked list of addresses. Does not add if the
  29. address is NULL or a duplicate.
  30. Arguments:
  31. IN pBaseAddress - base address returned by MapViewOfFile.
  32. Return Value:
  33. None
  34. History:
  35. 11/20/2000 maonis Created
  36. --*/
  37. VOID
  38. AddBaseAddress(
  39. IN LPCVOID pBaseAddress
  40. )
  41. {
  42. if (pBaseAddress)
  43. {
  44. MAPADDRESS *pMapAddress = g_pBaseAddressList;
  45. while (pMapAddress)
  46. {
  47. if (pMapAddress->pBaseAddress == pBaseAddress)
  48. {
  49. return;
  50. }
  51. pMapAddress = pMapAddress->next;
  52. }
  53. pMapAddress = (MAPADDRESS *) malloc(sizeof MAPADDRESS);
  54. pMapAddress->pBaseAddress = pBaseAddress;
  55. pMapAddress->next = g_pBaseAddressList;
  56. g_pBaseAddressList = pMapAddress;
  57. }
  58. }
  59. /*++
  60. Function Description:
  61. Remove a base address if it can be found in the linked list of addresses.
  62. Arguments:
  63. IN pBaseAddress - the base address to remove.
  64. Return Value:
  65. TRUE if the address is found.
  66. FALSE if the address is not found.
  67. History:
  68. 11/20/2000 maonis Created
  69. --*/
  70. BOOL
  71. RemoveBaseAddress(
  72. IN LPCVOID pBaseAddress
  73. )
  74. {
  75. MAPADDRESS *pMapAddress = g_pBaseAddressList;
  76. MAPADDRESS *last = NULL;
  77. while (pMapAddress)
  78. {
  79. if (pMapAddress->pBaseAddress == pBaseAddress)
  80. {
  81. if (last)
  82. {
  83. last->next = pMapAddress->next;
  84. }
  85. else
  86. {
  87. g_pBaseAddressList = pMapAddress->next;
  88. }
  89. free(pMapAddress);
  90. return TRUE;
  91. }
  92. last = pMapAddress;
  93. pMapAddress = pMapAddress->next;
  94. }
  95. return FALSE;
  96. }
  97. /*++
  98. Add the base address to our list.
  99. --*/
  100. LPVOID
  101. APIHOOK(MapViewOfFile)(
  102. HANDLE hFileMappingObject,
  103. DWORD dwDesiredAccess,
  104. DWORD dwFileOffsetHigh,
  105. DWORD dwFileOffsetLow,
  106. SIZE_T dwNumberOfBytesToMap
  107. )
  108. {
  109. LPVOID pRet = ORIGINAL_API(MapViewOfFile)(
  110. hFileMappingObject,
  111. dwDesiredAccess,
  112. dwFileOffsetHigh,
  113. dwFileOffsetLow,
  114. dwNumberOfBytesToMap);
  115. AddBaseAddress(pRet);
  116. DPFN( eDbgLevelInfo, "MapViewOfFile: added base address = 0x%x\n", pRet);
  117. return pRet;
  118. }
  119. /*++
  120. Remove the address from our list if it can be found; otherwise do nothing.
  121. --*/
  122. BOOL
  123. APIHOOK(UnmapViewOfFile)(
  124. LPCVOID lpBaseAddress
  125. )
  126. {
  127. BOOL bRet;
  128. if (RemoveBaseAddress(lpBaseAddress))
  129. {
  130. bRet = ORIGINAL_API(UnmapViewOfFile)(lpBaseAddress);
  131. if (bRet)
  132. {
  133. DPFN( eDbgLevelInfo, "UnmapViewOfFile unmapped address 0x%x\n", lpBaseAddress);
  134. }
  135. return bRet;
  136. }
  137. else
  138. {
  139. DPFN( eDbgLevelError,"UnmapViewOfFile was passed an invalid address 0x%x\n", lpBaseAddress);
  140. return FALSE;
  141. }
  142. }
  143. /*++
  144. Free the list.
  145. --*/
  146. BOOL
  147. NOTIFY_FUNCTION(
  148. DWORD fdwReason)
  149. {
  150. if (fdwReason == DLL_PROCESS_DETACH) {
  151. DWORD dwCount = 0;
  152. MAPADDRESS *pMapAddress = g_pBaseAddressList;
  153. while (pMapAddress)
  154. {
  155. g_pBaseAddressList = pMapAddress->next;
  156. ORIGINAL_API(UnmapViewOfFile)(pMapAddress->pBaseAddress);
  157. free(pMapAddress);
  158. pMapAddress = g_pBaseAddressList;
  159. dwCount++;
  160. }
  161. if (dwCount > 0)
  162. {
  163. DPFN( eDbgLevelInfo,"%d addresses not unmapped.", dwCount);
  164. }
  165. }
  166. return TRUE;
  167. }
  168. /*++
  169. Register hooked functions
  170. --*/
  171. HOOK_BEGIN
  172. APIHOOK_ENTRY(KERNEL32.DLL, MapViewOfFile)
  173. APIHOOK_ENTRY(KERNEL32.DLL, UnmapViewOfFile)
  174. CALL_NOTIFY_FUNCTION
  175. HOOK_END
  176. IMPLEMENT_SHIM_END