ReactOS 0.4.15-dev-7674-gc0b4db1
shimeng.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Application compatibility module
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Shim engine core
5 * COPYRIGHT: Copyright 2015-2019 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#define WIN32_NO_STATUS
9#include "ntndk.h"
10#define IN_APPHELP
11#include "shimlib.h"
12#include <strsafe.h>
13/* Make sure we don't include apphelp logging */
14#define APPHELP_NOSDBPAPI
15#include "apphelp.h"
16#include "shimeng.h"
17
18
19
22
23static const UNICODE_STRING Ntdll = RTL_CONSTANT_STRING(L"ntdll.dll");
24static const UNICODE_STRING Kernel32 = RTL_CONSTANT_STRING(L"kernel32.dll");
25static const UNICODE_STRING Verifier = RTL_CONSTANT_STRING(L"verifier.dll");
26
27extern HMODULE g_hInstance;
37static ARRAY g_pShimInfo; /* PSHIMMODULE */
38static ARRAY g_pHookArray; /* HOOKMODULEINFO */
39static ARRAY g_InExclude; /* INEXCLUDE */
40
42/* If we have setup a hook for a function, we should also redirect GetProcAddress for this function */
44{
45 {
46 "kernel32.dll", /* LibraryName */
47 "GetProcAddress", /* FunctionName */
48 StubGetProcAddress, /* ReplacementFunction*/
49 NULL, /* OriginalFunction */
50 NULL, /* pShimInfo */
51 NULL /* ApiLink */
52 },
53};
54
56{
57 Array->Data__ = NULL;
58 Array->Size__ = Array->MaxSize__ = 0;
59 Array->ItemSize__ = ItemSize;
60
61 return TRUE;
62}
63
64static inline BOOL ARRAY_EnsureSize(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
65{
66 PVOID pNewData;
68
69 ASSERT(Array);
70 ASSERT(ItemSize == Array->ItemSize__);
71
72 if (Array->MaxSize__ > Array->Size__)
73 return TRUE;
74
75 Count = Array->Size__ + GrowWith;
76 pNewData = SeiAlloc(Count * ItemSize);
77
78 if (!pNewData)
79 {
80 SHIMENG_FAIL("Failed to allocate %d bytes\n", Count * ItemSize);
81 return FALSE;
82 }
83 Array->MaxSize__ = Count;
84
85 if (Array->Data__)
86 {
87 memcpy(pNewData, Array->Data__, Array->Size__ * ItemSize);
88 SeiFree(Array->Data__);
89 }
90 Array->Data__ = pNewData;
91
92 return TRUE;
93}
94
95static inline PVOID ARRAY_AppendWorker(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
96{
98
99 if (!ARRAY_EnsureSize(Array, ItemSize, GrowWith))
100 return NULL;
101
102 pData = Array->Data__;
103 pData += (Array->Size__ * ItemSize);
104 Array->Size__++;
105
106 return pData;
107}
108
110{
111 PBYTE pData;
112
113 ASSERT(Array);
114 ASSERT(ItemSize == Array->ItemSize__);
115 ASSERT(n < Array->Size__);
116
117 pData = Array->Data__;
118 return pData + (n * ItemSize);
119}
120
121
122#define ARRAY_Init(Array, TypeOfArray) ARRAY_InitWorker((Array), sizeof(TypeOfArray))
123#define ARRAY_Append(Array, TypeOfArray) (TypeOfArray*)ARRAY_AppendWorker((Array), sizeof(TypeOfArray), 5)
124#define ARRAY_At(Array, TypeOfArray, at) (TypeOfArray*)ARRAY_AtWorker((Array), sizeof(TypeOfArray), at)
125#define ARRAY_Size(Array) (Array)->Size__
126
127
129{
130 static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIMENG_DEBUG_LEVEL");
131 UNICODE_STRING DebugValue;
133 ULONG NewLevel = SEI_MSG; /* Show some basic info in the logs, unless configured different */
134 WCHAR Buffer[40];
135
136 RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
137
138 Status = RtlQueryEnvironmentVariable_U(NULL, &DebugKey, &DebugValue);
139
140 if (NT_SUCCESS(Status))
141 {
142 if (!NT_SUCCESS(RtlUnicodeStringToInteger(&DebugValue, 10, &NewLevel)))
143 NewLevel = 0;
144 }
145 g_ShimEngDebugLevel = NewLevel;
146}
147
148
161{
162 char Buffer[512];
163 char* Current = Buffer;
164 const char* LevelStr;
165 size_t Length = sizeof(Buffer);
166 va_list ArgList;
167 HRESULT hr;
168
169 if (g_ShimEngDebugLevel == 0xffffffff)
171
173 return FALSE;
174
175 switch (Level)
176 {
177 case SEI_MSG:
178 LevelStr = "MSG ";
179 break;
180 case SEI_FAIL:
181 LevelStr = "FAIL";
182 break;
183 case SEI_WARN:
184 LevelStr = "WARN";
185 break;
186 case SEI_INFO:
187 LevelStr = "INFO";
188 break;
189 default:
190 LevelStr = "USER";
191 break;
192 }
193
194 if (Function)
195 hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] [%s] ", LevelStr, Function);
196 else
197 hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] ", LevelStr);
198
199 if (!SUCCEEDED(hr))
200 return FALSE;
201
202 va_start(ArgList, Format);
203 hr = StringCchVPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, Format, ArgList);
204 va_end(ArgList);
205 if (!SUCCEEDED(hr))
206 return FALSE;
207
208 DbgPrint("%s", Buffer);
209 return TRUE;
210}
211
212static
214{
215 return (ULONG_PTR)lpProcName <= MAXUSHORT;
216}
217
218LPCSTR SeiPrintFunctionName(LPCSTR lpProcName, char szOrdProcFmt[10])
219{
220 if (SeiIsOrdinalName(lpProcName))
221 {
222 StringCchPrintfA(szOrdProcFmt, 10, "#%Iu", (ULONG_PTR)lpProcName);
223 return szOrdProcFmt;
224 }
225 return lpProcName;
226}
227
228int SeiCompareFunctionName(LPCSTR lpProcName1, LPCSTR lpProcName2)
229{
230 BOOL Ord1 = SeiIsOrdinalName(lpProcName1);
231 BOOL Ord2 = SeiIsOrdinalName(lpProcName2);
232
233 /* One is an ordinal, the other not */
234 if (Ord1 != Ord2)
235 return 1;
236
237 /* Compare ordinals */
238 if (Ord1)
239 return (ULONG_PTR)lpProcName1 != (ULONG_PTR)lpProcName2;
240
241 /* Compare names */
242 return strcmp(lpProcName1, lpProcName2);
243}
244
245
247{
250 return hModule;
251}
252
253
254/* TODO: Guard against recursive calling / calling init multiple times! */
256{
257 DWORD n;
258
259 for (n = 0; n < ARRAY_Size(&g_pShimInfo); ++n)
260 {
261 PSHIMMODULE pShimModule = *ARRAY_At(&g_pShimInfo, PSHIMMODULE, n);
262 if (!pShimModule->pNotifyShims)
263 continue;
264
265 pShimModule->pNotifyShims(dwReason, Info);
266 }
267}
268
269
270
272{
273 ULONG ComSectionSize;
275
276 SHIMENG_INFO("COM+ executable %s\n", g_bComPlusImage ? "TRUE" : "FALSE");
277}
278
279
281{
282 DWORD n;
283
284 for (n = 0; n < ARRAY_Size(&g_pShimInfo); ++n)
285 {
286 PSHIMMODULE pShimModule = *ARRAY_At(&g_pShimInfo, PSHIMMODULE, n);
287
288 if (pShimModule->BaseAddress == BaseAddress)
289 return pShimModule;
290 }
291 return NULL;
292}
293
295{
296 static const ANSI_STRING GetHookAPIs = RTL_CONSTANT_STRING("GetHookAPIs");
297 static const ANSI_STRING NotifyShims = RTL_CONSTANT_STRING("NotifyShims");
299 PVOID pGetHookAPIs, pNotifyShims;
300
303 {
304 SHIMENG_WARN("Failed to resolve entry points for %S\n", DllName);
305 return NULL;
306 }
307
309 if (!pData)
310 return NULL;
311
312 *pData = SeiAlloc(sizeof(SHIMMODULE));
313
314 Data = *pData;
315
316 RtlCreateUnicodeString(&Data->Name, DllName);
317 Data->BaseAddress = BaseAddress;
318
319 Data->pGetHookAPIs = pGetHookAPIs;
320 Data->pNotifyShims = pNotifyShims;
321
322 ARRAY_Init(&Data->EnabledShims, PSHIMINFO);
323
324 return Data;
325}
326
327PSHIMINFO SeiAppendHookInfo(PSHIMMODULE pShimModuleInfo, PHOOKAPIEX pHookApi, DWORD dwHookCount, PCWSTR ShimName)
328{
330
331 pData = ARRAY_Append(&pShimModuleInfo->EnabledShims, PSHIMINFO);
332 if (!pData)
333 return NULL;
334
335 *pData = SeiAlloc(sizeof(SHIMINFO));
336 Data = *pData;
337
338 if (!Data)
339 return NULL;
340
341 Data->ShimName = SdbpStrDup(ShimName);
342 if (!Data->ShimName)
343 return NULL;
344
345 Data->pHookApi = pHookApi;
346 Data->dwHookCount = dwHookCount;
347 Data->pShimModule = pShimModuleInfo;
348 ARRAY_Init(&Data->InExclude, INEXCLUDE);
349 return Data;
350}
351
353{
354 DWORD n;
355
356 if (ModuleName == NULL && BaseAddress == NULL)
357 {
358 BaseAddress = NtCurrentPeb()->ImageBaseAddress;
359 }
360
361 for (n = 0; n < ARRAY_Size(&g_pHookArray); ++n)
362 {
364
365 if (BaseAddress && BaseAddress == pModuleInfo->BaseAddress)
366 return pModuleInfo;
367
368 if (!BaseAddress && RtlEqualUnicodeString(ModuleName, &pModuleInfo->Name, TRUE))
369 return pModuleInfo;
370 }
371
372 return NULL;
373}
374
376{
377 UNICODE_STRING DllName;
378 PVOID DllHandle;
380
381 if (!RtlCreateUnicodeStringFromAsciiz(&DllName, (PCSZ)(DllBase + ImportDescriptor->Name)))
382 {
383 SHIMENG_FAIL("Unable to convert dll name to unicode\n");
384 return NULL;
385 }
386
387 Success = LdrGetDllHandle(NULL, NULL, &DllName, &DllHandle);
388
389 if (!NT_SUCCESS(Success))
390 {
391 SHIMENG_FAIL("Unable to get module handle for %wZ (%p)\n", &DllName, DllBase);
392 RtlFreeUnicodeString(&DllName);
393
394 return NULL;
395 }
396 RtlFreeUnicodeString(&DllName);
397
398 return SeiFindHookModuleInfo(NULL, DllHandle);
399}
400
402{
403 TAGID tagEntry = SdbFindFirstTag(pdb, tag, type);
404 if (tagEntry == TAGID_NULL)
405 return NULL;
406
407 return SdbGetStringTagPtr(pdb, tagEntry);
408}
409
411{
412 TAGID tagEntry = SdbFindFirstTag(pdb, tag, type);
413 if (tagEntry == TAGID_NULL)
414 return 0;
415
416 return SdbReadDWORDTag(pdb, tagEntry, 0);
417}
418
420{
421 TAGID tagEntry = SdbFindFirstTag(pdb, tag, type);
422 if (tagEntry == TAGID_NULL)
423 return 0;
424
425 return SdbReadQWORDTag(pdb, tagEntry, 0);
426}
427
428static VOID SeiAddShim(TAGREF trShimRef, PARRAY pShimRef)
429{
430 TAGREF* Data;
431
432 Data = ARRAY_Append(pShimRef, TAGREF);
433 if (!Data)
434 return;
435
436 *Data = trShimRef;
437}
438
439static VOID SeiAddFlag(PDB pdb, TAGID tiFlagRef, PFLAGINFO pFlagInfo)
440{
442
443 /* Resolve the FLAG_REF to the real FLAG node */
444 TAGID FlagTag = SeiGetDWORD(pdb, tiFlagRef, TAG_FLAG_TAGID);
445
446 if (FlagTag == TAGID_NULL)
447 return;
448
451 Flag.QuadPart = SeiGetQWORD(pdb, FlagTag, TAG_FLAG_PROCESSPARAM);
452 pFlagInfo->ProcessParameters_Flags |= Flag.LowPart;
453}
454
455/* Propagate layers to child processes */
457{
459 UNICODE_STRING VarName = RTL_CONSTANT_STRING(L"__COMPAT_LAYER");
461
463
465 if (NT_SUCCESS(Status))
466 SHIMENG_INFO("%wZ=%wZ\n", &VarName, &Value);
467 else
468 SHIMENG_FAIL("Failed to set %wZ: 0x%x\n", &VarName, Status);
469}
470
471#define MAX_LAYER_LENGTH 256
472
473/* Translate all Exe and Layer entries to Shims, and propagate all layers */
474static VOID SeiBuildShimRefArray(HSDB hsdb, SDBQUERYRESULT* pQuery, PARRAY pShimRef, PFLAGINFO pFlagInfo)
475{
476 WCHAR wszLayerEnvVar[MAX_LAYER_LENGTH] = { 0 };
477 DWORD n;
478
479 for (n = 0; n < pQuery->dwExeCount; ++n)
480 {
481 PDB pdb;
482 TAGID tag;
483 if (SdbTagRefToTagID(hsdb, pQuery->atrExes[n], &pdb, &tag))
484 {
488
489 if (ExeName)
490 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(Exe(%S))\n", ExeName);
491
492 while (ShimRef != TAGID_NULL)
493 {
494 TAGREF trShimRef;
495 if (SdbTagIDToTagRef(hsdb, pdb, ShimRef, &trShimRef))
496 SeiAddShim(trShimRef, pShimRef);
497
499 }
500
501 while (FlagRef != TAGID_NULL)
502 {
503 SeiAddFlag(pdb, FlagRef, pFlagInfo);
504
506 }
507 }
508 }
509
510
511 for (n = 0; n < pQuery->dwLayerCount; ++n)
512 {
513 PDB pdb;
514 TAGID tag;
515 if (SdbTagRefToTagID(hsdb, pQuery->atrLayers[n], &pdb, &tag))
516 {
517 LPCWSTR LayerName = SeiGetStringPtr(pdb, tag, TAG_NAME);
520
521 if (LayerName)
522 {
523 HRESULT hr;
524 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(Layer(%S))\n", LayerName);
525 if (wszLayerEnvVar[0])
526 StringCchCatW(wszLayerEnvVar, ARRAYSIZE(wszLayerEnvVar), L" ");
527 hr = StringCchCatW(wszLayerEnvVar, ARRAYSIZE(wszLayerEnvVar), LayerName);
528 if (!SUCCEEDED(hr))
529 {
530 SHIMENG_FAIL("Unable to append %S\n", LayerName);
531 }
532 }
533
534 while (ShimRef != TAGID_NULL)
535 {
536 TAGREF trShimRef;
537 if (SdbTagIDToTagRef(hsdb, pdb, ShimRef, &trShimRef))
538 SeiAddShim(trShimRef, pShimRef);
539
541 }
542
543 while (FlagRef != TAGID_NULL)
544 {
545 SeiAddFlag(pdb, FlagRef, pFlagInfo);
546
548 }
549 }
550 }
551 if (wszLayerEnvVar[0])
552 SeiSetLayerEnvVar(wszLayerEnvVar);
553}
554
555/* Given the hooks from one shim, find the relevant modules and store the combination of module + hook */
556VOID SeiAddHooks(PHOOKAPIEX hooks, DWORD dwHookCount, PSHIMINFO pShim)
557{
558 DWORD n, j;
559 UNICODE_STRING UnicodeModName;
560 WCHAR Buf[512];
561
562 RtlInitEmptyUnicodeString(&UnicodeModName, Buf, sizeof(Buf));
563
564 for (n = 0; n < dwHookCount; ++n)
565 {
567 PVOID DllHandle;
568 PHOOKAPIEX hook = hooks + n;
569 PHOOKAPIEX* pHookApi;
570 PHOOKMODULEINFO HookModuleInfo;
571
572 RtlInitAnsiString(&AnsiString, hook->LibraryName);
574 {
575 SHIMENG_FAIL("Unable to convert %s to Unicode\n", hook->LibraryName);
576 continue;
577 }
578
579 if (NT_SUCCESS(LdrGetDllHandle(NULL, 0, &UnicodeModName, &DllHandle)))
580 {
581 HookModuleInfo = SeiFindHookModuleInfo(NULL, DllHandle);
582 }
583 else
584 {
585 HookModuleInfo = SeiFindHookModuleInfo(&UnicodeModName, NULL);
586 DllHandle = NULL;
587 }
588
589 if (!HookModuleInfo)
590 {
591 HookModuleInfo = ARRAY_Append(&g_pHookArray, HOOKMODULEINFO);
592 if (!HookModuleInfo)
593 continue;
594
595 HookModuleInfo->BaseAddress = DllHandle;
596 ARRAY_Init(&HookModuleInfo->HookApis, PHOOKAPIEX);
597 RtlCreateUnicodeString(&HookModuleInfo->Name, UnicodeModName.Buffer);
598 }
599
600 hook->pShimInfo = pShim;
601
602 for (j = 0; j < ARRAY_Size(&HookModuleInfo->HookApis); ++j)
603 {
604 PHOOKAPIEX HookApi = *ARRAY_At(&HookModuleInfo->HookApis, PHOOKAPIEX, j);
605 int CmpResult = SeiCompareFunctionName(hook->FunctionName, HookApi->FunctionName);
606 if (CmpResult == 0)
607 {
608 while (HookApi->ApiLink)
609 {
610 HookApi = HookApi->ApiLink;
611 }
612 HookApi->ApiLink = hook;
613 hook = NULL;
614 break;
615 }
616 }
617 /* No place found yet, append it */
618 if (hook)
619 {
620 pHookApi = ARRAY_Append(&HookModuleInfo->HookApis, PHOOKAPIEX);
621 if (pHookApi)
622 *pHookApi = hook;
623 }
624 }
625}
626
627/* Check if we should fake the return from GetProcAddress (because we also redirected the iat for this module) */
629{
630 PVOID Addr = _ReturnAddress();
631 PHOOKMODULEINFO HookModuleInfo;
632 FARPROC proc = ((GETPROCADDRESSPROC)g_IntHookEx[0].OriginalFunction)(hModule, lpProcName);
633 char szOrdProcFmt[10];
634
635 Addr = SeiGetModuleFromAddress(Addr);
636 if (SE_IsShimDll(Addr))
637 {
638 SHIMENG_MSG("Not touching GetProcAddress for shim dll (%p!%s)", hModule, SeiPrintFunctionName(lpProcName, szOrdProcFmt));
639 return proc;
640 }
641
642 SHIMENG_INFO("(GetProcAddress(%p!%s) => %p\n", hModule, SeiPrintFunctionName(lpProcName, szOrdProcFmt), proc);
643
644 HookModuleInfo = SeiFindHookModuleInfo(NULL, hModule);
645
646 if (HookModuleInfo)
647 {
648 DWORD n;
649 for (n = 0; n < ARRAY_Size(&HookModuleInfo->HookApis); ++n)
650 {
651 PHOOKAPIEX HookApi = *ARRAY_At(&HookModuleInfo->HookApis, PHOOKAPIEX, n);
652 int CmpResult = SeiCompareFunctionName(lpProcName, HookApi->FunctionName);
653 if (CmpResult == 0)
654 {
655 SHIMENG_MSG("Redirecting %p to %p\n", proc, HookApi->ReplacementFunction);
656 proc = HookApi->ReplacementFunction;
657 break;
658 }
659 }
660 }
661
662 return proc;
663}
664
666{
667 DWORD n;
669
670 ASSERT(HookModuleInfo->BaseAddress != NULL);
671
672 for (n = 0; n < ARRAY_Size(&HookModuleInfo->HookApis); ++n)
673 {
675 PVOID ProcAddress;
676 PHOOKAPIEX HookApi = *ARRAY_At(&HookModuleInfo->HookApis, PHOOKAPIEX, n);
677
678 if (!SeiIsOrdinalName(HookApi->FunctionName))
679 {
681 Status = LdrGetProcedureAddress(HookModuleInfo->BaseAddress, &AnsiString, 0, &ProcAddress);
682 }
683 else
684 {
685 Status = LdrGetProcedureAddress(HookModuleInfo->BaseAddress, NULL, (ULONG_PTR)HookApi->FunctionName, &ProcAddress);
686 }
687
688 if (!NT_SUCCESS(Status))
689 {
690 char szOrdProcFmt[10];
691 LPCSTR lpFunctionName = SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt);
692 SHIMENG_FAIL("Unable to retrieve %s!%s\n", HookApi->LibraryName, lpFunctionName);
693 continue;
694 }
695
696 HookApi->OriginalFunction = ProcAddress;
697 if (HookApi->ApiLink)
698 {
699 SHIMENG_MSG("TODO: Figure out how to handle conflicting In/Exports with ApiLink!\n");
700 }
701 while (HookApi->ApiLink)
702 {
703 HookApi->ApiLink->OriginalFunction = HookApi->OriginalFunction;
704 HookApi->OriginalFunction = HookApi->ApiLink->ReplacementFunction;
705 HookApi = HookApi->ApiLink;
706 }
707 }
708}
709
710/* Walk all shim modules / enabled shims, and add their hooks */
712{
713 DWORD n;
714
715 for (n = 0; n < ARRAY_Size(&g_pHookArray); ++n)
716 {
718
719 /* Is this module loaded? */
720 if (pModuleInfo->BaseAddress)
721 {
722 SeiResolveAPI(pModuleInfo);
723 }
724 }
725}
726
728{
729 DWORD mod, n;
730
731 /* Enumerate all Shim modules */
732 for (mod = 0; mod < ARRAY_Size(&g_pShimInfo); ++mod)
733 {
735 DWORD dwShimCount = ARRAY_Size(&pShimModule->EnabledShims);
736
737 /* Enumerate all Shims */
738 for (n = 0; n < dwShimCount; ++n)
739 {
740 PSHIMINFO pShim = *ARRAY_At(&pShimModule->EnabledShims, PSHIMINFO, n);
741
742 PHOOKAPIEX hooks = pShim->pHookApi;
743 DWORD dwHookCount = pShim->dwHookCount;
744
745 SeiAddHooks(hooks, dwHookCount, pShim);
746 }
747 }
748}
749
750/* If we hooked something, we should also redirect GetProcAddress */
752{
753 if (dwNumHooks == 0)
754 {
756 return;
757 }
758
761}
762
763/* Patch one function in the iat */
765{
766 ULONG OldProtection = 0;
767 PVOID Ptr;
768 SIZE_T Size;
770 char szOrdProcFmt[10];
771
772 SHIMENG_INFO("Hooking API \"%s!%s\" for DLL \"%wZ\"\n", HookApi->LibraryName, SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt), &LdrEntry->BaseDllName);
773
774 Ptr = &FirstThunk->u1.Function;
775 Size = sizeof(FirstThunk->u1.Function);
777
778 if (!NT_SUCCESS(Status))
779 {
780 SHIMENG_FAIL("Unable to unprotect 0x%p\n", &FirstThunk->u1.Function);
781 return;
782 }
783
784 SHIMENG_INFO("changing 0x%p to 0x%p\n", FirstThunk->u1.Function, HookApi->ReplacementFunction);
785 FirstThunk->u1.Function = (ULONG_PTR)HookApi->ReplacementFunction;
786
787 Size = sizeof(FirstThunk->u1.Function);
788 Status = NtProtectVirtualMemory(NtCurrentProcess(), &Ptr, &Size, OldProtection, &OldProtection);
789
790 if (!NT_SUCCESS(Status))
791 {
792 SHIMENG_WARN("Unable to reprotect 0x%p\n", &FirstThunk->u1.Function);
793 }
794}
795
796
798{
799 DWORD n;
800
801 for (n = 0; n < ARRAY_Size(InExclude); ++n)
802 {
804
805 if (RtlEqualUnicodeString(&InEx->Module, DllName, TRUE))
806 return InEx;
807 }
808
809 return NULL;
810}
811
813{
814 PSHIMINFO pShimInfo = HookApi->pShimInfo;
816 BOOL IsExcluded = FALSE;
817 char szOrdProcFmt[10];
818
819 if (!pShimInfo)
820 {
821 /* Internal hook, do not exclude it */
822 return FALSE;
823 }
824
825 /* By default, everything from System32 or WinSxs is excluded */
828 IsExcluded = TRUE;
829
830 InExclude = SeiFindInExclude(&pShimInfo->InExclude, &LdrEntry->BaseDllName);
831 if (InExclude)
832 {
833 /* If it is on the 'exclude' list, bail out */
834 if (!InExclude->Include)
835 {
836 SHIMENG_INFO("Module '%wZ' excluded for shim %S, API '%s!%s', because it on in the exclude list.\n",
837 &LdrEntry->BaseDllName, pShimInfo->ShimName, HookApi->LibraryName, SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt));
838
839 return TRUE;
840 }
841 /* If it is on the 'include' list, override System32 / Winsxs check. */
842 if (IsExcluded)
843 {
844 SHIMENG_INFO("Module '%wZ' included for shim %S, API '%s!%s', because it is on the include list.\n",
845 &LdrEntry->BaseDllName, pShimInfo->ShimName, HookApi->LibraryName, SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt));
846
847 }
848 IsExcluded = FALSE;
849 }
850
851 if (IsExcluded)
852 {
853 SHIMENG_INFO("Module '%wZ' excluded for shim %S, API '%s!%s', because it is in System32/WinSXS.\n",
854 &LdrEntry->BaseDllName, pShimInfo->ShimName, HookApi->LibraryName, SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt));
855 }
856
857 return IsExcluded;
858}
859
861{
863 UNICODE_STRING ModuleNameU;
864 RtlInitUnicodeString(&ModuleNameU, ModuleName);
865
866 InExclude = SeiFindInExclude(dest, &ModuleNameU);
867 if (InExclude)
868 {
869 InExclude->Include = IsInclude;
870 return;
871 }
872
874 if (InExclude)
875 {
876 PCWSTR ModuleNameCopy = SdbpStrDup(ModuleName);
877 RtlInitUnicodeString(&InExclude->Module, ModuleNameCopy);
878 InExclude->Include = IsInclude;
879 }
880}
881
882/* Read the INEXCLUD tags from a given parent tag
883FIXME:
884 Some observed tags:
885 '*' with include
886 '$' with include, followed by '*' without include
887 Include list logging, referring to: (MODE: EA)
888*/
890{
891 TAGID InExcludeTag;
892
893 InExcludeTag = SdbFindFirstTag(pdb, parent, TAG_INEXCLUD);
894
895 while (InExcludeTag != TAGID_NULL)
896 {
898 TAGID ModuleTag = SdbFindFirstTag(pdb, InExcludeTag, TAG_MODULE);
899 TAGID IncludeTag = SdbFindFirstTag(pdb, InExcludeTag, TAG_INCLUDE);
900
901 ModuleName = SdbGetStringTagPtr(pdb, ModuleTag);
902 if (ModuleName)
903 {
905 }
906 else
907 {
908 SHIMENG_WARN("INEXCLUDE without Module: 0x%x\n", InExcludeTag);
909 }
910
911 InExcludeTag = SdbFindNextTag(pdb, parent, InExcludeTag);
912 }
913}
914
916{
917 PDB pdb;
918 TAGREF tr = TAGREF_ROOT;
919 TAGID root, db, library;
920
921 if (!SdbTagRefToTagID(hsdb, tr, &pdb, &root))
922 {
923 SHIMENG_WARN("Unable to resolve database root\n");
924 return;
925 }
927 if (db == TAGID_NULL)
928 {
929 SHIMENG_WARN("Unable to resolve database\n");
930 return;
931 }
933 if (library == TAGID_NULL)
934 {
935 SHIMENG_WARN("Unable to resolve library\n");
936 return;
937 }
938
940}
941
943{
944 DWORD n;
945
946 /* First duplicate the global in/excludes */
947 for (n = 0; n < ARRAY_Size(&g_InExclude); ++n)
948 {
950 SeiAppendInExclude(&pShimInfo->InExclude, InEx->Module.Buffer, InEx->Include);
951 }
952
953 /* Now read this shim's in/excludes (possibly overriding the global ones) */
954 SeiReadInExclude(pdb, ShimTag, &pShimInfo->InExclude);
955}
956
957/* Given one loaded module, redirect (hook) all functions from the iat that are registered by shims */
959{
960 ULONG Size;
961 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
962 PBYTE DllBase = LdrEntry->DllBase;
963
964 if (SE_IsShimDll(DllBase) ||
965 g_hInstance == LdrEntry->DllBase ||
967 {
968 SHIMENG_INFO("Skipping shim module 0x%p \"%wZ\"\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
969 return;
970 }
971
973 {
974 SHIMENG_INFO("Skipping module 0x%p \"%wZ\" because it was already processed\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
975 return;
976 }
977
979 if (!ImportDescriptor)
980 {
981 SHIMENG_INFO("Skipping module 0x%p \"%wZ\" due to no iat found\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
982 return;
983 }
984
985 SHIMENG_INFO("Hooking module 0x%p \"%wZ\"\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
986
987 for ( ;ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk; ImportDescriptor++)
988 {
989 PHOOKMODULEINFO HookModuleInfo;
990
991 /* Do we have hooks for this module? */
992 HookModuleInfo = SeiFindHookModuleInfoForImportDescriptor(DllBase, ImportDescriptor);
993
994 if (HookModuleInfo)
995 {
996 PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
997 DWORD n;
998
999 for (n = 0; n < ARRAY_Size(&HookModuleInfo->HookApis); ++n)
1000 {
1001 DWORD dwFound = 0;
1002 PHOOKAPIEX HookApi = *ARRAY_At(&HookModuleInfo->HookApis, PHOOKAPIEX, n);
1003
1004 /* Check if this module should be excluded from being hooked (system32/winsxs, global or shim exclude) */
1005 if (SeiIsExcluded(LdrEntry, HookApi))
1006 {
1007 continue;
1008 }
1009
1010 OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
1011 FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
1012
1013 /* Walk all imports */
1014 for (;OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function; OriginalThunk++, FirstThunk++)
1015 {
1016 if (!IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Function))
1017 {
1018 if (!SeiIsOrdinalName(HookApi->FunctionName))
1019 {
1020 PIMAGE_IMPORT_BY_NAME ImportName;
1021
1022 ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.Function);
1023 if (!strcmp((PCSTR)ImportName->Name, HookApi->FunctionName))
1024 {
1025 SeiPatchNewImport(FirstThunk, HookApi, LdrEntry);
1026
1027 /* Sadly, iat does not have to be sorted, and can even contain duplicate entries. */
1028 dwFound++;
1029 }
1030 }
1031 }
1032 else
1033 {
1034 if (SeiIsOrdinalName(HookApi->FunctionName))
1035 {
1036 if ((PCSTR)IMAGE_ORDINAL(OriginalThunk->u1.Function) == HookApi->FunctionName)
1037 {
1038 SeiPatchNewImport(FirstThunk, HookApi, LdrEntry);
1039 dwFound++;
1040 }
1041 }
1042 }
1043 }
1044
1045 if (dwFound != 1)
1046 {
1047 char szOrdProcFmt[10];
1048 LPCSTR FuncName = SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt);
1049
1050 /* One entry not found. */
1051 if (!dwFound)
1052 SHIMENG_INFO("Entry \"%s!%s\" not found for \"%wZ\"\n", HookApi->LibraryName, FuncName, &LdrEntry->BaseDllName);
1053 else
1054 SHIMENG_INFO("Entry \"%s!%s\" found %d times for \"%wZ\"\n", HookApi->LibraryName, FuncName, dwFound, &LdrEntry->BaseDllName);
1055 }
1056 }
1057 }
1058 }
1059
1060 /* Mark this module as processed. */
1062}
1063
1064
1066{
1067 PLIST_ENTRY ListHead, ListEntry;
1068 PLDR_DATA_TABLE_ENTRY LdrEntry;
1069
1070 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1071 ListEntry = ListHead->Flink;
1072
1073 while (ListHead != ListEntry)
1074 {
1075 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1076 SeiHookImports(LdrEntry);
1077
1078 ListEntry = ListEntry->Flink;
1079 }
1080}
1081
1082
1084{
1085#define SYSTEM32 L"\\system32"
1086#define WINSXS L"\\winsxs"
1087
1088 PWSTR WindowsDirectory = SdbpStrDup(SharedUserData->NtSystemRoot);
1089 RtlInitUnicodeString(&g_WindowsDirectory, WindowsDirectory);
1090
1095
1100
1101#undef SYSTEM32
1102#undef WINSXS
1103}
1104
1106{
1107 PLIST_ENTRY ListHead, Entry;
1108 PLDR_DATA_TABLE_ENTRY LdrEntry;
1109
1110 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1111 Entry = ListHead->Flink;
1112 while (Entry != ListHead)
1113 {
1114 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1115 Entry = Entry->Flink;
1116
1117 if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &Ntdll, TRUE) ||
1121 SE_IsShimDll(LdrEntry->DllBase) ||
1122 (LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
1123 {
1124 SHIMENG_WARN("Don't mess with 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1125 }
1126 else
1127 {
1128 SHIMENG_WARN("Touching 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1130 }
1131 }
1132
1133 ListHead = &NtCurrentPeb()->Ldr->InMemoryOrderModuleList;
1134 Entry = ListHead->Flink;
1135 SHIMENG_INFO("In memory:\n");
1136 while (Entry != ListHead)
1137 {
1138 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
1139 Entry = Entry->Flink;
1140
1141 SHIMENG_INFO(" 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1142 }
1143
1144 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1145 Entry = ListHead->Flink;
1146 SHIMENG_INFO("In load:\n");
1147 while (Entry != ListHead)
1148 {
1149 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1150 Entry = Entry->Flink;
1151
1152 SHIMENG_INFO(" 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1153 }
1154}
1155
1157{
1158 PLIST_ENTRY ListHead, Entry;
1159 PLDR_DATA_TABLE_ENTRY LdrEntry;
1160
1161 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1162 Entry = ListHead->Flink;
1163 while (Entry != ListHead)
1164 {
1165 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1166 Entry = Entry->Flink;
1167
1168 if (SE_IsShimDll(LdrEntry->DllBase) ||
1169 g_hInstance == LdrEntry->DllBase ||
1173 !(LdrEntry->Flags & LDRP_SHIMENG_SUPPRESSED_ENTRY))
1174 {
1175 SHIMENG_WARN("Don't mess with 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1176 }
1177 else
1178 {
1179 SHIMENG_WARN("Resetting 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1181 }
1182 }
1183}
1184
1185VOID SeiInit(LPCWSTR ProcessImage, HSDB hsdb, SDBQUERYRESULT* pQuery, BOOLEAN ProcessInit)
1186{
1187 DWORD n;
1188 ARRAY ShimRefArray;
1189 DWORD dwTotalHooks = 0;
1190 FLAGINFO ShimFlags;
1191
1192 PPEB Peb = NtCurrentPeb();
1193
1194 /* We should only be called once! */
1196
1197 ARRAY_Init(&ShimRefArray, TAGREF);
1201 RtlZeroMemory(&ShimFlags, sizeof(ShimFlags));
1202
1203 SeiInitPaths();
1204
1206
1207 if (ProcessInit)
1208 {
1209 /* Mark all modules loaded until now as 'LDRP_ENTRY_PROCESSED' so that their entrypoint is not called while we are loading shims */
1211 }
1212
1213 /* TODO:
1214 if (pQuery->trApphelp)
1215 SeiDisplayAppHelp(?pQuery->trApphelp?);
1216 */
1217
1218 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(ExePath(%S))\n", ProcessImage);
1219 SeiBuildShimRefArray(hsdb, pQuery, &ShimRefArray, &ShimFlags);
1220 if (ShimFlags.AppCompatFlags.QuadPart)
1221 {
1222 SeiDbgPrint(SEI_MSG, NULL, "Using KERNEL apphack flags 0x%I64x\n", ShimFlags.AppCompatFlags.QuadPart);
1224 }
1225 if (ShimFlags.AppCompatFlagsUser.QuadPart)
1226 {
1227 SeiDbgPrint(SEI_MSG, NULL, "Using USER apphack flags 0x%I64x\n", ShimFlags.AppCompatFlagsUser.QuadPart);
1229 }
1230 if (ShimFlags.ProcessParameters_Flags)
1231 {
1232 SeiDbgPrint(SEI_MSG, NULL, "Using ProcessParameters flags 0x%x\n", ShimFlags.ProcessParameters_Flags);
1234 }
1235 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(Complete)\n");
1236
1237 SHIMENG_INFO("Got %d shims\n", ARRAY_Size(&ShimRefArray));
1239
1240 /* Walk all shims referenced (in layers + exes), and load their modules */
1241 for (n = 0; n < ARRAY_Size(&ShimRefArray); ++n)
1242 {
1243 PDB pdb;
1244 TAGID ShimRef;
1245
1246 TAGREF tr = *ARRAY_At(&ShimRefArray, TAGREF, n);
1247
1248 if (SdbTagRefToTagID(hsdb, tr, &pdb, &ShimRef))
1249 {
1250 LPCWSTR ShimName, DllName, CommandLine = NULL;
1251 TAGID ShimTag;
1252 WCHAR FullNameBuffer[MAX_PATH];
1253 UNICODE_STRING UnicodeDllName;
1255 PSHIMMODULE pShimModuleInfo = NULL;
1256 ANSI_STRING AnsiCommandLine = RTL_CONSTANT_STRING("");
1257 PSHIMINFO pShimInfo = NULL;
1258 PHOOKAPIEX pHookApi;
1259 DWORD dwHookCount;
1260
1261 ShimName = SeiGetStringPtr(pdb, ShimRef, TAG_NAME);
1262 if (!ShimName)
1263 {
1264 SHIMENG_FAIL("Failed to retrieve the name for 0x%x\n", tr);
1265 continue;
1266 }
1267
1269 if (CommandLine && *CommandLine)
1270 {
1271 RtlInitUnicodeString(&UnicodeDllName, CommandLine);
1272 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiCommandLine, &UnicodeDllName, TRUE)))
1273 {
1274 SHIMENG_INFO("COMMAND LINE %s for %S", AnsiCommandLine.Buffer, ShimName);
1275 }
1276 else
1277 {
1278 AnsiCommandLine.Buffer = "";
1279 CommandLine = NULL;
1280 }
1281 }
1282
1284 if (!ShimTag)
1285 {
1286 SHIMENG_FAIL("Failed to resolve %S to a shim\n", ShimName);
1287 continue;
1288 }
1289
1290 if (!SUCCEEDED(SdbGetAppPatchDir(NULL, FullNameBuffer, ARRAYSIZE(FullNameBuffer))))
1291 {
1292 SHIMENG_WARN("Failed to get the AppPatch dir\n");
1293 continue;
1294 }
1295
1296 DllName = SeiGetStringPtr(pdb, ShimTag, TAG_DLLFILE);
1297 if (DllName == NULL ||
1298 !SUCCEEDED(StringCchCatW(FullNameBuffer, ARRAYSIZE(FullNameBuffer), L"\\")) ||
1299 !SUCCEEDED(StringCchCatW(FullNameBuffer, ARRAYSIZE(FullNameBuffer), DllName)))
1300 {
1301 SHIMENG_WARN("Failed to build a full path for %S\n", ShimName);
1302 continue;
1303 }
1304
1306 RtlInitUnicodeString(&UnicodeDllName, FullNameBuffer);
1307 if (NT_SUCCESS(LdrGetDllHandle(NULL, NULL, &UnicodeDllName, &BaseAddress)))
1308 {
1309 /* This shim dll was already loaded, let's find it */
1310 pShimModuleInfo = SeiGetShimModuleInfo(BaseAddress);
1311 }
1312 else if (!NT_SUCCESS(LdrLoadDll(NULL, NULL, &UnicodeDllName, &BaseAddress)))
1313 {
1314 SHIMENG_WARN("Failed to load %wZ for %S\n", &UnicodeDllName, ShimName);
1315 continue;
1316 }
1318 /* No shim module found (or we just loaded it) */
1319 if (!pShimModuleInfo)
1320 {
1321 pShimModuleInfo = SeiCreateShimModuleInfo(DllName, BaseAddress);
1322 if (!pShimModuleInfo)
1323 {
1324 SHIMENG_FAIL("Failed to allocate ShimInfo for %S\n", DllName);
1325 continue;
1326 }
1327 }
1328
1329 SHIMENG_INFO("Shim DLL 0x%p \"%wZ\" loaded\n", BaseAddress, &UnicodeDllName);
1330 SHIMENG_INFO("Using SHIM \"%S!%S\"\n", DllName, ShimName);
1331
1332 /* Ask this shim what hooks it needs (and pass along the commandline) */
1333 dwHookCount = 0;
1334 pHookApi = pShimModuleInfo->pGetHookAPIs(AnsiCommandLine.Buffer, ShimName, &dwHookCount);
1335 SHIMENG_INFO("GetHookAPIs returns %d hooks for DLL \"%wZ\" SHIM \"%S\"\n", dwHookCount, &UnicodeDllName, ShimName);
1336 if (dwHookCount && pHookApi)
1337 pShimInfo = SeiAppendHookInfo(pShimModuleInfo, pHookApi, dwHookCount, ShimName);
1338 else
1339 dwHookCount = 0;
1340
1341 /* If this shim has hooks, create the include / exclude lists */
1342 if (pShimInfo)
1343 SeiBuildInclExclList(pdb, ShimTag, pShimInfo);
1344
1345 if (CommandLine && *CommandLine)
1346 RtlFreeAnsiString(&AnsiCommandLine);
1347
1348 dwTotalHooks += dwHookCount;
1349 }
1350 }
1351
1352 SeiAddInternalHooks(dwTotalHooks);
1356
1357 if (ProcessInit)
1358 {
1359 /* Remove the 'LDRP_ENTRY_PROCESSED' flag from entries we modified, so that the loader can continue to process them */
1361 }
1363}
1364
1365
1366/* Load the database + unpack the shim data (if this process is allowed) */
1367BOOL SeiGetShimData(PUNICODE_STRING ProcessImage, PVOID pShimData, HSDB* pHsdb, SDBQUERYRESULT* pQuery)
1368{
1369 static const UNICODE_STRING ForbiddenShimmingApps[] = {
1370 RTL_CONSTANT_STRING(L"ntsd.exe"),
1371 RTL_CONSTANT_STRING(L"windbg.exe"),
1372#if WINVER >= 0x600
1373 RTL_CONSTANT_STRING(L"slsvc.exe"),
1374#endif
1375 };
1376 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
1377 UNICODE_STRING ProcessName;
1378 USHORT PathDivider;
1379 HSDB hsdb;
1380 DWORD n;
1381
1382 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, ProcessImage, &PathDividerFind, &PathDivider)))
1383 PathDivider = 0;
1384
1385 if (PathDivider)
1386 PathDivider += sizeof(WCHAR);
1387
1388 ProcessName.Buffer = ProcessImage->Buffer + PathDivider / sizeof(WCHAR);
1389 ProcessName.Length = ProcessImage->Length - PathDivider;
1390 ProcessName.MaximumLength = ProcessImage->MaximumLength - PathDivider;
1391
1392 for (n = 0; n < ARRAYSIZE(ForbiddenShimmingApps); ++n)
1393 {
1394 if (RtlEqualUnicodeString(&ProcessName, ForbiddenShimmingApps + n, TRUE))
1395 {
1396 SHIMENG_MSG("Not shimming %wZ\n", ForbiddenShimmingApps + n);
1397 return FALSE;
1398 }
1399 }
1400
1401 /* We should probably load all db's here, but since we do not support that yet... */
1403 if (hsdb)
1404 {
1405 if (SdbUnpackAppCompatData(hsdb, ProcessImage->Buffer, pShimData, pQuery))
1406 {
1407 *pHsdb = hsdb;
1408 return TRUE;
1409 }
1410 SdbReleaseDatabase(hsdb);
1411 }
1412 return FALSE;
1413}
1414
1415
1416
1418{
1419 HSDB hsdb = NULL;
1420 SDBQUERYRESULT QueryResult = { { 0 } };
1421 SHIMENG_INFO("(%wZ, %p)\n", ProcessImage, pShimData);
1422
1423 if (!SeiGetShimData(ProcessImage, pShimData, &hsdb, &QueryResult))
1424 {
1425 SHIMENG_FAIL("Failed to get shim data\n");
1426 return;
1427 }
1428
1430 SeiInit(ProcessImage->Buffer, hsdb, &QueryResult, TRUE);
1432
1433 SdbReleaseDatabase(hsdb);
1434}
1435
1437{
1439}
1440
1442{
1443 SHIMENG_MSG("()\n");
1445}
1446
1448{
1449 PHOOKMODULEINFO HookModuleInfo;
1450 SHIMENG_INFO("%sINIT. loading DLL \"%wZ\"\n", g_bShimDuringInit ? "" : "AFTER ", &LdrEntry->BaseDllName);
1451
1452 HookModuleInfo = SeiFindHookModuleInfo(&LdrEntry->BaseDllName, NULL);
1453 if (HookModuleInfo)
1454 {
1455 ASSERT(HookModuleInfo->BaseAddress == NULL);
1456 HookModuleInfo->BaseAddress = LdrEntry->DllBase;
1457 SeiResolveAPI(HookModuleInfo);
1458 }
1459
1460 SeiHookImports(LdrEntry);
1461
1463}
1464
1466{
1467 SHIMENG_INFO("(%p)\n", LdrEntry);
1468
1469 /* Should we unhook here? */
1470
1472}
1473
1475{
1476 SHIMENG_INFO("(%p)\n", BaseAddress);
1477
1479}
1480
1481/* 'Private' ntdll function */
1482BOOLEAN
1483NTAPI
1485
1486
1487BOOL WINAPI SE_DynamicShim(LPCWSTR ProcessImage, HSDB hsdb, PVOID pQueryResult, LPCSTR Module, LPDWORD lpdwDynamicToken)
1488{
1490 {
1491 SHIMENG_MSG("ReactOS HACK(CORE-13283): ShimEng already initialized!\n");
1492 return TRUE;
1493 }
1494
1496 SeiInit(ProcessImage, hsdb, pQueryResult, FALSE);
1498
1500
1501 return TRUE;
1502}
1503
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
WCHAR * ExeName
@ hook
Definition: SystemMenu.c:35
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
DWORD SdbpStrsize(PCWSTR string)
Definition: sdbapi.c:157
#define SDB_DATABASE_MAIN_SHIM
Definition: apphelp.h:24
TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag)
Definition: sdbread.c:208
BOOL WINAPI SdbTagRefToTagID(HSDB hsdb, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich)
Definition: hsdb.c:638
#define HID_DOS_PATHS
Definition: apphelp.h:19
void WINAPI SdbReleaseDatabase(HSDB)
Definition: hsdb.c:417
PWSTR SdbpStrDup(LPCWSTR string)
Definition: sdbapi.c:162
HRESULT WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
Definition: hsdb.c:579
BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF *ptrWhich)
Definition: hsdb.c:669
HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR)
Definition: hsdb.c:369
QWORD WINAPI SdbReadQWORDTag(PDB pdb, TAGID tagid, QWORD ret)
Definition: sdbread.c:321
BOOL WINAPI SdbUnpackAppCompatData(HSDB hsdb, LPCWSTR pszImageName, PVOID pData, PSDBQUERYRESULT pQueryResult)
Definition: hsdb.c:761
TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:231
DWORD WINAPI SdbReadDWORDTag(PDB pdb, TAGID tagid, DWORD ret)
Definition: sdbread.c:305
LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid)
Definition: sdbread.c:375
DWORD TAGREF
DWORD TAGID
LONG NTSTATUS
Definition: precomp.h:26
DWORD dwReason
Definition: misc.cpp:154
struct _root root
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
FT_Library library
Definition: cffdrivr.c:654
Definition: bufpool.h:45
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static PDB pdb
Definition: db.cpp:172
#define TAG_MODULE
Definition: db.cpp:99
#define TAGID_NULL
Definition: db.cpp:38
#define TAG_INEXCLUD
Definition: db.cpp:86
#define TAG_COMMAND_LINE
Definition: db.cpp:102
#define TAG_INCLUDE
Definition: db.cpp:56
#define TAG_SHIM_REF
Definition: db.cpp:89
#define TAG_DATABASE
Definition: db.cpp:85
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PHOOKAPI WINAPI GetHookAPIs(IN LPCSTR szCommandLine, IN LPCWSTR wszShimName, OUT PDWORD pdwHookCount)
Definition: main.c:15
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:656
HMODULE hModule
Definition: animate.c:44
int(* FARPROC)()
Definition: compat.h:36
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define MAX_PATH
Definition: compat.h:34
PPEB Peb
Definition: dllmain.c:27
@ AnsiString
Definition: dnslib.h:19
r parent
Definition: btrfs.c:3010
#define ULONG_PTR
Definition: config.h:101
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
static int mod
Definition: i386-dis.c:1288
#define _ReturnAddress()
Definition: intrin_arm.h:35
#define SUCCEEDED(hr)
Definition: intsafe.h:50
macro IMPORT Name endm macro EXPORT Name global &Name endm macro TEXTAREA section rx align endm macro DATAAREA section rw endm macro RODATAAREA section rw endm macro NESTED_ENTRY Name FuncName equ &Name PrologName equ &Name &_Prolog FuncEndName equ &Name &_end global &FuncName align func &FuncName & FuncName
Definition: kxarm.h:221
static PCWSTR wszLayer
Definition: layerapi.c:36
NTSTATUS NTAPI LdrGetDllHandle(_In_opt_ PWSTR DllPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *DllHandle)
Definition: ldrapi.c:810
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(_In_opt_ PWSTR SearchPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *BaseAddress)
Definition: ldrapi.c:312
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:829
#define LDRP_SHIMENG_SUPPRESSED_ENTRY
Definition: ldrtypes.h:40
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define LDRP_COMPAT_DATABASE_PROCESSED
Definition: ldrtypes.h:61
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
LPCWSTR LPCWSTR LPCWSTR DWORD PSDBQUERYRESULT_VISTA pQueryResult
Definition: env.c:37
static tGETHOOKAPIS pGetHookAPIs
Definition: dispmode.c:26
static char * dest
Definition: rtl.c:135
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable(_In_z_ PWSTR *Environment, _In_ PUNICODE_STRING Name, _In_ PUNICODE_STRING Value)
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END
Definition: rtl.h:25
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3109
#define STRSAFE_NULL_ON_FAILURE
Definition: ntstrsafe.h:34
#define L(x)
Definition: ntvdm.h:50
static HANDLE proc()
Definition: pdb.c:34
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
BYTE * PBYTE
Definition: pedump.c:66
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
LPVOID SdbpAlloc(SIZE_T size)
Definition: sdbapi.c:55
#define WINAPIV
Definition: sdbpapi.h:64
#define TAG_FLAG_REF
Definition: sdbtagid.h:183
#define TAG_FLAG_PROCESSPARAM
Definition: sdbtagid.h:124
#define TAG_SHIM_TAGID
Definition: sdbtagid.h:67
#define TAG_LIBRARY
Definition: sdbtagid.h:164
#define TAG_FLAG_MASK_KERNEL
Definition: sdbtagid.h:114
#define TAG_FLAG_MASK_USER
Definition: sdbtagid.h:117
#define TAG_FLAG_TAGID
Definition: sdbtagid.h:94
#define TAG_DLLFILE
Definition: sdbtagid.h:137
#define TAGREF_ROOT
Definition: sdbtypes.h:22
#define SharedUserData
static UCHAR ItemSize[4]
Definition: parser.c:16
UINT64 QWORD
Definition: shimdbg.c:104
VOID SeiAppendInExclude(PARRAY dest, PCWSTR ModuleName, BOOL IsInclude)
Definition: shimeng.c:860
BOOL SeiIsExcluded(PLDR_DATA_TABLE_ENTRY LdrEntry, PHOOKAPIEX HookApi)
Definition: shimeng.c:812
VOID SeiCombineHookInfo(VOID)
Definition: shimeng.c:727
PHOOKMODULEINFO SeiFindHookModuleInfo(PUNICODE_STRING ModuleName, PVOID BaseAddress)
Definition: shimeng.c:352
HOOKAPIEX g_IntHookEx[]
Definition: shimeng.c:43
PHOOKMODULEINFO SeiFindHookModuleInfoForImportDescriptor(PBYTE DllBase, PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor)
Definition: shimeng.c:375
static const UNICODE_STRING Verifier
Definition: shimeng.c:25
PINEXCLUDE SeiFindInExclude(PARRAY InExclude, PCUNICODE_STRING DllName)
Definition: shimeng.c:797
BOOL WINAPI SE_DynamicShim(LPCWSTR ProcessImage, HSDB hsdb, PVOID pQueryResult, LPCSTR Module, LPDWORD lpdwDynamicToken)
Definition: shimeng.c:1487
VOID NotifyShims(DWORD dwReason, PVOID Info)
Definition: shimeng.c:255
PSHIMINFO SeiAppendHookInfo(PSHIMMODULE pShimModuleInfo, PHOOKAPIEX pHookApi, DWORD dwHookCount, PCWSTR ShimName)
Definition: shimeng.c:327
VOID SeiAddInternalHooks(DWORD dwNumHooks)
Definition: shimeng.c:751
static DWORD SeiGetDWORD(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:410
#define WINSXS
VOID SeiBuildGlobalInclExclList(HSDB hsdb)
Definition: shimeng.c:915
static PVOID ARRAY_AtWorker(PARRAY Array, DWORD ItemSize, DWORD n)
Definition: shimeng.c:109
VOID SeiCheckComPlusImage(PVOID BaseAddress)
Definition: shimeng.c:271
static UNICODE_STRING g_LoadingShimDll
Definition: shimeng.c:31
#define ARRAY_Init(Array, TypeOfArray)
Definition: shimeng.c:122
VOID SeiResetEntryProcessed(PPEB Peb)
Definition: shimeng.c:1156
PVOID SeiGetModuleFromAddress(PVOID addr)
Definition: shimeng.c:246
static UNICODE_STRING g_System32Directory
Definition: shimeng.c:29
static const UNICODE_STRING Ntdll
Definition: shimeng.c:23
VOID SeiResolveAPI(PHOOKMODULEINFO HookModuleInfo)
Definition: shimeng.c:665
FARPROC WINAPI StubGetProcAddress(HINSTANCE hModule, LPCSTR lpProcName)
Definition: shimeng.c:628
BOOLEAN NTAPI LdrInitShimEngineDynamic(IN PVOID BaseAddress)
Definition: ldrapi.c:1690
BOOL SeiGetShimData(PUNICODE_STRING ProcessImage, PVOID pShimData, HSDB *pHsdb, SDBQUERYRESULT *pQuery)
Definition: shimeng.c:1367
VOID SeiPatchNewImport(PIMAGE_THUNK_DATA FirstThunk, PHOOKAPIEX HookApi, PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:764
VOID SeiReadInExclude(PDB pdb, TAGID parent, PARRAY dest)
Definition: shimeng.c:889
#define ARRAY_Append(Array, TypeOfArray)
Definition: shimeng.c:123
BOOL g_bInternalHooksUsed
Definition: shimeng.c:36
BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format,...)
Definition: shimeng.c:160
LPCSTR SeiPrintFunctionName(LPCSTR lpProcName, char szOrdProcFmt[10])
Definition: shimeng.c:218
VOID PatchNewModules(PPEB Peb)
Definition: shimeng.c:1065
static PVOID ARRAY_AppendWorker(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
Definition: shimeng.c:95
static VOID SeiBuildShimRefArray(HSDB hsdb, SDBQUERYRESULT *pQuery, PARRAY pShimRef, PFLAGINFO pFlagInfo)
Definition: shimeng.c:474
static UNICODE_STRING g_SxsDirectory
Definition: shimeng.c:30
VOID SeiBuildInclExclList(PDB pdb, TAGID ShimTag, PSHIMINFO pShimInfo)
Definition: shimeng.c:942
static UNICODE_STRING g_WindowsDirectory
Definition: shimeng.c:28
PSHIMMODULE SeiCreateShimModuleInfo(PCWSTR DllName, PVOID BaseAddress)
Definition: shimeng.c:294
static LPCWSTR SeiGetStringPtr(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:401
int SeiCompareFunctionName(LPCSTR lpProcName1, LPCSTR lpProcName2)
Definition: shimeng.c:228
VOID SeiInitPaths(VOID)
Definition: shimeng.c:1083
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1436
#define SYSTEM32
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1417
static ARRAY g_InExclude
Definition: shimeng.c:39
static VOID SeiAddShim(TAGREF trShimRef, PARRAY pShimRef)
Definition: shimeng.c:428
static BOOL SeiIsOrdinalName(LPCSTR lpProcName)
Definition: shimeng.c:213
BOOL g_bShimDuringInit
Definition: shimeng.c:34
VOID SeiResolveAPIs(VOID)
Definition: shimeng.c:711
BOOL WINAPI SE_IsShimDll(PVOID BaseAddress)
Definition: shimeng.c:1474
VOID SeiInitDebugSupport(VOID)
Definition: shimeng.c:128
static BOOL ARRAY_EnsureSize(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
Definition: shimeng.c:64
#define ARRAY_Size(Array)
Definition: shimeng.c:125
ULONG g_ShimEngDebugLevel
Definition: shimeng.c:32
BOOL g_bComPlusImage
Definition: shimeng.c:33
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
HMODULE g_hInstance
Definition: MainWindow.cpp:18
#define MAX_LAYER_LENGTH
Definition: shimeng.c:471
static VOID SeiSetLayerEnvVar(LPCWSTR wszLayer)
Definition: shimeng.c:456
VOID WINAPI SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1447
static VOID SeiAddFlag(PDB pdb, TAGID tiFlagRef, PFLAGINFO pFlagInfo)
Definition: shimeng.c:439
static BOOL ARRAY_InitWorker(PARRAY Array, DWORD ItemSize)
Definition: shimeng.c:55
static ARRAY g_pHookArray
Definition: shimeng.c:38
static const UNICODE_STRING Kernel32
Definition: shimeng.c:24
static QWORD SeiGetQWORD(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:419
VOID SeiSetEntryProcessed(PPEB Peb)
Definition: shimeng.c:1105
#define ARRAY_At(Array, TypeOfArray, at)
Definition: shimeng.c:124
static ARRAY g_pShimInfo
Definition: shimeng.c:37
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1465
BOOL g_bShimEngInitialized
Definition: shimeng.c:35
VOID SeiInit(LPCWSTR ProcessImage, HSDB hsdb, SDBQUERYRESULT *pQuery, BOOLEAN ProcessInit)
Definition: shimeng.c:1185
VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:958
PSHIMMODULE SeiGetShimModuleInfo(PVOID BaseAddress)
Definition: shimeng.c:280
VOID SeiAddHooks(PHOOKAPIEX hooks, DWORD dwHookCount, PSHIMINFO pShim)
Definition: shimeng.c:556
FARPROC(WINAPI * GETPROCADDRESSPROC)(HINSTANCE, LPCSTR)
Definition: shimeng.c:41
#define SeiAlloc(size)
Definition: shimeng.h:101
#define SeiFree(mem)
Definition: shimeng.h:103
@ SEI_FAIL
Definition: shimlib.h:59
@ SEI_MSG
Definition: shimlib.h:58
@ SEI_INFO
Definition: shimlib.h:61
@ SEI_WARN
Definition: shimlib.h:60
#define SHIM_REASON_DLL_UNLOAD
Definition: shimlib.h:48
#define SHIM_REASON_DLL_LOAD
Definition: shimlib.h:47
#define SHIM_NOTIFY_DETACH
Definition: shimlib.h:51
enum _SEI_LOG_LEVEL SEI_LOG_LEVEL
#define SHIM_NOTIFY_ATTACH
Definition: shimlib.h:50
HRESULT hr
Definition: shlfolder.c:183
STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:650
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:575
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
std::string Name
Definition: xml2sdb.h:101
base of all file and directory entries
Definition: entries.h:83
Definition: xml2sdb.h:80
std::string Module
Definition: xml2sdb.h:37
bool Include
Definition: xml2sdb.h:38
Definition: shimeng.h:16
PVOID Data__
Definition: shimeng.h:17
DWORD Size__
Definition: shimeng.h:18
DWORD ItemSize__
Definition: shimeng.h:20
DWORD MaxSize__
Definition: shimeng.h:19
ULONG ProcessParameters_Flags
Definition: shimeng.h:81
ULARGE_INTEGER AppCompatFlagsUser
Definition: shimeng.h:80
ULARGE_INTEGER AppCompatFlags
Definition: shimeng.h:79
PVOID BaseAddress
Definition: shimeng.h:71
UNICODE_STRING Name
Definition: shimeng.h:70
ARRAY HookApis
Definition: shimeng.h:73
union _IMAGE_THUNK_DATA32::@2130 u1
BOOL Include
Definition: shimeng.h:45
UNICODE_STRING Module
Definition: shimeng.h:44
Definition: btrfs_drv.h:1876
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
ULARGE_INTEGER AppCompatFlagsUser
Definition: winternl.h:350
ULARGE_INTEGER AppCompatFlags
Definition: winternl.h:349
Definition: apphelp.h:30
PHOOKAPIEX pHookApi
Definition: shimeng.h:51
DWORD dwHookCount
Definition: shimeng.h:52
PCWSTR ShimName
Definition: shimeng.h:50
ARRAY InExclude
Definition: shimeng.h:54
PVOID BaseAddress
Definition: shimeng.h:60
ARRAY EnabledShims
Definition: shimeng.h:65
Definition: fs_rec.h:143
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
PHOOKAPIEX ApiLink
Definition: shimeng.h:36
PCSTR LibraryName
Definition: shimeng.h:31
PVOID ReplacementFunction
Definition: shimeng.h:33
PSHIMINFO pShimInfo
Definition: shimeng.h:35
PVOID OriginalFunction
Definition: shimeng.h:34
PCSTR FunctionName
Definition: shimeng.h:32
DWORD dwLayerCount
Definition: apphelp.h:71
TAGREF atrLayers[SDB_MAX_LAYERS]
Definition: apphelp.h:67
DWORD dwExeCount
Definition: apphelp.h:70
TAGREF atrExes[SDB_MAX_EXES]
Definition: apphelp.h:65
Definition: ecma_167.h:138
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
HANDLE HINSTANCE
Definition: typedefs.h:77
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
CONST char * PCSZ
Definition: umtypes.h:125
#define TAG_NAME
Definition: vfat.h:553
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define WINAPI
Definition: msvc.h:6
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185