ReactOS 0.4.16-dev-2104-gb84fa49
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
958{
959 DWORD dwFound = 0;
960
961 for (; OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function; OriginalThunk++, FirstThunk++)
962 {
963 if (!IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Function) && !SeiIsOrdinalName(HookApi->FunctionName))
964 {
965 PIMAGE_IMPORT_BY_NAME ImportName;
966
967 ImportName = (PIMAGE_IMPORT_BY_NAME)((PBYTE)LdrEntry->DllBase + OriginalThunk->u1.Function);
968 if (!strcmp((PCSTR)ImportName->Name, HookApi->FunctionName))
969 {
970 SeiPatchNewImport(FirstThunk, HookApi, LdrEntry);
971 dwFound++;
972 }
973 }
974 else
975 {
976 if (SeiIsOrdinalName(HookApi->FunctionName) && ((PCSTR)IMAGE_ORDINAL(OriginalThunk->u1.Function) == HookApi->FunctionName))
977 {
978 SeiPatchNewImport(FirstThunk, HookApi, LdrEntry);
979 dwFound++;
980 }
981 }
982 }
983
984 return dwFound;
985}
986
988{
989 DWORD dwFound = 0;
990
991 for (; FirstThunk->u1.Function; FirstThunk++)
992 {
993 if ((PULONG_PTR)FirstThunk->u1.Function == HookApi->OriginalFunction)
994 {
995 SeiPatchNewImport(FirstThunk, HookApi, LdrEntry);
996 dwFound++;
997 }
998 }
999
1000 return dwFound;
1001}
1002
1003/* Given one loaded module, redirect (hook) all functions from the iat that are registered by shims */
1005{
1006 BOOLEAN HasImportNameTable;
1007 ULONG Size;
1008 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1009 PBYTE DllBase = LdrEntry->DllBase;
1010
1011 if (SE_IsShimDll(DllBase) ||
1012 g_hInstance == LdrEntry->DllBase ||
1014 {
1015 SHIMENG_INFO("Skipping shim module 0x%p \"%wZ\"\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1016 return;
1017 }
1018
1019 if (LdrEntry->Flags & LDRP_COMPAT_DATABASE_PROCESSED)
1020 {
1021 SHIMENG_INFO("Skipping module 0x%p \"%wZ\" because it was already processed\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1022 return;
1023 }
1024
1026 if (!ImportDescriptor)
1027 {
1028 SHIMENG_INFO("Skipping module 0x%p \"%wZ\" due to no iat found\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1029 return;
1030 }
1031
1032 SHIMENG_INFO("Hooking module 0x%p \"%wZ\"\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1033
1034 HasImportNameTable = ImportDescriptor->OriginalFirstThunk;
1035 if (!HasImportNameTable)
1036 {
1037 /* Some PEs (eg. built with Borland toolchain or compressed with UPX) may not have an import name table.
1038 * In that case we have to rely solely on an import address table. */
1039 SHIMENG_INFO("Module 0x%p \"%wZ\" does not have an import name table\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1040 }
1041
1042 for ( ;ImportDescriptor->Name && (HasImportNameTable ? ImportDescriptor->OriginalFirstThunk : ImportDescriptor->FirstThunk); ImportDescriptor++)
1043 {
1044 PHOOKMODULEINFO HookModuleInfo;
1045
1046 /* Do we have hooks for this module? */
1047 HookModuleInfo = SeiFindHookModuleInfoForImportDescriptor(DllBase, ImportDescriptor);
1048
1049 if (HookModuleInfo)
1050 {
1051 PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
1052 DWORD n;
1053
1054 for (n = 0; n < ARRAY_Size(&HookModuleInfo->HookApis); ++n)
1055 {
1056 DWORD dwFound;
1057 PHOOKAPIEX HookApi = *ARRAY_At(&HookModuleInfo->HookApis, PHOOKAPIEX, n);
1058
1059 /* Check if this module should be excluded from being hooked (system32/winsxs, global or shim exclude) */
1060 if (SeiIsExcluded(LdrEntry, HookApi))
1061 {
1062 continue;
1063 }
1064
1065 FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
1066
1067 if (HasImportNameTable)
1068 {
1069 OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
1070 dwFound = SeiPatchImportsByName(OriginalThunk, FirstThunk, HookApi, LdrEntry);
1071 }
1072 else
1073 {
1074 dwFound = SeiPatchImportsByAddress(FirstThunk, HookApi, LdrEntry);
1075 }
1076
1077 /* Sadly, IAT does not have to be sorted, and can even contain duplicate entries. */
1078 if (dwFound != 1)
1079 {
1080 char szOrdProcFmt[10];
1081 LPCSTR FuncName = SeiPrintFunctionName(HookApi->FunctionName, szOrdProcFmt);
1082
1083 /* One entry not found. */
1084 if (!dwFound)
1085 SHIMENG_INFO("Entry \"%s!%s\" not found for \"%wZ\"\n", HookApi->LibraryName, FuncName, &LdrEntry->BaseDllName);
1086 else
1087 SHIMENG_INFO("Entry \"%s!%s\" found %d times for \"%wZ\"\n", HookApi->LibraryName, FuncName, dwFound, &LdrEntry->BaseDllName);
1088 }
1089 }
1090 }
1091 }
1092
1093 /* Mark this module as processed. */
1095}
1096
1097
1099{
1100 PLIST_ENTRY ListHead, ListEntry;
1101 PLDR_DATA_TABLE_ENTRY LdrEntry;
1102
1103 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1104 ListEntry = ListHead->Flink;
1105
1106 while (ListHead != ListEntry)
1107 {
1108 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1109 SeiHookImports(LdrEntry);
1110
1111 ListEntry = ListEntry->Flink;
1112 }
1113}
1114
1115
1117{
1118#define SYSTEM32 L"\\system32"
1119#define WINSXS L"\\winsxs"
1120
1121 PWSTR WindowsDirectory = SdbpStrDup(SharedUserData->NtSystemRoot);
1122 RtlInitUnicodeString(&g_WindowsDirectory, WindowsDirectory);
1123
1128
1133
1134#undef SYSTEM32
1135#undef WINSXS
1136}
1137
1139{
1140 PLIST_ENTRY ListHead, Entry;
1141 PLDR_DATA_TABLE_ENTRY LdrEntry;
1142
1143 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1144 Entry = ListHead->Flink;
1145 while (Entry != ListHead)
1146 {
1147 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1148 Entry = Entry->Flink;
1149
1150 if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &Ntdll, TRUE) ||
1154 SE_IsShimDll(LdrEntry->DllBase) ||
1155 (LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
1156 {
1157 SHIMENG_WARN("Don't mess with 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1158 }
1159 else
1160 {
1161 SHIMENG_WARN("Touching 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1162 LdrEntry->Flags |= (LDRP_ENTRY_PROCESSED | LDRP_SHIMENG_SUPPRESSED_ENTRY);
1163 }
1164 }
1165
1166 ListHead = &NtCurrentPeb()->Ldr->InMemoryOrderModuleList;
1167 Entry = ListHead->Flink;
1168 SHIMENG_INFO("In memory:\n");
1169 while (Entry != ListHead)
1170 {
1171 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
1172 Entry = Entry->Flink;
1173
1174 SHIMENG_INFO(" 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1175 }
1176
1177 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1178 Entry = ListHead->Flink;
1179 SHIMENG_INFO("In load:\n");
1180 while (Entry != ListHead)
1181 {
1182 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1183 Entry = Entry->Flink;
1184
1185 SHIMENG_INFO(" 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1186 }
1187}
1188
1190{
1191 PLIST_ENTRY ListHead, Entry;
1192 PLDR_DATA_TABLE_ENTRY LdrEntry;
1193
1194 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1195 Entry = ListHead->Flink;
1196 while (Entry != ListHead)
1197 {
1198 LdrEntry = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1199 Entry = Entry->Flink;
1200
1201 if (SE_IsShimDll(LdrEntry->DllBase) ||
1202 g_hInstance == LdrEntry->DllBase ||
1206 !(LdrEntry->Flags & LDRP_SHIMENG_SUPPRESSED_ENTRY))
1207 {
1208 SHIMENG_WARN("Don't mess with 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1209 }
1210 else
1211 {
1212 SHIMENG_WARN("Resetting 0x%p '%wZ'\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
1213 LdrEntry->Flags &= ~(LDRP_ENTRY_PROCESSED | LDRP_SHIMENG_SUPPRESSED_ENTRY);
1214 }
1215 }
1216}
1217
1218VOID SeiInit(LPCWSTR ProcessImage, HSDB hsdb, SDBQUERYRESULT* pQuery, BOOLEAN ProcessInit)
1219{
1220 DWORD n;
1221 ARRAY ShimRefArray;
1222 DWORD dwTotalHooks = 0;
1223 FLAGINFO ShimFlags;
1224
1225 PPEB Peb = NtCurrentPeb();
1226
1227 /* We should only be called once! */
1229
1230 ARRAY_Init(&ShimRefArray, TAGREF);
1234 RtlZeroMemory(&ShimFlags, sizeof(ShimFlags));
1235
1236 SeiInitPaths();
1237
1239
1240 if (ProcessInit)
1241 {
1242 /* Mark all modules loaded until now as 'LDRP_ENTRY_PROCESSED' so that their entrypoint is not called while we are loading shims */
1244 }
1245
1246 /* TODO:
1247 if (pQuery->trApphelp)
1248 SeiDisplayAppHelp(?pQuery->trApphelp?);
1249 */
1250
1251 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(ExePath(%S))\n", ProcessImage);
1252 SeiBuildShimRefArray(hsdb, pQuery, &ShimRefArray, &ShimFlags);
1253 if (ShimFlags.AppCompatFlags.QuadPart)
1254 {
1255 SeiDbgPrint(SEI_MSG, NULL, "Using KERNEL apphack flags 0x%llx\n", ShimFlags.AppCompatFlags.QuadPart);
1257 }
1258 if (ShimFlags.AppCompatFlagsUser.QuadPart)
1259 {
1260 SeiDbgPrint(SEI_MSG, NULL, "Using USER apphack flags 0x%llx\n", ShimFlags.AppCompatFlagsUser.QuadPart);
1262 }
1263 if (ShimFlags.ProcessParameters_Flags)
1264 {
1265 SeiDbgPrint(SEI_MSG, NULL, "Using ProcessParameters flags 0x%x\n", ShimFlags.ProcessParameters_Flags);
1267 }
1268 SeiDbgPrint(SEI_MSG, NULL, "ShimInfo(Complete)\n");
1269
1270 SHIMENG_INFO("Got %d shims\n", ARRAY_Size(&ShimRefArray));
1272
1273 /* Walk all shims referenced (in layers + exes), and load their modules */
1274 for (n = 0; n < ARRAY_Size(&ShimRefArray); ++n)
1275 {
1276 PDB pdb;
1277 TAGID ShimRef;
1278
1279 TAGREF tr = *ARRAY_At(&ShimRefArray, TAGREF, n);
1280
1281 if (SdbTagRefToTagID(hsdb, tr, &pdb, &ShimRef))
1282 {
1283 LPCWSTR ShimName, DllName, CommandLine = NULL;
1284 TAGID ShimTag;
1285 WCHAR FullNameBuffer[MAX_PATH];
1286 UNICODE_STRING UnicodeDllName;
1288 PSHIMMODULE pShimModuleInfo = NULL;
1289 ANSI_STRING AnsiCommandLine = RTL_CONSTANT_STRING("");
1290 PSHIMINFO pShimInfo = NULL;
1291 PHOOKAPIEX pHookApi;
1292 DWORD dwHookCount;
1293
1294 ShimName = SeiGetStringPtr(pdb, ShimRef, TAG_NAME);
1295 if (!ShimName)
1296 {
1297 SHIMENG_FAIL("Failed to retrieve the name for 0x%x\n", tr);
1298 continue;
1299 }
1300
1302 if (CommandLine && *CommandLine)
1303 {
1304 RtlInitUnicodeString(&UnicodeDllName, CommandLine);
1305 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiCommandLine, &UnicodeDllName, TRUE)))
1306 {
1307 SHIMENG_INFO("COMMAND LINE %s for %S", AnsiCommandLine.Buffer, ShimName);
1308 }
1309 else
1310 {
1311 AnsiCommandLine.Buffer = "";
1312 CommandLine = NULL;
1313 }
1314 }
1315
1317 if (!ShimTag)
1318 {
1319 SHIMENG_FAIL("Failed to resolve %S to a shim\n", ShimName);
1320 continue;
1321 }
1322
1323 if (!SUCCEEDED(SdbGetAppPatchDir(NULL, FullNameBuffer, ARRAYSIZE(FullNameBuffer))))
1324 {
1325 SHIMENG_WARN("Failed to get the AppPatch dir\n");
1326 continue;
1327 }
1328
1329 DllName = SeiGetStringPtr(pdb, ShimTag, TAG_DLLFILE);
1330 if (DllName == NULL ||
1331 !SUCCEEDED(StringCchCatW(FullNameBuffer, ARRAYSIZE(FullNameBuffer), L"\\")) ||
1332 !SUCCEEDED(StringCchCatW(FullNameBuffer, ARRAYSIZE(FullNameBuffer), DllName)))
1333 {
1334 SHIMENG_WARN("Failed to build a full path for %S\n", ShimName);
1335 continue;
1336 }
1337
1339 RtlInitUnicodeString(&UnicodeDllName, FullNameBuffer);
1340 if (NT_SUCCESS(LdrGetDllHandle(NULL, NULL, &UnicodeDllName, &BaseAddress)))
1341 {
1342 /* This shim dll was already loaded, let's find it */
1343 pShimModuleInfo = SeiGetShimModuleInfo(BaseAddress);
1344 }
1345 else if (!NT_SUCCESS(LdrLoadDll(NULL, NULL, &UnicodeDllName, &BaseAddress)))
1346 {
1347 SHIMENG_WARN("Failed to load %wZ for %S\n", &UnicodeDllName, ShimName);
1348 continue;
1349 }
1351 /* No shim module found (or we just loaded it) */
1352 if (!pShimModuleInfo)
1353 {
1354 pShimModuleInfo = SeiCreateShimModuleInfo(DllName, BaseAddress);
1355 if (!pShimModuleInfo)
1356 {
1357 SHIMENG_FAIL("Failed to allocate ShimInfo for %S\n", DllName);
1358 continue;
1359 }
1360 }
1361
1362 SHIMENG_INFO("Shim DLL 0x%p \"%wZ\" loaded\n", BaseAddress, &UnicodeDllName);
1363 SHIMENG_INFO("Using SHIM \"%S!%S\"\n", DllName, ShimName);
1364
1365 /* Ask this shim what hooks it needs (and pass along the commandline) */
1366 dwHookCount = 0;
1367 pHookApi = pShimModuleInfo->pGetHookAPIs(AnsiCommandLine.Buffer, ShimName, &dwHookCount);
1368 SHIMENG_INFO("GetHookAPIs returns %d hooks for DLL \"%wZ\" SHIM \"%S\"\n", dwHookCount, &UnicodeDllName, ShimName);
1369 if (dwHookCount && pHookApi)
1370 pShimInfo = SeiAppendHookInfo(pShimModuleInfo, pHookApi, dwHookCount, ShimName);
1371 else
1372 dwHookCount = 0;
1373
1374 /* If this shim has hooks, create the include / exclude lists */
1375 if (pShimInfo)
1376 SeiBuildInclExclList(pdb, ShimTag, pShimInfo);
1377
1378 if (CommandLine && *CommandLine)
1379 RtlFreeAnsiString(&AnsiCommandLine);
1380
1381 dwTotalHooks += dwHookCount;
1382 }
1383 }
1384
1385 SeiAddInternalHooks(dwTotalHooks);
1389
1390 if (ProcessInit)
1391 {
1392 /* Remove the 'LDRP_ENTRY_PROCESSED' flag from entries we modified, so that the loader can continue to process them */
1394 }
1396}
1397
1398
1399/* Load the database + unpack the shim data (if this process is allowed) */
1400BOOL SeiGetShimData(PUNICODE_STRING ProcessImage, PVOID pShimData, HSDB* pHsdb, SDBQUERYRESULT* pQuery)
1401{
1402 static const UNICODE_STRING ForbiddenShimmingApps[] = {
1403 RTL_CONSTANT_STRING(L"ntsd.exe"),
1404 RTL_CONSTANT_STRING(L"windbg.exe"),
1405#if WINVER >= 0x600
1406 RTL_CONSTANT_STRING(L"slsvc.exe"),
1407#endif
1408 };
1409 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
1410 UNICODE_STRING ProcessName;
1411 USHORT PathDivider;
1412 HSDB hsdb;
1413 DWORD n;
1414
1415 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, ProcessImage, &PathDividerFind, &PathDivider)))
1416 PathDivider = 0;
1417
1418 if (PathDivider)
1419 PathDivider += sizeof(WCHAR);
1420
1421 ProcessName.Buffer = ProcessImage->Buffer + PathDivider / sizeof(WCHAR);
1422 ProcessName.Length = ProcessImage->Length - PathDivider;
1423 ProcessName.MaximumLength = ProcessImage->MaximumLength - PathDivider;
1424
1425 for (n = 0; n < ARRAYSIZE(ForbiddenShimmingApps); ++n)
1426 {
1427 if (RtlEqualUnicodeString(&ProcessName, ForbiddenShimmingApps + n, TRUE))
1428 {
1429 SHIMENG_MSG("Not shimming %wZ\n", ForbiddenShimmingApps + n);
1430 return FALSE;
1431 }
1432 }
1433
1434 /* We should probably load all db's here, but since we do not support that yet... */
1436 if (hsdb)
1437 {
1438 if (SdbUnpackAppCompatData(hsdb, ProcessImage->Buffer, pShimData, pQuery))
1439 {
1440 *pHsdb = hsdb;
1441 return TRUE;
1442 }
1443 SdbReleaseDatabase(hsdb);
1444 }
1445 return FALSE;
1446}
1447
1448
1449
1451{
1452 HSDB hsdb = NULL;
1453 SDBQUERYRESULT QueryResult = { { 0 } };
1454 SHIMENG_INFO("(%wZ, %p)\n", ProcessImage, pShimData);
1455
1456 if (!SeiGetShimData(ProcessImage, pShimData, &hsdb, &QueryResult))
1457 {
1458 SHIMENG_FAIL("Failed to get shim data\n");
1459 return;
1460 }
1461
1463 SeiInit(ProcessImage->Buffer, hsdb, &QueryResult, TRUE);
1465
1466 SdbReleaseDatabase(hsdb);
1467}
1468
1470{
1472}
1473
1475{
1476 SHIMENG_MSG("()\n");
1478}
1479
1481{
1482 PHOOKMODULEINFO HookModuleInfo;
1483 SHIMENG_INFO("%sINIT. loading DLL \"%wZ\"\n", g_bShimDuringInit ? "" : "AFTER ", &LdrEntry->BaseDllName);
1484
1485 HookModuleInfo = SeiFindHookModuleInfo(&LdrEntry->BaseDllName, NULL);
1486 if (HookModuleInfo)
1487 {
1488 ASSERT(HookModuleInfo->BaseAddress == NULL);
1489 HookModuleInfo->BaseAddress = LdrEntry->DllBase;
1490 SeiResolveAPI(HookModuleInfo);
1491 }
1492
1493 SeiHookImports(LdrEntry);
1494
1496}
1497
1499{
1500 SHIMENG_INFO("(%p)\n", LdrEntry);
1501
1502 /* Should we unhook here? */
1503
1505}
1506
1508{
1509 SHIMENG_INFO("(%p)\n", BaseAddress);
1510
1512}
1513
1514/* 'Private' ntdll function */
1515BOOLEAN
1516NTAPI
1518
1519
1520BOOL WINAPI SE_DynamicShim(LPCWSTR ProcessImage, HSDB hsdb, PVOID pQueryResult, LPCSTR Module, LPDWORD lpdwDynamicToken)
1521{
1523 {
1524 SHIMENG_MSG("ReactOS HACK(CORE-13283): ShimEng already initialized!\n");
1525 return TRUE;
1526 }
1527
1529 SeiInit(ProcessImage, hsdb, pQueryResult, FALSE);
1531
1533
1534 return TRUE;
1535}
1536
#define NtCurrentPeb()
Definition: FLS.c:22
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
unsigned char BOOLEAN
@ hook
Definition: SystemMenu.c:35
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:645
#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:586
BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF *ptrWhich)
Definition: hsdb.c:676
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:768
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:135
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:661
Definition: bufpool.h:45
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static PDB pdb
Definition: db.cpp:173
#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:33
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:658
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
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
char * va_list
Definition: vadefs.h:50
@ AnsiString
Definition: dnslib.h:19
#define L(x)
Definition: resources.c:13
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
#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:770
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:789
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:48
#define LDRP_COMPAT_DATABASE_PROCESSED
Definition: ldrtypes.h:65
#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)
HMODULE hModule
Definition: netsh.c:17
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:1660
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:1311
_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:3076
#define STRSAFE_NULL_ON_FAILURE
Definition: ntstrsafe.h:34
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:1520
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
DWORD SeiPatchImportsByAddress(PIMAGE_THUNK_DATA FirstThunk, PHOOKAPIEX HookApi, PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:987
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
DWORD SeiPatchImportsByName(PIMAGE_THUNK_DATA OriginalThunk, PIMAGE_THUNK_DATA FirstThunk, PHOOKAPIEX HookApi, PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:957
#define ARRAY_Init(Array, TypeOfArray)
Definition: shimeng.c:122
VOID SeiResetEntryProcessed(PPEB Peb)
Definition: shimeng.c:1189
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:1649
BOOL SeiGetShimData(PUNICODE_STRING ProcessImage, PVOID pShimData, HSDB *pHsdb, SDBQUERYRESULT *pQuery)
Definition: shimeng.c:1400
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:1098
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:1116
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1469
#define SYSTEM32
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1450
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:1507
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:1474
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:1480
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:1138
#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:1498
BOOL g_bShimEngInitialized
Definition: shimeng.c:35
VOID SeiInit(LPCWSTR ProcessImage, HSDB hsdb, SDBQUERYRESULT *pQuery, BOOLEAN ProcessInit)
Definition: shimeng.c:1218
VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1004
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:114
base of all file and directory entries
Definition: entries.h:83
Definition: xml2sdb.h:97
std::string Module
Definition: xml2sdb.h:59
bool Include
Definition: xml2sdb.h:60
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::@2328 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:149
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:542
ULARGE_INTEGER AppCompatFlags
Definition: winternl.h:541
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
uint32_t * PULONG_PTR
Definition: typedefs.h:65
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:4539
_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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180