ReactOS  0.4.14-dev-77-gd9e7c48
vmhorizon.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS 'Layers' Shim library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Shim for VMWare Horizon setup
5  * COPYRIGHT: Copyright 2017 Thomas Faber (thomas.faber@reactos.org)
6  * Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
7  */
8 
9 #define WIN32_NO_STATUS
10 #include <windef.h>
11 #include <winbase.h>
12 #include <shimlib.h>
13 #include "ntndk.h"
14 
16 {
19  ULONG OldProtection;
21  if (NT_SUCCESS(Status))
22  {
23  SIZE_T Bytes;
25  if (NT_SUCCESS(Status) && Bytes != Size)
27  NtProtectVirtualMemory(NtCurrentProcess(), &BaseAddress, &RegionSize, OldProtection, &OldProtection);
28  }
29  return NT_SUCCESS(Status);
30 }
31 
32 static void FixupDll(PLDR_DATA_TABLE_ENTRY LdrEntry)
33 {
34  static const UCHAR Match1[5] = { 0x0C, 0x8B, 0xFC, 0xF3, 0xA5 };
35  static const UCHAR Match2[5] = { 0x0C, 0x8B, 0xFC, 0xF3, 0xA5 };
36  static const UCHAR Match3[5] = { 0xB0, 0x8B, 0xFC, 0xF3, 0xA5 };
37  UCHAR Replacement1[5] = { 0x10, 0x89, 0x34, 0x24, 0x90 };
38  UCHAR Replacement2[5] = { 0x10, 0x89, 0x34, 0x24, 0x90 };
39  UCHAR Replacement3[5] = { 0xB4, 0x89, 0x34, 0x24, 0x90 };
40 #define OFFSET_1 0x21A6E
41 #define OFFSET_2 0x21B04
42 #define OFFSET_3 0x21C3C
43 
44 
45  UCHAR Buffer[5];
46  PBYTE Base = LdrEntry->DllBase;
47  SIZE_T Bytes;
48 
49  /*
50  00020E6E: 0C 8B FC F3 A5 --> 10 89 34 24 90 F11A6E - ef0000 = 21A6E
51  00020F04: 0C 8B FC F3 A5 --> 10 89 34 24 90 F11B04 - ef0000 = 21B04
52  00021C3C: B0 8B FC F3 A5 --> B4 89 34 24 90 F11C3C - ef0000 = 21C3C
53  */
54  do {
55  DbgPrint("Module %wZ Loaded at 0x%p, we should patch!\n", &LdrEntry->BaseDllName, LdrEntry->DllBase);
57  break;
58  if (memcmp(Buffer, Match1, sizeof(Match1)))
59  break;
60 
62  break;
63  if (memcmp(Buffer, Match2, sizeof(Match2)))
64  break;
65 
67  break;
68  if (memcmp(Buffer, Match3, sizeof(Match3)))
69  break;
70 
71  DbgPrint("Module %wZ Loaded at 0x%p, OK to patch!\n", &LdrEntry->BaseDllName, LdrEntry->DllBase);
72  if (!Write(Base + OFFSET_1, Replacement1, sizeof(Replacement1)))
73  break;
74  if (!Write(Base + OFFSET_2, Replacement2, sizeof(Replacement2)))
75  break;
76  if (!Write(Base + OFFSET_3, Replacement3, sizeof(Replacement3)))
77  break;
78 
80 
81  DbgPrint("Module %wZ Loaded at 0x%p, patched!\n", &LdrEntry->BaseDllName, LdrEntry->DllBase);
82  } while (0);
83 }
84 
86 {
87  PWCHAR pc1;
88  PWCHAR pc2;
89  ULONG NumChars;
90 
91  if (String2->Length < String1->Length)
92  return FALSE;
93 
94  if (!String1->Buffer || !String2->Buffer)
95  return FALSE;
96 
97  NumChars = String1->Length / sizeof(WCHAR);
98  pc1 = String1->Buffer;
99  pc2 = String2->Buffer + (String2->Length / sizeof(WCHAR)) - NumChars;
100 
101  while (NumChars--)
102  {
104  return FALSE;
105  }
106 
107  return TRUE;
108 }
109 
110 #define SHIM_NS VMHorizonSetup
111 #include <setup_shim.inl>
112 
113 #define SHIM_NUM_HOOKS 0
114 #define SHIM_NOTIFY_FN SHIM_OBJ_NAME(Notify)
115 
116 BOOL WINAPI SHIM_OBJ_NAME(Notify)(DWORD fdwReason, PVOID ptr)
117 {
118  if (fdwReason == SHIM_REASON_DLL_LOAD)
119  {
120  static const UNICODE_STRING DllPrefix = RTL_CONSTANT_STRING(L"msi");
121  static const UNICODE_STRING DllPostfix = RTL_CONSTANT_STRING(L".tmp");
122  PLDR_DATA_TABLE_ENTRY LdrEntry = ptr;
123 
124  BOOLEAN Prefix = RtlPrefixUnicodeString(&DllPrefix, &LdrEntry->BaseDllName, TRUE);
125  BOOLEAN Postfix = PostfixUnicodeString(&DllPostfix, &LdrEntry->BaseDllName);
126  ULONG ExtraChars = (LdrEntry->BaseDllName.Length - DllPrefix.Length - DllPostfix.Length) / sizeof(WCHAR);
127 
128  /* msiN[N].tmp */
129  if (Prefix && Postfix && ExtraChars <= 2)
130  {
133  {
134  SHIM_MSG("Module %wZ is a match, applying fixups\n", &LdrEntry->BaseDllName);
135  FixupDll(LdrEntry);
136  }
137  }
138  }
139  return TRUE;
140 }
141 
142 #include <implement_shim.inl>
static const unsigned char pc2[48]
Definition: des.c:68
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
static const unsigned char pc1[56]
Definition: des.c:54
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define DbgPrint
Definition: loader.c:25
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
#define OFFSET_1
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
_In_ UINT Bytes
Definition: mmcopy.h:9
static void FixupDll(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: vmhorizon.c:32
#define OFFSET_3
uint16_t * PWCHAR
Definition: typedefs.h:54
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
Definition: vmhorizon.c:116
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID DllBase
Definition: btrfs_drv.h:1784
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:2919
static PVOID ptr
Definition: dispmode.c:27
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
Definition: bufpool.h:45
#define NtCurrentProcess()
Definition: nt_native.h:1657
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SHIM_MSG(fmt,...)
Definition: shimlib.h:75
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2691
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
Definition: btrfs_drv.h:1780
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:382
static BOOLEAN PostfixUnicodeString(const UNICODE_STRING *String1, const UNICODE_STRING *String2)
Definition: vmhorizon.c:85
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define OFFSET_2
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define RtlImageNtHeader
Definition: compat.h:457
_In_ const STRING * String2
Definition: rtlfuncs.h:2261
#define SHIM_REASON_DLL_LOAD
Definition: shimlib.h:47
unsigned int ULONG
Definition: retypes.h:1
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
Definition: virtual.c:2805
BYTE * PBYTE
Definition: pedump.c:66
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14