1 /* 2 * PROJECT: ReactOS NT User Mode Library 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Verifier support routines 5 * COPYRIGHT: Copyright 2011 Aleksey Bragin (aleksey@reactos.org) 6 * Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 7 */ 8 9 10 #include <ntdll.h> 11 #include <reactos/verifier.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; 17 ULONG AVrfpVerifierFlags = 0; 18 WCHAR AVrfpVerifierDllsString[256] = { 0 }; 19 ULONG AVrfpDebug = 0; 20 BOOL AVrfpInitialized = FALSE; 21 RTL_CRITICAL_SECTION AVrfpVerifierLock; 22 LIST_ENTRY AVrfpVerifierProvidersList; 23 24 #define VERIFIER_DLL_FLAGS_RESOLVED 1 25 26 27 typedef struct _VERIFIER_PROVIDER 28 { 29 LIST_ENTRY ListEntry; 30 UNICODE_STRING DllName; 31 PVOID BaseAddress; 32 PVOID EntryPoint; 33 34 // Provider data 35 PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls; 36 RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback; 37 RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback; 38 RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback; 39 } VERIFIER_PROVIDER, *PVERIFIER_PROVIDER; 40 41 42 43 44 VOID 45 NTAPI 46 AVrfReadIFEO(HANDLE KeyHandle) 47 { 48 NTSTATUS Status; 49 50 Status = LdrQueryImageFileKeyOption(KeyHandle, 51 L"VerifierDlls", 52 REG_SZ, 53 AVrfpVerifierDllsString, 54 sizeof(AVrfpVerifierDllsString) - sizeof(WCHAR), 55 NULL); 56 57 if (!NT_SUCCESS(Status)) 58 AVrfpVerifierDllsString[0] = UNICODE_NULL; 59 60 Status = LdrQueryImageFileKeyOption(KeyHandle, 61 L"VerifierFlags", 62 REG_DWORD, 63 &AVrfpVerifierFlags, 64 sizeof(AVrfpVerifierFlags), 65 NULL); 66 if (!NT_SUCCESS(Status)) 67 AVrfpVerifierFlags = RTL_VRF_FLG_HANDLE_CHECKS | RTL_VRF_FLG_FAST_FILL_HEAP | RTL_VRF_FLG_LOCK_CHECKS; 68 69 Status = LdrQueryImageFileKeyOption(KeyHandle, 70 L"VerifierDebug", 71 REG_DWORD, 72 &AVrfpDebug, 73 sizeof(AVrfpDebug), 74 NULL); 75 if (!NT_SUCCESS(Status)) 76 AVrfpDebug = 0; 77 } 78 79 80 NTSTATUS 81 NTAPI 82 LdrpInitializeApplicationVerifierPackage(HANDLE KeyHandle, PPEB Peb, BOOLEAN SystemWide, BOOLEAN ReadAdvancedOptions) 83 { 84 /* If global flags request DPH, perform some additional actions */ 85 if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) 86 { 87 // TODO: Read advanced DPH flags from the registry if requested 88 if (ReadAdvancedOptions) 89 { 90 UNIMPLEMENTED; 91 } 92 93 /* Enable page heap */ 94 RtlpPageHeapEnabled = TRUE; 95 } 96 97 AVrfReadIFEO(KeyHandle); 98 99 return STATUS_SUCCESS; 100 } 101 102 BOOLEAN 103 AVrfpIsVerifierProviderDll(PVOID BaseAddress) 104 { 105 PLIST_ENTRY Entry; 106 PVERIFIER_PROVIDER Provider; 107 108 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 109 { 110 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 111 112 if (BaseAddress == Provider->BaseAddress) 113 return TRUE; 114 } 115 116 return FALSE; 117 } 118 119 SIZE_T 120 AVrfpCountThunks(PIMAGE_THUNK_DATA Thunk) 121 { 122 SIZE_T Count = 0; 123 while (Thunk[Count].u1.Function) 124 Count++; 125 return Count; 126 } 127 128 VOID 129 AVrfpSnapDllImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry) 130 { 131 ULONG Size; 132 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; 133 PBYTE DllBase = LdrEntry->DllBase; 134 135 ImportDescriptor = RtlImageDirectoryEntryToData(DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size); 136 if (!ImportDescriptor) 137 { 138 //SHIMENG_INFO("Skipping module 0x%p \"%wZ\" due to no iat found\n", LdrEntry->DllBase, &LdrEntry->BaseDllName); 139 return; 140 } 141 142 for (; ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk; ImportDescriptor++) 143 { 144 PIMAGE_THUNK_DATA FirstThunk; 145 PVOID UnprotectedPtr = NULL; 146 SIZE_T UnprotectedSize = 0; 147 ULONG OldProtection = 0; 148 FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk); 149 150 /* Walk all imports */ 151 for (;FirstThunk->u1.Function; FirstThunk++) 152 { 153 PLIST_ENTRY Entry; 154 PVERIFIER_PROVIDER Provider; 155 156 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 157 { 158 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 159 160 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 161 for (DllDescriptor = Provider->ProviderDlls; DllDescriptor && DllDescriptor->DllName; ++DllDescriptor) 162 { 163 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 164 165 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor && ThunkDescriptor->ThunkName; ++ThunkDescriptor) 166 { 167 /* Just compare function addresses, the loader will have handled forwarders and ordinals for us */ 168 if ((PVOID)FirstThunk->u1.Function != ThunkDescriptor->ThunkOldAddress) 169 continue; 170 171 if (!UnprotectedPtr) 172 { 173 PVOID Ptr = &FirstThunk->u1.Function; 174 SIZE_T Size = sizeof(FirstThunk->u1.Function) * AVrfpCountThunks(FirstThunk); 175 NTSTATUS Status; 176 177 UnprotectedPtr = Ptr; 178 UnprotectedSize = Size; 179 180 Status = NtProtectVirtualMemory(NtCurrentProcess(), 181 &Ptr, 182 &Size, 183 PAGE_EXECUTE_READWRITE, 184 &OldProtection); 185 186 if (!NT_SUCCESS(Status)) 187 { 188 DbgPrint("AVRF: Unable to unprotect IAT to modify thunks (status %08X).\n", Status); 189 UnprotectedPtr = NULL; 190 continue; 191 } 192 } 193 194 if (ThunkDescriptor->ThunkNewAddress == NULL) 195 { 196 DbgPrint("AVRF: internal error: New thunk for %s is null.\n", ThunkDescriptor->ThunkName); 197 continue; 198 } 199 FirstThunk->u1.Function = (SIZE_T)ThunkDescriptor->ThunkNewAddress; 200 if (AVrfpDebug & RTL_VRF_DBG_SHOWSNAPS) 201 DbgPrint("AVRF: Snapped (%wZ: %s) with (%wZ: %p).\n", 202 &LdrEntry->BaseDllName, 203 ThunkDescriptor->ThunkName, 204 &Provider->DllName, 205 ThunkDescriptor->ThunkNewAddress); 206 } 207 } 208 } 209 } 210 211 if (UnprotectedPtr) 212 { 213 PVOID Ptr = UnprotectedPtr; 214 SIZE_T Size = UnprotectedSize; 215 NTSTATUS Status; 216 217 UnprotectedPtr = Ptr; 218 UnprotectedSize = Size; 219 220 Status = NtProtectVirtualMemory(NtCurrentProcess(), 221 &Ptr, 222 &Size, 223 OldProtection, 224 &OldProtection); 225 if (!NT_SUCCESS(Status)) 226 { 227 DbgPrint("AVRF: Unable to reprotect IAT to modify thunks (status %08X).\n", Status); 228 } 229 } 230 } 231 } 232 233 234 VOID 235 AvrfpResolveThunks(IN PLDR_DATA_TABLE_ENTRY LdrEntry) 236 { 237 PLIST_ENTRY Entry; 238 PVERIFIER_PROVIDER Provider; 239 240 if (!AVrfpInitialized) 241 return; 242 243 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 244 { 245 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 246 247 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 248 249 for (DllDescriptor = Provider->ProviderDlls; DllDescriptor && DllDescriptor->DllName; ++DllDescriptor) 250 { 251 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 252 253 if ((DllDescriptor->DllFlags & VERIFIER_DLL_FLAGS_RESOLVED) || 254 _wcsicmp(DllDescriptor->DllName, LdrEntry->BaseDllName.Buffer)) 255 continue; 256 257 if (AVrfpDebug & RTL_VRF_DBG_SHOWVERIFIEDEXPORTS) 258 DbgPrint("AVRF: pid 0x%X: found dll descriptor for `%wZ' with verified exports\n", 259 NtCurrentTeb()->ClientId.UniqueProcess, 260 &LdrEntry->BaseDllName); 261 262 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor && ThunkDescriptor->ThunkName; ++ThunkDescriptor) 263 { 264 if (!ThunkDescriptor->ThunkOldAddress) 265 { 266 ANSI_STRING ThunkName; 267 268 RtlInitAnsiString(&ThunkName, ThunkDescriptor->ThunkName); 269 /* We cannot call the public api, because that would run init routines! */ 270 if (NT_SUCCESS(LdrpGetProcedureAddress(LdrEntry->DllBase, &ThunkName, 0, &ThunkDescriptor->ThunkOldAddress, FALSE))) 271 { 272 if (AVrfpDebug & RTL_VRF_DBG_SHOWFOUNDEXPORTS) 273 DbgPrint("AVRF: (%wZ) %Z export found.\n", &LdrEntry->BaseDllName, &ThunkName); 274 } 275 else 276 { 277 if (AVrfpDebug & RTL_VRF_DBG_SHOWFOUNDEXPORTS) 278 DbgPrint("AVRF: warning: did not find `%Z' export in %wZ.\n", &ThunkName, &LdrEntry->BaseDllName); 279 } 280 } 281 } 282 283 DllDescriptor->DllFlags |= VERIFIER_DLL_FLAGS_RESOLVED; 284 } 285 } 286 287 AVrfpSnapDllImports(LdrEntry); 288 } 289 290 291 292 VOID 293 NTAPI 294 AVrfDllLoadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry) 295 { 296 PLIST_ENTRY Entry; 297 298 if (!(NtCurrentPeb()->NtGlobalFlag & FLG_APPLICATION_VERIFIER)) 299 return; 300 301 RtlEnterCriticalSection(&AVrfpVerifierLock); 302 if (!AVrfpIsVerifierProviderDll(LdrEntry->DllBase)) 303 { 304 AvrfpResolveThunks(LdrEntry); 305 306 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 307 { 308 PVERIFIER_PROVIDER Provider; 309 RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback; 310 311 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 312 313 ProviderDllLoadCallback = Provider->ProviderDllLoadCallback; 314 if (ProviderDllLoadCallback) 315 { 316 ProviderDllLoadCallback(LdrEntry->BaseDllName.Buffer, 317 LdrEntry->DllBase, 318 LdrEntry->SizeOfImage, 319 LdrEntry); 320 } 321 } 322 } 323 RtlLeaveCriticalSection(&AVrfpVerifierLock); 324 } 325 326 VOID 327 NTAPI 328 AVrfDllUnloadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry) 329 { 330 PLIST_ENTRY Entry; 331 332 if (!(NtCurrentPeb()->NtGlobalFlag & FLG_APPLICATION_VERIFIER)) 333 return; 334 335 RtlEnterCriticalSection(&AVrfpVerifierLock); 336 if (!AVrfpIsVerifierProviderDll(LdrEntry->DllBase)) 337 { 338 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 339 { 340 PVERIFIER_PROVIDER Provider; 341 RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback; 342 343 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 344 345 ProviderDllUnloadCallback = Provider->ProviderDllUnloadCallback; 346 if (ProviderDllUnloadCallback) 347 { 348 ProviderDllUnloadCallback(LdrEntry->BaseDllName.Buffer, 349 LdrEntry->DllBase, 350 LdrEntry->SizeOfImage, 351 LdrEntry); 352 } 353 } 354 } 355 RtlLeaveCriticalSection(&AVrfpVerifierLock); 356 } 357 358 359 VOID 360 NTAPI 361 AVrfPageHeapDllNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry) 362 { 363 /* Check if page heap dll notification is turned on */ 364 if (!(RtlpDphGlobalFlags & DPH_FLAG_DLL_NOTIFY)) 365 return; 366 367 /* We don't support this flag currently */ 368 UNIMPLEMENTED; 369 } 370 371 372 VOID 373 NTAPI 374 AVrfpResnapInitialModules(VOID) 375 { 376 PLIST_ENTRY ListHead, ListEntry; 377 378 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 379 for (ListEntry = ListHead->Flink; ListHead != ListEntry; ListEntry = ListEntry->Flink) 380 { 381 PLDR_DATA_TABLE_ENTRY LdrEntry; 382 383 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 384 385 if (AVrfpIsVerifierProviderDll(LdrEntry->DllBase)) 386 { 387 if (AVrfpDebug & RTL_VRF_DBG_SHOWSNAPS) 388 DbgPrint("AVRF: skipped resnapping provider %wZ ...\n", &LdrEntry->BaseDllName); 389 } 390 else 391 { 392 if (AVrfpDebug & RTL_VRF_DBG_SHOWSNAPS) 393 DbgPrint("AVRF: resnapping %wZ ...\n", &LdrEntry->BaseDllName); 394 395 AvrfpResolveThunks(LdrEntry); 396 } 397 } 398 } 399 400 PVOID 401 NTAPI 402 AvrfpFindDuplicateThunk(PLIST_ENTRY EndEntry, PWCHAR DllName, PCHAR ThunkName) 403 { 404 PLIST_ENTRY Entry; 405 406 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != EndEntry; Entry = Entry->Flink) 407 { 408 PVERIFIER_PROVIDER Provider; 409 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 410 411 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 412 413 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING_DEBUG) 414 DbgPrint("AVRF: chain: searching in %wZ\n", &Provider->DllName); 415 416 for (DllDescriptor = Provider->ProviderDlls; DllDescriptor && DllDescriptor->DllName; ++DllDescriptor) 417 { 418 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 419 420 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING_DEBUG) 421 DbgPrint("AVRF: chain: dll: %ws\n", DllDescriptor->DllName); 422 423 if (_wcsicmp(DllDescriptor->DllName, DllName)) 424 continue; 425 426 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor && ThunkDescriptor->ThunkName; ++ThunkDescriptor) 427 { 428 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING_DEBUG) 429 DbgPrint("AVRF: chain: thunk: %s == %s ?\n", ThunkDescriptor->ThunkName, ThunkName); 430 431 if (!_stricmp(ThunkDescriptor->ThunkName, ThunkName)) 432 { 433 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING_DEBUG) 434 DbgPrint("AVRF: Found duplicate for (%ws: %s) in %wZ\n", 435 DllDescriptor->DllName, ThunkDescriptor->ThunkName, &Provider->DllName); 436 437 return ThunkDescriptor->ThunkNewAddress; 438 } 439 } 440 } 441 } 442 return NULL; 443 } 444 445 446 VOID 447 NTAPI 448 AVrfpChainDuplicateThunks(VOID) 449 { 450 PLIST_ENTRY Entry; 451 PVERIFIER_PROVIDER Provider; 452 453 for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) 454 { 455 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 456 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 457 458 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 459 460 for (DllDescriptor = Provider->ProviderDlls; DllDescriptor && DllDescriptor->DllName; ++DllDescriptor) 461 { 462 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor && ThunkDescriptor->ThunkName; ++ThunkDescriptor) 463 { 464 PVOID Ptr; 465 466 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING_DEBUG) 467 DbgPrint("AVRF: Checking %wZ for duplicate (%ws: %s)\n", 468 &Provider->DllName, DllDescriptor->DllName, ThunkDescriptor->ThunkName); 469 470 Ptr = AvrfpFindDuplicateThunk(Entry, DllDescriptor->DllName, ThunkDescriptor->ThunkName); 471 if (Ptr) 472 { 473 if (AVrfpDebug & RTL_VRF_DBG_SHOWCHAINING) 474 DbgPrint("AVRF: Chaining (%ws: %s) to %wZ\n", DllDescriptor->DllName, ThunkDescriptor->ThunkName, &Provider->DllName); 475 476 ThunkDescriptor->ThunkOldAddress = Ptr; 477 } 478 } 479 } 480 } 481 } 482 483 NTSTATUS 484 NTAPI 485 AVrfpLoadAndInitializeProvider(PVERIFIER_PROVIDER Provider) 486 { 487 WCHAR StringBuffer[MAX_PATH + 11]; 488 UNICODE_STRING DllPath; 489 PRTL_VERIFIER_PROVIDER_DESCRIPTOR Descriptor; 490 PIMAGE_NT_HEADERS ImageNtHeader; 491 NTSTATUS Status; 492 493 RtlInitEmptyUnicodeString(&DllPath, StringBuffer, sizeof(StringBuffer)); 494 RtlAppendUnicodeToString(&DllPath, SharedUserData->NtSystemRoot); 495 RtlAppendUnicodeToString(&DllPath, L"\\System32\\"); 496 497 if (AVrfpDebug & RTL_VRF_DBG_SHOWSNAPS) 498 DbgPrint("AVRF: verifier dll `%wZ'\n", &Provider->DllName); 499 500 Status = LdrLoadDll(DllPath.Buffer, NULL, &Provider->DllName, &Provider->BaseAddress); 501 if (!NT_SUCCESS(Status)) 502 { 503 DbgPrint("AVRF: %wZ: failed to load provider `%wZ' (status %08X) from %wZ\n", 504 &LdrpImageEntry->BaseDllName, 505 &Provider->DllName, 506 Status, 507 &DllPath); 508 return Status; 509 } 510 511 /* Prevent someone funny from specifying his own application as provider */ 512 ImageNtHeader = RtlImageNtHeader(Provider->BaseAddress); 513 if (!ImageNtHeader || 514 !(ImageNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL)) 515 { 516 DbgPrint("AVRF: provider %wZ is not a DLL image\n", &Provider->DllName); 517 return STATUS_DLL_INIT_FAILED; 518 } 519 520 Provider->EntryPoint = LdrpFetchAddressOfEntryPoint(Provider->BaseAddress); 521 if (!Provider->EntryPoint) 522 { 523 DbgPrint("AVRF: cannot find an entry point for provider %wZ\n", &Provider->DllName); 524 return STATUS_PROCEDURE_NOT_FOUND; 525 } 526 527 _SEH2_TRY 528 { 529 if (LdrpCallInitRoutine(Provider->EntryPoint, 530 Provider->BaseAddress, 531 DLL_PROCESS_VERIFIER, 532 &Descriptor)) 533 { 534 if (Descriptor && Descriptor->Length == sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR)) 535 { 536 /* Copy the data */ 537 Provider->ProviderDlls = Descriptor->ProviderDlls; 538 Provider->ProviderDllLoadCallback = Descriptor->ProviderDllLoadCallback; 539 Provider->ProviderDllUnloadCallback = Descriptor->ProviderDllUnloadCallback; 540 Provider->ProviderNtdllHeapFreeCallback = Descriptor->ProviderNtdllHeapFreeCallback; 541 542 /* Update some info for the provider */ 543 Descriptor->VerifierImage = LdrpImageEntry->BaseDllName.Buffer; 544 Descriptor->VerifierFlags = AVrfpVerifierFlags; 545 Descriptor->VerifierDebug = AVrfpDebug; 546 547 /* We don't have these yet */ 548 DPRINT1("AVRF: RtlpGetStackTraceAddress MISSING\n"); 549 DPRINT1("AVRF: RtlpDebugPageHeapCreate MISSING\n"); 550 DPRINT1("AVRF: RtlpDebugPageHeapDestroy MISSING\n"); 551 Descriptor->RtlpGetStackTraceAddress = NULL; 552 Descriptor->RtlpDebugPageHeapCreate = NULL; 553 Descriptor->RtlpDebugPageHeapDestroy = NULL; 554 Status = STATUS_SUCCESS; 555 } 556 else 557 { 558 DbgPrint("AVRF: provider %wZ passed an invalid descriptor @ %p\n", &Provider->DllName, Descriptor); 559 Status = STATUS_INVALID_PARAMETER_4; 560 } 561 } 562 else 563 { 564 DbgPrint("AVRF: provider %wZ did not initialize correctly\n", &Provider->DllName); 565 Status = STATUS_DLL_INIT_FAILED; 566 } 567 } 568 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 569 { 570 Status = _SEH2_GetExceptionCode(); 571 } 572 _SEH2_END; 573 574 if (!NT_SUCCESS(Status)) 575 return Status; 576 577 578 if (AVrfpDebug & RTL_VRF_DBG_LISTPROVIDERS) 579 DbgPrint("AVRF: initialized provider %wZ (descriptor @ %p)\n", &Provider->DllName, Descriptor); 580 581 /* Done loading providers, allow dll notifications */ 582 AVrfpInitialized = TRUE; 583 584 AVrfpChainDuplicateThunks(); 585 AVrfpResnapInitialModules(); 586 587 /* Manually call with DLL_PROCESS_ATTACH, since the process is not done initializing */ 588 _SEH2_TRY 589 { 590 if (!LdrpCallInitRoutine(Provider->EntryPoint, 591 Provider->BaseAddress, 592 DLL_PROCESS_ATTACH, 593 NULL)) 594 { 595 DbgPrint("AVRF: provider %wZ did not initialize correctly\n", &Provider->DllName); 596 Status = STATUS_DLL_INIT_FAILED; 597 } 598 599 } 600 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 601 { 602 Status = _SEH2_GetExceptionCode(); 603 } 604 _SEH2_END; 605 606 return Status; 607 } 608 609 610 NTSTATUS 611 NTAPI 612 AVrfInitializeVerifier(VOID) 613 { 614 NTSTATUS Status; 615 PVERIFIER_PROVIDER Provider; 616 PLIST_ENTRY Entry; 617 WCHAR* Ptr, *Next; 618 619 Status = RtlInitializeCriticalSection(&AVrfpVerifierLock); 620 InitializeListHead(&AVrfpVerifierProvidersList); 621 622 if (!NT_SUCCESS(Status)) 623 return Status; 624 625 DbgPrint("AVRF: %wZ: pid 0x%X: flags 0x%X: application verifier enabled\n", 626 &LdrpImageEntry->BaseDllName, NtCurrentTeb()->ClientId.UniqueProcess, AVrfpVerifierFlags); 627 628 Provider = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERIFIER_PROVIDER)); 629 if (!Provider) 630 return STATUS_NO_MEMORY; 631 632 RtlInitUnicodeString(&Provider->DllName, L"verifier.dll"); 633 InsertTailList(&AVrfpVerifierProvidersList, &Provider->ListEntry); 634 635 Next = AVrfpVerifierDllsString; 636 637 do 638 { 639 while (*Next == L' ' || *Next == L'\t') 640 Next++; 641 642 Ptr = Next; 643 644 while (*Next != ' ' && *Next != '\t' && *Next) 645 Next++; 646 647 if (*Next) 648 *(Next++) = '\0'; 649 else 650 Next = NULL; 651 652 if (*Ptr) 653 { 654 Provider = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERIFIER_PROVIDER)); 655 if (!Provider) 656 return STATUS_NO_MEMORY; 657 RtlInitUnicodeString(&Provider->DllName, Ptr); 658 InsertTailList(&AVrfpVerifierProvidersList, &Provider->ListEntry); 659 } 660 } while (Next); 661 662 Entry = AVrfpVerifierProvidersList.Flink; 663 while (Entry != &AVrfpVerifierProvidersList) 664 { 665 Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); 666 Entry = Entry->Flink; 667 668 Status = AVrfpLoadAndInitializeProvider(Provider); 669 if (!NT_SUCCESS(Status)) 670 { 671 RemoveEntryList(&Provider->ListEntry); 672 RtlFreeHeap(RtlGetProcessHeap(), 0, Provider); 673 } 674 } 675 676 if (!NT_SUCCESS(Status)) 677 { 678 DbgPrint("AVRF: %wZ: pid 0x%X: application verifier will be disabled due to an initialization error.\n", 679 &LdrpImageEntry->BaseDllName, NtCurrentTeb()->ClientId.UniqueProcess); 680 NtCurrentPeb()->NtGlobalFlag &= ~FLG_APPLICATION_VERIFIER; 681 } 682 683 return Status; 684 } 685 686