Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

567 lines
18 KiB

  1. /*++
  2. Copyright (c) 2002- Microsoft Corporation
  3. Module Name:
  4. w64shim.c
  5. Abstract:
  6. This module implement Handle redirection for registry redirection.
  7. Author:
  8. ATM Shafiqul Khalid (askhalid) 12-March-2002
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <ntregapi.h>
  17. #include "psapi.h"
  18. #define _WOW64REFLECTOR_
  19. #include "regremap.h"
  20. #include "wow64reg.h"
  21. #include "wow64reg\reflectr.h"
  22. #ifdef _WOW64DLLAPI_
  23. #include "wow64.h"
  24. #else
  25. #define ERRORLOG 1 //this one is completely dummy
  26. #define LOGPRINT(x)
  27. #define WOWASSERT(p)
  28. #endif //_WOW64DLLAPI_
  29. //HANDLE hIsDel = INVALID_HANDLE_VALUE;
  30. HANDLE h_IsDel;
  31. BOOL
  32. InitWow64Shim ( )
  33. /*++
  34. Routine Description:
  35. Initialize Shim engine for wow64.
  36. Arguments:
  37. None.
  38. Return Value:
  39. TRUE if the function succeed.
  40. FALSE otherwise.
  41. <TBD> this might allocate more memory and free up later.
  42. --*/
  43. {
  44. PPEB Peb = NtCurrentPeb ();
  45. PUNICODE_STRING Name = &Peb->ProcessParameters->ImagePathName;
  46. if ((Name->Length > 22) && (_wcsnicmp ( Name->Buffer + (Name->Length/2)-11, L"\\_isdel.exe",11) == 0)) {
  47. //
  48. // Image is _isdel.exe
  49. OBJECT_ATTRIBUTES ObjectAttributes;
  50. NTSTATUS Status;
  51. IO_STATUS_BLOCK statusBlock;
  52. UNICODE_STRING FileNameU;
  53. //
  54. // Open the file
  55. //
  56. if (!RtlDosPathNameToNtPathName_U(Name->Buffer,
  57. &FileNameU,
  58. NULL,
  59. NULL)) {
  60. // probably out-of-memory
  61. return FALSE;
  62. }
  63. InitializeObjectAttributes(&ObjectAttributes,
  64. &FileNameU,
  65. OBJ_CASE_INSENSITIVE,
  66. NULL,
  67. NULL);
  68. Status = NtOpenFile(&h_IsDel,
  69. FILE_READ_DATA,
  70. &ObjectAttributes,
  71. &statusBlock,
  72. 0, //FILE_SHARE_READ, //don't share
  73. 0);
  74. //
  75. // Nothing much we can do if the operation fails, its a plain hack.
  76. //
  77. RtlFreeHeap(RtlProcessHeap(), 0, FileNameU.Buffer);
  78. }
  79. return TRUE;
  80. }
  81. BOOL
  82. CloseWow64Shim ()
  83. {
  84. //
  85. // close all the resources allocated during shim Init.
  86. //
  87. if ( h_IsDel != INVALID_HANDLE_VALUE ) {
  88. NtClose (h_IsDel);
  89. h_IsDel = INVALID_HANDLE_VALUE;
  90. }
  91. return TRUE;
  92. }
  93. #ifdef DBG
  94. NTSTATUS
  95. LogDriverAccess (
  96. IN POBJECT_ATTRIBUTES ObjectAttributes
  97. )
  98. /*++
  99. Routine Description:
  100. If the application if trying to access driver [.sys] file, this API will dump a warning
  101. message in the debugger. In the long run this routine might call some API to include
  102. appropriate message to the event log so that administrator can diagnose this instance.
  103. In general creating 32bit driver files (mostly installation) on IA64 doesn't make any
  104. sense at all and admin might need to know what are those files and which apps are touhing
  105. them.
  106. Arguments:
  107. ObjectAttributes - object application is trying to access.
  108. Return Value:
  109. None.
  110. --*/
  111. {
  112. WCHAR DriverNameBuff[MAX_PATH];
  113. WCHAR ImageNameBuff[MAX_PATH];
  114. DWORD CopyLength;
  115. //
  116. // Those definition will move in a header file while logging event.
  117. //
  118. #define WOW64_DRIVER_EXT_NAME L".sys"
  119. #define WOW64_DRIVER_EXT_NAME_LENGTH (sizeof (WOW64_DRIVER_EXT_NAME)/sizeof(WCHAR) - 1 )
  120. try {
  121. if ( ( ObjectAttributes->ObjectName->Length > ( WOW64_DRIVER_EXT_NAME_LENGTH << 1 ))
  122. && !_wcsnicmp ( ObjectAttributes->ObjectName->Buffer - WOW64_DRIVER_EXT_NAME_LENGTH + (ObjectAttributes->ObjectName->Length>>1), WOW64_DRIVER_EXT_NAME, WOW64_DRIVER_EXT_NAME_LENGTH)) {
  123. PPEB Peb = NtCurrentPeb ();
  124. PUNICODE_STRING ImageName;
  125. RTL_UNICODE_STRING_BUFFER DosNameStrBuf;
  126. UNICODE_STRING NtNameStr;
  127. if (Peb->ProcessParameters == NULL)
  128. return STATUS_SUCCESS;
  129. ImageName = &Peb->ProcessParameters->ImagePathName;
  130. RtlInitUnicodeStringBuffer(&DosNameStrBuf, 0, 0);
  131. CopyLength = min (ObjectAttributes->ObjectName->Length, sizeof (DriverNameBuff) - sizeof (UNICODE_NULL)); //skip \??\ ==>8 byte
  132. RtlCopyMemory (DriverNameBuff, (PBYTE)ObjectAttributes->ObjectName->Buffer + ObjectAttributes->ObjectName->Length - CopyLength, CopyLength);
  133. DriverNameBuff[CopyLength>>1] = UNICODE_NULL; //make sure NULL terminated
  134. RtlInitUnicodeString(&NtNameStr, DriverNameBuff);
  135. if ( NT_SUCCESS(RtlAssignUnicodeStringBuffer(&DosNameStrBuf, &NtNameStr)) &&
  136. NT_SUCCESS(RtlNtPathNameToDosPathName(0, &DosNameStrBuf, NULL, NULL))) {
  137. DosNameStrBuf.String.Buffer[DosNameStrBuf.String.Length>>1] = UNICODE_NULL; // make sure NULL terminated is case it has been formatted.
  138. //
  139. // Extract Image name
  140. //
  141. ImageNameBuff[0] = UNICODE_NULL;
  142. if (ImageName->Length >0) {
  143. ASSERT (ImageName->Buffer != NULL);
  144. CopyLength = min (ImageName->Length, sizeof (ImageNameBuff) - sizeof (UNICODE_NULL));
  145. RtlCopyMemory (ImageNameBuff, (PBYTE)ImageName->Buffer + ImageName->Length - CopyLength, CopyLength);
  146. ImageNameBuff[CopyLength>>1] = UNICODE_NULL; //make sure NULL terminated
  147. }
  148. LOGPRINT((ERRORLOG,"Wow64-driver access warning: [%S] is a 32bit application trying to create/access 32bit driver [%S]\n", ImageNameBuff, DosNameStrBuf.String.Buffer));
  149. //
  150. // BUGBUG: deny access to write files.
  151. // Check file creation flag and also \drivers string.
  152. //
  153. return STATUS_ACCESS_DENIED;
  154. }
  155. RtlFreeUnicodeStringBuffer(&DosNameStrBuf);
  156. }
  157. } except( EXCEPTION_EXECUTE_HANDLER){
  158. return STATUS_SUCCESS;
  159. }
  160. return STATUS_SUCCESS;
  161. }
  162. #endif
  163. BOOL
  164. CheckAndThunkFileName (
  165. IN OUT POBJECT_ATTRIBUTES ObjectAttributes,
  166. IN OUT PULONG pShareAccess,
  167. IN ULONG DesiredAccess,
  168. IN ULONG Option,
  169. IN ULONG DespositionFlag,
  170. IN ULONG CallFlag //0 for NtOpenFile and 1- for NtCreateFile
  171. )
  172. {
  173. NTSTATUS Ret;
  174. PUNICODE_STRING Name = ObjectAttributes->ObjectName;
  175. PUNICODE_STRING NewName = NULL;
  176. //
  177. // Check if any install shield stuff
  178. // Following code should be active in the process that does deal with 16bit process.
  179. // Need to initialize some flag possibly NtVdm64
  180. //
  181. try {
  182. //
  183. // filter access for scripbuilder that pass
  184. // (ShareAccess= 0, DesAcc = 0x80100080, Options 0x60, Desposition = 1) that need to be failed
  185. // and (7, 0x100100, 204020, 0) and (7, 10080, 204040, 0) that doesn't need redirection
  186. //
  187. if (*pShareAccess == 0x7)
  188. return FALSE; //shared delete don't need any redirection
  189. //
  190. //
  191. //
  192. if (CallFlag == 0) // Don't redirect OpenCall for the time being this was a hack for Scriptbuilder
  193. return FALSE;
  194. if ((Name->Length > 22) && (_wcsnicmp ( Name->Buffer + (Name->Length/2)-11, L"\\_isdel.exe",11) == 0)) {
  195. // Check if the name is \_isdel.exe
  196. PPEB Peb = NtCurrentPeb ();
  197. PUNICODE_STRING ImageName = &Peb->ProcessParameters->ImagePathName;
  198. if (
  199. (ImageName->Length > 36) && //check if its scriptbuilder
  200. (_wcsnicmp ( ImageName->Buffer + (ImageName->Length/2)-18, L"\\scriptbuilder.exe",18) == 0)
  201. ) {
  202. //
  203. // The memory allocation contains a terminating NULL character, but the
  204. // Unicode string's Length does not.
  205. //
  206. SIZE_T SystemRootLength = wcslen(USER_SHARED_DATA->NtSystemRoot);
  207. SIZE_T NameLength = sizeof(L"\\??\\")-sizeof(WCHAR) +
  208. SystemRootLength*sizeof(WCHAR) +
  209. sizeof(L'\\') +
  210. sizeof(WOW64_SYSTEM_DIRECTORY_U)-sizeof(WCHAR) +
  211. sizeof(L"\\InstallShield\\_isdel.exe");
  212. NewName = Wow64AllocateTemp(sizeof(UNICODE_STRING)+NameLength);
  213. NewName->Length = (USHORT)NameLength-sizeof(WCHAR);
  214. NewName->MaximumLength = NewName->Length;
  215. NewName->Buffer = (PWSTR)(NewName+1);
  216. wcscpy(NewName->Buffer, L"\\??\\");
  217. wcscpy(&NewName->Buffer[4], USER_SHARED_DATA->NtSystemRoot);
  218. NewName->Buffer[4+SystemRootLength] = '\\';
  219. wcscpy(&NewName->Buffer[4+SystemRootLength+1], WOW64_SYSTEM_DIRECTORY_U);
  220. wcscpy(&NewName->Buffer[4+SystemRootLength+1+(sizeof(WOW64_SYSTEM_DIRECTORY_U)-sizeof (UNICODE_NULL))/sizeof(WCHAR)], L"\\InstallShield\\_isdel.exe");
  221. ObjectAttributes->ObjectName = NewName;
  222. ObjectAttributes->RootDirectory = NULL;
  223. //
  224. // DbgPrint ("\nPatched _isDel.exe Flag %x, %x, %x, %x, %x", *pShareAccess, DesiredAccess, Option, DespositionFlag, CallFlag);
  225. //
  226. if ( pShareAccess != NULL )
  227. *pShareAccess = 0;
  228. }
  229. } //if check _isdel
  230. } except( NULL, EXCEPTION_EXECUTE_HANDLER){
  231. return FALSE;
  232. }
  233. return TRUE;
  234. }
  235. NTSTATUS
  236. Wow64NtCreateFile(
  237. OUT PHANDLE FileHandle,
  238. IN ACCESS_MASK DesiredAccess,
  239. IN POBJECT_ATTRIBUTES ObjectAttributes,
  240. OUT PIO_STATUS_BLOCK IoStatusBlock,
  241. IN PLARGE_INTEGER AllocationSize OPTIONAL,
  242. IN ULONG FileAttributes,
  243. IN ULONG ShareAccess,
  244. IN ULONG CreateDisposition,
  245. IN ULONG CreateOptions,
  246. IN PVOID EaBuffer OPTIONAL,
  247. IN ULONG EaLength
  248. )
  249. /*++
  250. Routine Description:
  251. This service opens or creates a file, or opens a device. It is used to
  252. establish a file handle to the open device/file that can then be used
  253. in subsequent operations to perform I/O operations on. For purposes of
  254. readability, files and devices are treated as "files" throughout the
  255. majority of this module and the system service portion of the I/O system.
  256. The only time a distinction is made is when it is important to determine
  257. which is really being accessed. Then a distinction is also made in the
  258. comments.
  259. Arguments:
  260. FileHandle - A pointer to a variable to receive the handle to the open file.
  261. DesiredAccess - Supplies the types of access that the caller would like to
  262. the file.
  263. ObjectAttributes - Supplies the attributes to be used for file object (name,
  264. SECURITY_DESCRIPTOR, etc.)
  265. IoStatusBlock - Specifies the address of the caller's I/O status block.
  266. AllocationSize - Initial size that should be allocated to the file. This
  267. parameter only has an affect if the file is created. Further, if
  268. not specified, then it is taken to mean zero.
  269. FileAttributes - Specifies the attributes that should be set on the file,
  270. if it is created.
  271. ShareAccess - Supplies the types of share access that the caller would like
  272. to the file.
  273. CreateDisposition - Supplies the method for handling the create/open.
  274. CreateOptions - Caller options for how to perform the create/open.
  275. EaBuffer - Optionally specifies a set of EAs to be applied to the file if
  276. it is created.
  277. EaLength - Supplies the length of the EaBuffer.
  278. Return Value:
  279. The function value is the final status of the create/open operation.
  280. --*/
  281. {
  282. NTSTATUS Ret;
  283. #ifdef DBG
  284. Ret = LogDriverAccess ( ObjectAttributes);
  285. if (!NT_SUCCESS (Ret))
  286. return Ret;
  287. #endif
  288. if ( CreateDisposition == FILE_OPEN ){
  289. CheckAndThunkFileName (
  290. ObjectAttributes,
  291. &ShareAccess,
  292. DesiredAccess,
  293. CreateOptions,
  294. CreateDisposition,
  295. 1
  296. );
  297. }
  298. Ret = NtCreateFile(
  299. FileHandle,
  300. DesiredAccess,
  301. ObjectAttributes,
  302. IoStatusBlock,
  303. AllocationSize,
  304. FileAttributes,
  305. ShareAccess,
  306. CreateDisposition,
  307. CreateOptions,
  308. EaBuffer,
  309. EaLength
  310. );
  311. return Ret;
  312. }
  313. NTSTATUS
  314. Wow64NtOpenFile(
  315. OUT PHANDLE FileHandle,
  316. IN ACCESS_MASK DesiredAccess,
  317. IN POBJECT_ATTRIBUTES ObjectAttributes,
  318. OUT PIO_STATUS_BLOCK IoStatusBlock,
  319. IN ULONG ShareAccess,
  320. IN ULONG OpenOptions
  321. )
  322. {
  323. NTSTATUS Ret;
  324. CheckAndThunkFileName (
  325. ObjectAttributes,
  326. &ShareAccess,
  327. DesiredAccess,
  328. OpenOptions,
  329. 0,
  330. 0
  331. );
  332. Ret = NtOpenFile(
  333. FileHandle,
  334. DesiredAccess,
  335. ObjectAttributes,
  336. IoStatusBlock,
  337. ShareAccess,
  338. OpenOptions
  339. );
  340. return Ret;
  341. }
  342. /****************************************************************************/
  343. #define TOTAL_GUARD_REGION_RESERVE 0x3000 //64K memory
  344. #define SIGNATURE_SIZE 0x1000 //a small window in the reserved region to put signature
  345. DWORD dwCount=0;
  346. DWORD dwCountMax=0x5000;
  347. NTSTATUS
  348. Wow64DbgNtAllocateVirtualMemory (
  349. IN HANDLE ProcessHandle,
  350. IN OUT PVOID *BaseAddress,
  351. IN ULONG_PTR ZeroBits,
  352. IN OUT PSIZE_T RegionSize,
  353. IN ULONG AllocationType,
  354. IN ULONG Protect
  355. )
  356. {
  357. NTSTATUS St;
  358. NTSTATUS St1;
  359. PVOID Base1=NULL;
  360. SIZE_T RegionSizeExtra = 0;
  361. if ((dwCount++ > dwCountMax) && (*BaseAddress == NULL) && (MEM_RESERVE & AllocationType) && (*RegionSize = 0x10000 )) {
  362. *RegionSize +=TOTAL_GUARD_REGION_RESERVE;
  363. RegionSizeExtra = TOTAL_GUARD_REGION_RESERVE;
  364. //DbgPrint ("Guard page %x %x A:%x P:%x\n", *BaseAddress, *RegionSize, AllocationType, Protect);
  365. }
  366. St = NtAllocateVirtualMemory (
  367. ProcessHandle,
  368. BaseAddress,
  369. ZeroBits,
  370. RegionSize,
  371. AllocationType,
  372. Protect
  373. );
  374. if (NT_SUCCESS (St) && RegionSizeExtra ) {
  375. //
  376. // Commit some pages and return memory in the middle
  377. //
  378. SIZE_T R1 = SIGNATURE_SIZE;
  379. PWCHAR Name;
  380. Base1 = *BaseAddress;
  381. *BaseAddress = (PVOID)((ULONGLONG)(*BaseAddress)+RegionSizeExtra);
  382. *RegionSize -=TOTAL_GUARD_REGION_RESERVE;
  383. St1 = NtAllocateVirtualMemory (
  384. ProcessHandle,
  385. &Base1,
  386. ZeroBits,
  387. &R1,
  388. MEM_COMMIT,
  389. PAGE_READWRITE
  390. );
  391. //
  392. // Write the signature
  393. //
  394. if (NT_SUCCESS (St1)) {
  395. Name = (PWCHAR)(Base1);
  396. wcscpy (Name, L"ATM Shafiqul Khalid");
  397. }
  398. } //if extra region is to be committed.
  399. return St;
  400. }
  401. NTSTATUS
  402. Wow64DbgNtFreeVirtualMemory(
  403. IN HANDLE ProcessHandle,
  404. IN OUT PVOID *BaseAddress,
  405. IN OUT PSIZE_T RegionSize,
  406. IN ULONG FreeType
  407. )
  408. {
  409. NTSTATUS st;
  410. PVOID Base1;
  411. PWCHAR Name = (PWCHAR)(((ULONGLONG)*BaseAddress)-TOTAL_GUARD_REGION_RESERVE);
  412. MEMORY_BASIC_INFORMATION MemoryInformation;
  413. if ((dwCount > dwCountMax) && (MEM_RELEASE & FreeType)) {
  414. try {
  415. st = NtQueryVirtualMemory(ProcessHandle,
  416. Name,
  417. MemoryBasicInformation,
  418. &MemoryInformation,
  419. sizeof(MEMORY_BASIC_INFORMATION),
  420. NULL);
  421. if (NT_SUCCESS(st) && MemoryInformation.State == MEM_COMMIT)
  422. if (wcsncmp (Name, L"ATM Shafiqul Khalid", 20 )==0) {
  423. *RegionSize += TOTAL_GUARD_REGION_RESERVE;
  424. *BaseAddress = (PVOID)((ULONGLONG)(*BaseAddress)-TOTAL_GUARD_REGION_RESERVE);
  425. //DbgPrint ("#########Freeing Guarded Memory#########");
  426. }
  427. } except( NULL, EXCEPTION_EXECUTE_HANDLER){
  428. ;
  429. }
  430. }
  431. st = NtFreeVirtualMemory(
  432. ProcessHandle,
  433. BaseAddress,
  434. RegionSize,
  435. FreeType
  436. );
  437. return st;
  438. }