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.

201 lines
7.1 KiB

  1. #include "stdinc.h"
  2. #include "lhport.h"
  3. #include "imagehlp.h"
  4. #include "winthrow.h"
  5. #include "fusionbuffer.h"
  6. #include "sxshimlib.h"
  7. #include "fusionhandle.h"
  8. #include <stdio.h>
  9. BOOL
  10. SxspFormatGUID(
  11. IN const GUID &rGuid,
  12. IN OUT F::CBaseStringBuffer &rBuffer
  13. );
  14. //
  15. // Not yet used but I expect either we'll need it, or we'll just not shim msvcrt.dll at all.
  16. // This list is derived from searching public\sdk\inc\crt for "_CRTIMP extern"
  17. //
  18. BOOL
  19. SxpepIsKnownDataSymbol()
  20. {
  21. return FALSE;
  22. }
  23. //
  24. // arg, the implementation but not the declaration of this was removed..
  25. //
  26. #include "yvals.h"
  27. #pragma warning(disable:4663)
  28. #include <vector>
  29. class CMySmallANSIStringBuffer : public std::vector<char>
  30. {
  31. public:
  32. CMySmallANSIStringBuffer() { }
  33. ~CMySmallANSIStringBuffer() { }
  34. void RemoveTrailingNuls()
  35. {
  36. while (this->size() != 0 && this->operator[](this->size() - 1) == 0)
  37. this->resize(size() - 1);
  38. }
  39. BOOL Win32Append(PCSTR s)
  40. {
  41. return this->Win32Append(s, ::strlen(s));
  42. }
  43. BOOL Win32Append(PCSTR s, SIZE_T i)
  44. {
  45. this->RemoveTrailingNuls();
  46. SIZE_T j = this->size();
  47. this->resize(j + i + 1);
  48. CopyMemory(&*begin() + j, s, i);
  49. this->operator[](i + j) = 0;
  50. return TRUE;
  51. }
  52. BOOL Win32Assign(PCSTR s, SIZE_T i)
  53. {
  54. this->clear();
  55. return this->Win32Append(s, i);
  56. }
  57. operator PCSTR()
  58. {
  59. this->EnsureTrailingNul();
  60. return &*begin();
  61. }
  62. void EnsureTrailingNul()
  63. {
  64. if (this->size() == 0 || this->operator[](size() - 1) != 0)
  65. {
  66. this->push_back(0);
  67. }
  68. }
  69. };
  70. BOOL
  71. SxPepApplyShims(
  72. PCSXPE_APPLY_SHIMS_IN in,
  73. SXPE_APPLY_SHIMS_OUT* out
  74. )
  75. {
  76. FN_PROLOG_WIN32
  77. ULONG Size = 0;
  78. PIMAGE_SECTION_HEADER ImportSection = NULL;
  79. PBYTE FromHandle = NULL;
  80. PIMAGE_NT_HEADERS FromNtHeader = NULL;
  81. PCWSTR ToPath = NULL;
  82. PBYTE ImportData = NULL;
  83. DWORD OldImportSectionVirtualProtection = 0;
  84. PCSTR ImportDllName = NULL;
  85. PCSTR* ImportFunctionNames = NULL;
  86. PBYTE* ImportFunctionAddresses = NULL;
  87. CMySmallANSIStringBuffer PrefixedFunctionName;
  88. F::CDynamicLinkLibrary ToHandle;
  89. SIZE_T PrefixLength = 0;
  90. FromHandle = reinterpret_cast<PBYTE>(in->DllToRedirectFrom);
  91. FromNtHeader = ImageNtHeaderOrThrow(FromHandle);
  92. ToPath = in->DllToRedirectTo.Path;
  93. out->DllToRedirectTo.Path = ToPath;
  94. ToHandle = in->DllToRedirectTo.DllHandle;
  95. if (ToHandle == static_cast<HMODULE>(NULL))
  96. {
  97. ToHandle = LoadLibraryWOrThrow(ToPath);
  98. }
  99. out->DllToRedirectTo.DllHandle = ToHandle;
  100. ImportData = reinterpret_cast<PBYTE>(ImageDirectoryEntryToDataExOrThrow(
  101. FromHandle, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size, &ImportSection));
  102. // ImageDirectoryEntryToDataEx almost never returns the ImportSection.
  103. if (ImportSection == NULL)
  104. ImportSection = ImageRvaToSectionOrThrow(FromNtHeader, FromHandle, static_cast<ULONG>(ImportData - FromHandle));
  105. VirtualProtectOrThrow(
  106. FromHandle + ImportSection->VirtualAddress,
  107. ImportSection->Misc.VirtualSize,
  108. PAGE_WRITECOPY,
  109. &OldImportSectionVirtualProtection
  110. );
  111. if (in->Prefix != NULL)
  112. PrefixLength = ::strlen(in->Prefix);
  113. for (
  114. PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(ImportData);
  115. ImportDescriptor->Characteristics != 0 ;
  116. ++ImportDescriptor
  117. )
  118. {
  119. PCSTR ImportDllName = reinterpret_cast<PCSTR>(FromHandle + ImportDescriptor->Name);
  120. printf("%s\n", ImportDllName);
  121. DWORD* ImportFunctionNames = reinterpret_cast<DWORD*>(FromHandle + ImportDescriptor->OriginalFirstThunk);
  122. PVOID* ImportFunctionAddresses = reinterpret_cast<PVOID*>(FromHandle + ImportDescriptor->FirstThunk);
  123. for ( ; *ImportFunctionNames != NULL && *ImportFunctionAddresses != NULL ; ++ImportFunctionNames, ++ImportFunctionAddresses )
  124. {
  125. typedef WORD HINT;
  126. PCSTR NonPrefixedFunctionName = sizeof(HINT) + reinterpret_cast<PCSTR>(FromHandle + *ImportFunctionNames);
  127. PCSTR PossiblyPrefixedFunctionName = NonPrefixedFunctionName;
  128. // we should make this available to the shims, like to enable shim chaining
  129. //PVOID OriginalFunctionAddress = *ImportFunctionAddresses;
  130. if (PrefixLength != 0)
  131. {
  132. IFW32FALSE_EXIT(PrefixedFunctionName.Win32Assign(in->Prefix, PrefixLength));
  133. IFW32FALSE_EXIT(PrefixedFunctionName.Win32Append(NonPrefixedFunctionName));
  134. PossiblyPrefixedFunctionName = PrefixedFunctionName;
  135. }
  136. PVOID NewFunctionAddress = ::GetProcAddress(ToHandle, PossiblyPrefixedFunctionName);
  137. if (NewFunctionAddress == NULL)
  138. {
  139. printf( "%s%s%s%s not shimmed\n",
  140. NonPrefixedFunctionName,
  141. PossiblyPrefixedFunctionName != NonPrefixedFunctionName ? "(" : "",
  142. PossiblyPrefixedFunctionName != NonPrefixedFunctionName ? PossiblyPrefixedFunctionName : "",
  143. PossiblyPrefixedFunctionName != NonPrefixedFunctionName ? ")" : ""
  144. );
  145. }
  146. else
  147. {
  148. PVOID OldAddress = *ImportFunctionAddresses;
  149. printf("%p.%s.%p shimmed to %ls%s%p.%s.%p\n",
  150. in->DllToRedirectFrom,
  151. NonPrefixedFunctionName,
  152. OldAddress,
  153. (ToPath != NULL) ? ToPath : L"",
  154. (ToPath != NULL) ? "." : "",
  155. ToHandle,
  156. PossiblyPrefixedFunctionName,
  157. NewFunctionAddress);
  158. *ImportFunctionAddresses = NewFunctionAddress;
  159. //
  160. // if they have export named <prefix>OriginalFoo, poke
  161. // it with the old address (we include the prefix so that
  162. // chaining might work)
  163. //
  164. IFW32FALSE_EXIT(PrefixedFunctionName.Win32Assign(in->Prefix, PrefixLength));
  165. IFW32FALSE_EXIT(PrefixedFunctionName.Win32Append("Original"));
  166. IFW32FALSE_EXIT(PrefixedFunctionName.Win32Append(NonPrefixedFunctionName));
  167. PVOID* InformOriginalAddress = reinterpret_cast<PVOID*>(::GetProcAddress(ToHandle, PrefixedFunctionName));
  168. if (InformOriginalAddress != NULL)
  169. *InformOriginalAddress = OldAddress;
  170. }
  171. }
  172. }
  173. VirtualProtectOrThrow(
  174. FromHandle + ImportSection->VirtualAddress,
  175. ImportSection->Misc.VirtualSize,
  176. OldImportSectionVirtualProtection,
  177. &OldImportSectionVirtualProtection
  178. );
  179. FN_EPILOG
  180. }