ReactOS  0.4.15-dev-5500-g82cf6c2
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 
23 static const UNICODE_STRING Ntdll = RTL_CONSTANT_STRING(L"ntdll.dll");
24 static const UNICODE_STRING Kernel32 = RTL_CONSTANT_STRING(L"kernel32.dll");
25 static const UNICODE_STRING Verifier = RTL_CONSTANT_STRING(L"verifier.dll");
26 
27 extern HMODULE g_hInstance;
37 static ARRAY g_pShimInfo; /* PSHIMMODULE */
38 static ARRAY g_pHookArray; /* HOOKMODULEINFO */
39 static 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 
55 static inline BOOL ARRAY_InitWorker(PARRAY Array, DWORD ItemSize)
56 {
57  Array->Data__ = NULL;
58  Array->Size__ = Array->MaxSize__ = 0;
59  Array->ItemSize__ = ItemSize;
60 
61  return TRUE;
62 }
63 
64 static inline BOOL ARRAY_EnsureSize(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
65 {
66  PVOID pNewData;
67  DWORD Count;
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 
95 static inline PVOID ARRAY_AppendWorker(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
96 {
97  PBYTE pData;
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 
212 static
214 {
215  return (ULONG_PTR)lpProcName <= MAXUSHORT;
216 }
217 
218 LPCSTR 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 
228 int 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 {
248  PVOID hModule = NULL;
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 
327 PSHIMINFO SeiAppendHookInfo(PSHIMMODULE pShimModuleInfo, PHOOKAPIEX pHookApi, DWORD dwHookCount, PCWSTR ShimName)
328 {
329  PSHIMINFO* pData, Data;
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 
428 static 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 
439 static 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 */
474 static 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 */
556 VOID 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);
573  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeModName, &AnsiString, FALSE)))
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  {
734  PSHIMMODULE pShimModule = *ARRAY_At(&g_pShimInfo, PSHIMMODULE, mod);
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
883 FIXME:
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  {
904  SeiAppendInExclude(dest, ModuleName, IncludeTag != TAGID_NULL);
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 
972  if (LdrEntry->Flags & LDRP_COMPAT_DATABASE_PROCESSED)
973  {
974  SHIMENG_INFO("Skipping module 0x%p \"%wZ\" because it was already processed\n", LdrEntry->DllBase, &LdrEntry->BaseDllName);
975  return;
976  }
977 
978  ImportDescriptor = RtlImageDirectoryEntryToData(DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
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 ||
1170  RtlEqualUnicodeString(&LdrEntry->BaseDllName, &Ntdll, TRUE) ||
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 
1185 VOID 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 
1268  CommandLine = SeiGetStringPtr(pdb, ShimRef, TAG_COMMAND_LINE);
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 
1283  ShimTag = SeiGetDWORD(pdb, ShimRef, TAG_SHIM_TAGID);
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);
1354  SeiResolveAPIs();
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) */
1367 BOOL 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 
1462  NotifyShims(SHIM_REASON_DLL_LOAD, LdrEntry);
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 */
1482 BOOLEAN
1483 NTAPI
1485 
1486 
1487 BOOL 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 RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END
Definition: rtl.h:25
VOID SeiResetEntryProcessed(PPEB Peb)
Definition: shimeng.c:1156
WCHAR * ExeName
PSHIMMODULE SeiGetShimModuleInfo(PVOID BaseAddress)
Definition: shimeng.c:280
CONST char * PCSZ
Definition: umtypes.h:125
DWORD TAGREF
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define WINSXS
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
UNICODE_STRING Name
Definition: shimeng.h:70
static BOOL ARRAY_InitWorker(PARRAY Array, DWORD ItemSize)
Definition: shimeng.c:55
#define TAG_NAME
Definition: vfat.h:553
VOID SeiAppendInExclude(PARRAY dest, PCWSTR ModuleName, BOOL IsInclude)
Definition: shimeng.c:860
#define TAG_INCLUDE
Definition: db.cpp:56
NTSTATUS NTAPI LdrGetDllHandle(IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
Definition: ldrapi.c:805
static ARRAY g_pShimInfo
Definition: shimeng.c:37
PPEB Peb
Definition: dllmain.c:27
static PDB pdb
Definition: db.cpp:172
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
static ARRAY g_InExclude
Definition: shimeng.c:39
ARRAY HookApis
Definition: shimeng.h:73
#define TAG_LIBRARY
Definition: sdbtagid.h:164
#define DbgPrint
Definition: hal.h:12
HRESULT hr
Definition: shlfolder.c:183
struct _Entry Entry
Definition: kefuncs.h:629
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
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
#define TAGREF_ROOT
Definition: sdbtypes.h:22
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
VOID SeiInit(LPCWSTR ProcessImage, HSDB hsdb, SDBQUERYRESULT *pQuery, BOOLEAN ProcessInit)
Definition: shimeng.c:1185
VOID SeiResolveAPI(PHOOKMODULEINFO HookModuleInfo)
Definition: shimeng.c:665
VOID PatchNewModules(PPEB Peb)
Definition: shimeng.c:1065
PSHIMINFO SeiAppendHookInfo(PSHIMMODULE pShimModuleInfo, PHOOKAPIEX pHookApi, DWORD dwHookCount, PCWSTR ShimName)
Definition: shimeng.c:327
#define TAG_DATABASE
Definition: db.cpp:85
ULARGE_INTEGER AppCompatFlagsUser
Definition: winternl.h:350
BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format,...)
Definition: shimeng.c:160
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
struct _root root
DWORD WINAPI SdbReadDWORDTag(PDB pdb, TAGID tagid, DWORD ret)
Definition: sdbread.c:305
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
DWORD Size__
Definition: shimeng.h:18
HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR)
Definition: hsdb.c:369
ULONG ProcessParameters_Flags
Definition: shimeng.h:81
TAGREF atrLayers[SDB_MAX_LAYERS]
Definition: apphelp.h:67
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3105
LONG NTSTATUS
Definition: precomp.h:26
bool Include
Definition: xml2sdb.h:38
VOID WINAPI SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1447
#define LDRP_SHIMENG_SUPPRESSED_ENTRY
Definition: ldrtypes.h:40
PHOOKMODULEINFO SeiFindHookModuleInfo(PUNICODE_STRING ModuleName, PVOID BaseAddress)
Definition: shimeng.c:352
HRESULT WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
Definition: hsdb.c:579
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1436
LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid)
Definition: sdbread.c:375
GLdouble n
Definition: glext.h:7729
static VOID SeiBuildShimRefArray(HSDB hsdb, SDBQUERYRESULT *pQuery, PARRAY pShimRef, PFLAGINFO pFlagInfo)
Definition: shimeng.c:474
ULONG g_ShimEngDebugLevel
Definition: shimeng.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
ULARGE_INTEGER AppCompatFlags
Definition: shimeng.h:79
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
Definition: ecma_167.h:138
#define TAG_COMMAND_LINE
Definition: db.cpp:102
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
BOOL SeiIsExcluded(PLDR_DATA_TABLE_ENTRY LdrEntry, PHOOKAPIEX HookApi)
Definition: shimeng.c:812
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:1278
static HANDLE proc()
Definition: pdb.c:34
#define TAG_FLAG_PROCESSPARAM
Definition: sdbtagid.h:124
#define ARRAY_Append(Array, TypeOfArray)
Definition: shimeng.c:123
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
#define SeiFree(mem)
Definition: shimeng.h:103
DWORD dwLayerCount
Definition: apphelp.h:71
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:659
FT_Library library
Definition: cffdrivr.c:654
LPCWSTR LPCWSTR LPCWSTR DWORD PSDBQUERYRESULT_VISTA pQueryResult
Definition: env.c:37
DWORD SdbpStrsize(PCWSTR string)
Definition: sdbapi.c:157
STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:575
PVOID BaseAddress
Definition: shimeng.h:60
LPVOID SdbpAlloc(SIZE_T size)
Definition: sdbapi.c:55
DWORD dwHookCount
Definition: shimeng.h:52
static BOOL SeiIsOrdinalName(LPCSTR lpProcName)
Definition: shimeng.c:213
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
BOOL g_bShimEngInitialized
Definition: shimeng.c:35
Definition: apphelp.h:30
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
static const UNICODE_STRING Verifier
Definition: shimeng.c:25
PHOOKAPI WINAPI GetHookAPIs(IN LPCSTR szCommandLine, IN LPCWSTR wszShimName, OUT PDWORD pdwHookCount)
Definition: main.c:15
PVOID BaseAddress
Definition: shimeng.h:71
#define SDB_DATABASE_MAIN_SHIM
Definition: apphelp.h:24
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
PVOID DllBase
Definition: btrfs_drv.h:1880
DWORD dwReason
Definition: misc.cpp:154
static const UNICODE_STRING Ntdll
Definition: shimeng.c:23
#define TAG_INEXCLUD
Definition: db.cpp:86
VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:958
PHOOKAPIEX pHookApi
Definition: shimeng.h:51
#define L(x)
Definition: ntvdm.h:50
#define TAG_DLLFILE
Definition: sdbtagid.h:137
VOID SeiInitPaths(VOID)
Definition: shimeng.c:1083
static PCWSTR wszLayer
Definition: layerapi.c:36
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define TAG_MODULE
Definition: db.cpp:99
#define va_end(ap)
Definition: acmsvcex.h:90
VOID SeiBuildInclExclList(PDB pdb, TAGID ShimTag, PSHIMINFO pShimInfo)
Definition: shimeng.c:942
#define SYSTEM32
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
BOOL WINAPI SE_DynamicShim(LPCWSTR ProcessImage, HSDB hsdb, PVOID pQueryResult, LPCSTR Module, LPDWORD lpdwDynamicToken)
Definition: shimeng.c:1487
static BOOL ARRAY_EnsureSize(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
Definition: shimeng.c:64
unsigned int BOOL
Definition: ntddk_ex.h:94
#define LDRP_COMPAT_DATABASE_PROCESSED
Definition: ldrtypes.h:61
int SeiCompareFunctionName(LPCSTR lpProcName1, LPCSTR lpProcName2)
Definition: shimeng.c:228
if SUCCEEDED(hr)
#define TAG_FLAG_MASK_KERNEL
Definition: sdbtagid.h:114
QWORD WINAPI SdbReadQWORDTag(PDB pdb, TAGID tagid, QWORD ret)
Definition: sdbread.c:321
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1417
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
unsigned char BOOLEAN
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable(_In_z_ PWSTR *Environment, _In_ PUNICODE_STRING Name, _In_ PUNICODE_STRING Value)
char * va_list
Definition: acmsvcex.h:78
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
Definition: bufpool.h:45
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
const char * LPCSTR
Definition: xmlstorage.h:183
VOID SeiSetEntryProcessed(PPEB Peb)
Definition: shimeng.c:1105
std::string Module
Definition: xml2sdb.h:37
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define SHIM_NOTIFY_ATTACH
Definition: shimlib.h:50
static UNICODE_STRING g_SxsDirectory
Definition: shimeng.c:30
#define NtCurrentProcess()
Definition: nt_native.h:1657
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
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
static UNICODE_STRING g_System32Directory
Definition: shimeng.c:29
TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:231
Status
Definition: gdiplustypes.h:24
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
union _IMAGE_THUNK_DATA32::@2092 u1
Definition: msg.h:42
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1465
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:185
#define TAG_SHIM_TAGID
Definition: sdbtagid.h:67
VOID SeiBuildGlobalInclExclList(HSDB hsdb)
Definition: shimeng.c:915
#define ASSERT(a)
Definition: mode.c:44
r parent
Definition: btrfs.c:3010
LPCSTR SeiPrintFunctionName(LPCSTR lpProcName, char szOrdProcFmt[10])
Definition: shimeng.c:218
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG HRESULT
Definition: typedefs.h:79
UNICODE_STRING Module
Definition: shimeng.h:44
UINT64 QWORD
Definition: shimdbg.c:104
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
Definition: xml2sdb.h:79
BOOL SeiGetShimData(PUNICODE_STRING ProcessImage, PVOID pShimData, HSDB *pHsdb, SDBQUERYRESULT *pQuery)
Definition: shimeng.c:1367
static const UNICODE_STRING Kernel32
Definition: shimeng.c:24
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
unsigned long DWORD
Definition: ntddk_ex.h:95
PCWSTR ShimName
Definition: shimeng.h:50
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
va_start(ap, x)
static tGETHOOKAPIS pGetHookAPIs
Definition: dispmode.c:26
BOOL Include
Definition: shimeng.h:45
#define TAG_FLAG_TAGID
Definition: sdbtagid.h:94
#define HID_DOS_PATHS
Definition: apphelp.h:19
TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag)
Definition: sdbread.c:208
HANDLE HINSTANCE
Definition: typedefs.h:77
PVOID OriginalFunction
Definition: shimeng.h:34
static UNICODE_STRING g_WindowsDirectory
Definition: shimeng.c:28
#define SharedUserData
#define ARRAY_Size(Array)
Definition: shimeng.c:125
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
VOID SeiAddInternalHooks(DWORD dwNumHooks)
Definition: shimeng.c:751
GLenum const GLvoid * addr
Definition: glext.h:9621
ULARGE_INTEGER AppCompatFlagsUser
Definition: shimeng.h:80
PCSTR LibraryName
Definition: shimeng.h:31
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define TAG_SHIM_REF
Definition: db.cpp:89
void WINAPI SdbReleaseDatabase(HSDB)
Definition: hsdb.c:417
Definition: btrfs_drv.h:1876
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
DWORD dwExeCount
Definition: apphelp.h:70
PVOID Data__
Definition: shimeng.h:17
BOOL g_bComPlusImage
Definition: shimeng.c:33
Definition: typedefs.h:119
BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF *ptrWhich)
Definition: hsdb.c:669
#define SHIM_NOTIFY_DETACH
Definition: shimlib.h:51
static UCHAR ItemSize[4]
Definition: parser.c:16
PWSTR SdbpStrDup(LPCWSTR string)
Definition: sdbapi.c:162
VOID SeiPatchNewImport(PIMAGE_THUNK_DATA FirstThunk, PHOOKAPIEX HookApi, PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:764
static PVOID ARRAY_AtWorker(PARRAY Array, DWORD ItemSize, DWORD n)
Definition: shimeng.c:109
ARRAY EnabledShims
Definition: shimeng.h:65
static QWORD SeiGetQWORD(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:419
std::string Name
Definition: xml2sdb.h:101
#define WINAPIV
Definition: sdbpapi.h:64
FARPROC WINAPI StubGetProcAddress(HINSTANCE hModule, LPCSTR lpProcName)
Definition: shimeng.c:628
TAGREF atrExes[SDB_MAX_EXES]
Definition: apphelp.h:65
FARPROC(WINAPI * GETPROCADDRESSPROC)(HINSTANCE, LPCSTR)
Definition: shimeng.c:41
PCSTR FunctionName
Definition: shimeng.h:32
static ARRAY g_pHookArray
Definition: shimeng.c:38
#define TAGID_NULL
Definition: db.cpp:38
enum _SEI_LOG_LEVEL SEI_LOG_LEVEL
static UNICODE_STRING g_LoadingShimDll
Definition: shimeng.c:31
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PHOOKAPIEX ApiLink
Definition: shimeng.h:36
static LPCWSTR SeiGetStringPtr(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:401
#define SHIM_REASON_DLL_UNLOAD
Definition: shimlib.h:48
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
PHOOKMODULEINFO SeiFindHookModuleInfoForImportDescriptor(PBYTE DllBase, PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor)
Definition: shimeng.c:375
#define NtCurrentPeb()
Definition: FLS.c:22
PSHIMINFO pShimInfo
Definition: shimeng.h:35
unsigned short USHORT
Definition: pedump.c:61
BOOL g_bShimDuringInit
Definition: shimeng.c:34
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define MAX_LAYER_LENGTH
Definition: shimeng.c:471
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
DWORD ItemSize__
Definition: shimeng.h:20
VOID SeiAddHooks(PHOOKAPIEX hooks, DWORD dwHookCount, PSHIMINFO pShim)
Definition: shimeng.c:556
VOID NotifyShims(DWORD dwReason, PVOID Info)
Definition: shimeng.c:255
#define NULL
Definition: types.h:112
ARRAY InExclude
Definition: shimeng.h:54
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
Definition: fs_rec.h:142
PVOID ReplacementFunction
Definition: shimeng.h:33
#define MAXUSHORT
Definition: typedefs.h:83
ULARGE_INTEGER AppCompatFlags
Definition: winternl.h:349
#define TAG_FLAG_REF
Definition: sdbtagid.h:183
static PVOID ARRAY_AppendWorker(PARRAY Array, DWORD ItemSize, DWORD GrowWith)
Definition: shimeng.c:95
PINEXCLUDE SeiFindInExclude(PARRAY InExclude, PCUNICODE_STRING DllName)
Definition: shimeng.c:797
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
VOID SeiReadInExclude(PDB pdb, TAGID parent, PARRAY dest)
Definition: shimeng.c:889
VOID SeiResolveAPIs(VOID)
Definition: shimeng.c:711
void * _ReturnAddress(void)
Definition: shimeng.h:15
#define STRSAFE_NULL_ON_FAILURE
Definition: ntstrsafe.h:34
#define ARRAY_Init(Array, TypeOfArray)
Definition: shimeng.c:122
BOOL g_bInternalHooksUsed
Definition: shimeng.c:36
#define SHIM_REASON_DLL_LOAD
Definition: shimlib.h:47
ULONG Flags
Definition: ntddk_ex.h:207
uint32_t * LPDWORD
Definition: typedefs.h:59
HMODULE g_hInstance
Definition: MainWindow.cpp:18
HOOKAPIEX g_IntHookEx[]
Definition: shimeng.c:43
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
static VOID SeiAddFlag(PDB pdb, TAGID tiFlagRef, PFLAGINFO pFlagInfo)
Definition: shimeng.c:439
BOOLEAN NTAPI LdrInitShimEngineDynamic(IN PVOID BaseAddress)
Definition: ldrapi.c:1677
#define SeiAlloc(size)
Definition: shimeng.h:101
static char * dest
Definition: rtl.c:135
static VOID SeiAddShim(TAGREF trShimRef, PARRAY pShimRef)
Definition: shimeng.c:428
const char * PCSTR
Definition: typedefs.h:52
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
DWORD TAGID
#define TAG_FLAG_MASK_USER
Definition: sdbtagid.h:117
VOID SeiCombineHookInfo(VOID)
Definition: shimeng.c:727
VOID SeiInitDebugSupport(VOID)
Definition: shimeng.c:128
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
BOOL WINAPI SdbUnpackAppCompatData(HSDB hsdb, LPCWSTR pszImageName, PVOID pData, PSDBQUERYRESULT pQueryResult)
Definition: hsdb.c:761
PVOID SeiGetModuleFromAddress(PVOID addr)
Definition: shimeng.c:246
BOOL WINAPI SdbTagRefToTagID(HSDB hsdb, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich)
Definition: hsdb.c:638
BOOL WINAPI SE_IsShimDll(PVOID BaseAddress)
Definition: shimeng.c:1474
DWORD MaxSize__
Definition: shimeng.h:19
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
BYTE * PBYTE
Definition: pedump.c:66
static DWORD SeiGetDWORD(PDB pdb, TAGID tag, TAG type)
Definition: shimeng.c:410
#define ARRAY_At(Array, TypeOfArray, at)
Definition: shimeng.c:124
base of all file and directory entries
Definition: entries.h:82
int(* FARPROC)()
Definition: compat.h:36
static int mod
Definition: i386-dis.c:1289
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
static VOID SeiSetLayerEnvVar(LPCWSTR wszLayer)
Definition: shimeng.c:456
HMODULE hModule
Definition: animate.c:44
PSHIMMODULE SeiCreateShimModuleInfo(PCWSTR DllName, PVOID BaseAddress)
Definition: shimeng.c:294
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
VOID SeiCheckComPlusImage(PVOID BaseAddress)
Definition: shimeng.c:271
char * tag
Definition: main.c:59