DelayLoadLibrary.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "CommonCorePch.h"
  6. #include "Core/DelayLoadLibrary.h"
  7. DelayLoadLibrary::DelayLoadLibrary()
  8. {
  9. m_hModule = nullptr;
  10. m_isInit = false;
  11. }
  12. DelayLoadLibrary::~DelayLoadLibrary()
  13. {
  14. if (m_hModule)
  15. {
  16. FreeLibrary(m_hModule);
  17. m_hModule = nullptr;
  18. }
  19. }
  20. void DelayLoadLibrary::Ensure(DWORD dwFlags)
  21. {
  22. if (!m_isInit)
  23. {
  24. m_hModule = LoadLibraryEx(GetLibraryName(), nullptr, dwFlags);
  25. m_isInit = true;
  26. }
  27. }
  28. void DelayLoadLibrary::EnsureFromSystemDirOnly()
  29. {
  30. Ensure(LOAD_LIBRARY_SEARCH_SYSTEM32);
  31. }
  32. FARPROC DelayLoadLibrary::GetFunction(__in LPCSTR lpFunctionName)
  33. {
  34. if (m_hModule)
  35. {
  36. return GetProcAddress(m_hModule, lpFunctionName);
  37. }
  38. return nullptr;
  39. }
  40. bool DelayLoadLibrary::IsAvailable()
  41. {
  42. return m_hModule != nullptr;
  43. }
  44. #if _WIN32
  45. static NtdllLibrary NtdllLibraryObject;
  46. NtdllLibrary* NtdllLibrary::Instance = &NtdllLibraryObject;
  47. LPCTSTR NtdllLibrary::GetLibraryName() const
  48. {
  49. return _u("ntdll.dll");
  50. }
  51. #if PDATA_ENABLED
  52. _Success_(return == 0)
  53. NtdllLibrary::NTSTATUS NtdllLibrary::AddGrowableFunctionTable( _Out_ PVOID * DynamicTable,
  54. _In_reads_(MaximumEntryCount) PRUNTIME_FUNCTION FunctionTable,
  55. _In_ DWORD EntryCount,
  56. _In_ DWORD MaximumEntryCount,
  57. _In_ ULONG_PTR RangeBase,
  58. _In_ ULONG_PTR RangeEnd )
  59. {
  60. Assert(AutoSystemInfo::Data.IsWin8OrLater());
  61. if(m_hModule)
  62. {
  63. if(addGrowableFunctionTable == NULL)
  64. {
  65. addGrowableFunctionTable = (PFnRtlAddGrowableFunctionTable)GetFunction("RtlAddGrowableFunctionTable");
  66. if(addGrowableFunctionTable == NULL)
  67. {
  68. Assert(false);
  69. return 1;
  70. }
  71. }
  72. *DynamicTable = nullptr;
  73. NTSTATUS status = addGrowableFunctionTable(DynamicTable,
  74. FunctionTable,
  75. EntryCount,
  76. MaximumEntryCount,
  77. RangeBase,
  78. RangeEnd);
  79. #if _M_X64
  80. PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("Register: [%d] Begin: %llx, End: %x, Unwind: %llx, RangeBase: %llx, RangeEnd: %llx, table: %llx, Status: %x\n"),
  81. GetCurrentThreadId(), FunctionTable->BeginAddress, FunctionTable->EndAddress, FunctionTable->UnwindInfoAddress, RangeBase, RangeEnd, *DynamicTable, status);
  82. #endif
  83. Assert((status >= 0 && *DynamicTable != nullptr) || status == 0xC000009A /*STATUS_INSUFFICIENT_RESOURCES*/);
  84. return status;
  85. }
  86. return 1;
  87. }
  88. VOID NtdllLibrary::DeleteGrowableFunctionTable( _In_ PVOID DynamicTable )
  89. {
  90. Assert(AutoSystemInfo::Data.IsWin8OrLater());
  91. if(m_hModule)
  92. {
  93. if(deleteGrowableFunctionTable == NULL)
  94. {
  95. deleteGrowableFunctionTable = (PFnRtlDeleteGrowableFunctionTable)GetFunction("RtlDeleteGrowableFunctionTable");
  96. if(deleteGrowableFunctionTable == NULL)
  97. {
  98. Assert(false);
  99. return;
  100. }
  101. }
  102. deleteGrowableFunctionTable(DynamicTable);
  103. PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("UnRegister: [%d] table: %llx\n"), GetCurrentThreadId(), DynamicTable);
  104. }
  105. }
  106. VOID NtdllLibrary::GrowFunctionTable(_Inout_ PVOID DynamicTable, _In_ ULONG NewEntryCount)
  107. {
  108. if (m_hModule)
  109. {
  110. if (growFunctionTable == nullptr)
  111. {
  112. growFunctionTable = (PFnRtlGrowFunctionTable)GetFunction("RtlGrowFunctionTable");
  113. if (growFunctionTable == nullptr)
  114. {
  115. Assert(false);
  116. return;
  117. }
  118. }
  119. growFunctionTable(DynamicTable, NewEntryCount);
  120. }
  121. }
  122. #endif // PDATA_ENABLED
  123. VOID NtdllLibrary::InitializeObjectAttributes(
  124. POBJECT_ATTRIBUTES InitializedAttributes,
  125. PUNICODE_STRING ObjectName,
  126. ULONG Attributes,
  127. HANDLE RootDirectory,
  128. PSECURITY_DESCRIPTOR SecurityDescriptor)
  129. {
  130. InitializedAttributes->Length = sizeof(OBJECT_ATTRIBUTES);
  131. InitializedAttributes->RootDirectory = RootDirectory;
  132. InitializedAttributes->Attributes = Attributes;
  133. InitializedAttributes->ObjectName = ObjectName;
  134. InitializedAttributes->SecurityDescriptor = SecurityDescriptor;
  135. InitializedAttributes->SecurityQualityOfService = NULL;
  136. }
  137. #ifndef DELAYLOAD_SECTIONAPI
  138. extern "C"
  139. WINBASEAPI
  140. NtdllLibrary::NTSTATUS
  141. WINAPI
  142. NtCreateSection(
  143. _Out_ PHANDLE SectionHandle,
  144. _In_ ACCESS_MASK DesiredAccess,
  145. _In_opt_ NtdllLibrary::POBJECT_ATTRIBUTES ObjectAttributes,
  146. _In_opt_ PLARGE_INTEGER MaximumSize,
  147. _In_ ULONG SectionPageProtection,
  148. _In_ ULONG AllocationAttributes,
  149. _In_opt_ HANDLE FileHandle
  150. );
  151. #endif
  152. NtdllLibrary::NTSTATUS NtdllLibrary::CreateSection(
  153. _Out_ PHANDLE SectionHandle,
  154. _In_ ACCESS_MASK DesiredAccess,
  155. _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
  156. _In_opt_ PLARGE_INTEGER MaximumSize,
  157. _In_ ULONG SectionPageProtection,
  158. _In_ ULONG AllocationAttributes,
  159. _In_opt_ HANDLE FileHandle)
  160. {
  161. #ifdef DELAYLOAD_SECTIONAPI
  162. if (m_hModule)
  163. {
  164. if (createSection == nullptr)
  165. {
  166. createSection = (PFnNtCreateSection)GetFunction("NtCreateSection");
  167. if (createSection == nullptr)
  168. {
  169. Assert(false);
  170. SectionHandle = nullptr;
  171. return -1;
  172. }
  173. }
  174. return createSection(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle);
  175. }
  176. SectionHandle = nullptr;
  177. return -1;
  178. #else
  179. return NtCreateSection(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle);
  180. #endif
  181. }
  182. #ifndef DELAYLOAD_SECTIONAPI
  183. extern "C"
  184. WINBASEAPI
  185. NtdllLibrary::NTSTATUS
  186. WINAPI
  187. NtMapViewOfSection(
  188. _In_ HANDLE SectionHandle,
  189. _In_ HANDLE ProcessHandle,
  190. _Inout_ PVOID *BaseAddress,
  191. _In_ ULONG_PTR ZeroBits,
  192. _In_ SIZE_T CommitSize,
  193. _Inout_opt_ PLARGE_INTEGER SectionOffset,
  194. _Inout_ PSIZE_T ViewSize,
  195. _In_ NtdllLibrary::SECTION_INHERIT InheritDisposition,
  196. _In_ ULONG AllocationType,
  197. _In_ ULONG Win32Protect
  198. );
  199. #endif
  200. NtdllLibrary::NTSTATUS NtdllLibrary::MapViewOfSection(
  201. _In_ HANDLE SectionHandle,
  202. _In_ HANDLE ProcessHandle,
  203. _Inout_ PVOID *BaseAddress,
  204. _In_ ULONG_PTR ZeroBits,
  205. _In_ SIZE_T CommitSize,
  206. _Inout_opt_ PLARGE_INTEGER SectionOffset,
  207. _Inout_ PSIZE_T ViewSize,
  208. _In_ SECTION_INHERIT InheritDisposition,
  209. _In_ ULONG AllocationType,
  210. _In_ ULONG Win32Protect)
  211. {
  212. #ifdef DELAYLOAD_SECTIONAPI
  213. if (m_hModule)
  214. {
  215. if (mapViewOfSection == nullptr)
  216. {
  217. mapViewOfSection = (PFnNtMapViewOfSection)GetFunction("NtMapViewOfSection");
  218. if (mapViewOfSection == nullptr)
  219. {
  220. Assert(false);
  221. return -1;
  222. }
  223. }
  224. return mapViewOfSection(SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
  225. }
  226. return -1;
  227. #else
  228. return NtMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
  229. #endif
  230. }
  231. #ifndef DELAYLOAD_SECTIONAPI
  232. extern "C"
  233. WINBASEAPI
  234. NtdllLibrary::NTSTATUS
  235. WINAPI
  236. NtUnmapViewOfSection(
  237. _In_ HANDLE ProcessHandle,
  238. _In_opt_ PVOID BaseAddress
  239. );
  240. #endif
  241. NtdllLibrary::NTSTATUS NtdllLibrary::UnmapViewOfSection(
  242. _In_ HANDLE ProcessHandle,
  243. _In_opt_ PVOID BaseAddress)
  244. {
  245. #ifdef DELAYLOAD_SECTIONAPI
  246. if (m_hModule)
  247. {
  248. if (unmapViewOfSection == nullptr)
  249. {
  250. unmapViewOfSection = (PFnNtUnmapViewOfSection)GetFunction("NtUnmapViewOfSection");
  251. if (unmapViewOfSection == nullptr)
  252. {
  253. Assert(false);
  254. return -1;
  255. }
  256. }
  257. return unmapViewOfSection(ProcessHandle, BaseAddress);
  258. }
  259. return -1;
  260. #else
  261. return NtUnmapViewOfSection(ProcessHandle, BaseAddress);
  262. #endif
  263. }
  264. #ifndef DELAYLOAD_SECTIONAPI
  265. extern "C"
  266. WINBASEAPI
  267. NtdllLibrary::NTSTATUS
  268. WINAPI
  269. NtClose(_In_ HANDLE Handle);
  270. #endif
  271. NtdllLibrary::NTSTATUS NtdllLibrary::Close(_In_ HANDLE Handle)
  272. {
  273. #ifdef DELAYLOAD_SECTIONAPI
  274. if (m_hModule)
  275. {
  276. if (close == nullptr)
  277. {
  278. close = (PFnNtClose)GetFunction("NtClose");
  279. if (close == nullptr)
  280. {
  281. Assert(false);
  282. return -1;
  283. }
  284. }
  285. return close(Handle);
  286. }
  287. return -1;
  288. #else
  289. return NtClose(Handle);
  290. #endif
  291. }
  292. #ifndef DELAYLOAD_UNLOCKMEMORY
  293. extern "C"
  294. WINBASEAPI
  295. NtdllLibrary::NTSTATUS
  296. WINAPI
  297. NtUnlockVirtualMemory(
  298. _In_ HANDLE ProcessHandle,
  299. _Inout_ PVOID *BaseAddress,
  300. _Inout_ PSIZE_T RegionSize,
  301. _In_ ULONG MapType
  302. );
  303. #endif
  304. NtdllLibrary::NTSTATUS NtdllLibrary::UnlockVirtualMemory(
  305. _In_ HANDLE ProcessHandle,
  306. _Inout_ PVOID *BaseAddress,
  307. _Inout_ PSIZE_T RegionSize,
  308. _In_ ULONG MapType)
  309. {
  310. #ifdef DELAYLOAD_UNLOCKMEMORY
  311. if (m_hModule)
  312. {
  313. if (unlock == nullptr)
  314. {
  315. unlock = (PFnNtUnlockVirtualMemory)GetFunction("NtUnlockVirtualMemory");
  316. if (unlock == nullptr)
  317. {
  318. Assert(false);
  319. return -1;
  320. }
  321. }
  322. return unlock(ProcessHandle, BaseAddress, RegionSize, MapType);
  323. }
  324. return -1;
  325. #else
  326. return NtUnlockVirtualMemory(ProcessHandle, BaseAddress, RegionSize, MapType);
  327. #endif
  328. }
  329. #endif // _WIN32