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