[Wine-patches] [eter-1.0.10 2/5] ntoskrnl.exe: Prevent crash of some Katran programs.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Июн 5 13:02:58 MSD 2009


---
 dlls/ntoskrnl.exe/ntoskrnl.c |   57 ++++++++++++++++++++++++++++--------------
 1 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index fd371bf..8a74616 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -135,6 +135,8 @@ struct HandleInstance
 #define IOCTL_WINE_DRIVER_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, \
         METHOD_BUFFERED, FILE_ANY_ACCESS)
 
+#define UPKEY_NKEY_DATA_SIZE 8192
+
 #ifdef __i386__
 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
     __ASM_GLOBAL_FUNC( name, \
@@ -450,44 +452,61 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
     LARGE_INTEGER count;
     IO_STATUS_BLOCK iosb;
     HANDLE process = NULL;
-    CHAR data[146];
+    CHAR *data = NULL;
     void *saved_ptr = NULL;
-    ULONG offset = 0;
+    ULONG offset = 0, offset2 = 0;
 
     TRACE( "ioctl %x device %p in_size %u out_size %u\n", code, device, in_size, *out_size );
 
+    /* HACK for UPKey.sys and NKey.sys */
+    if (0x3fc == code) offset = 2;
+    else if (0x222040 == code || 0x222044 == code || 0x222048 == code ||
+             0x22204c == code || 0x222060 == code || 0x222100 == code ||
+             0x222104 == code || 0x222108 == code || 0x222110 == code ||
+             0x222118 == code || 0x222120 == code ||
+             0x44c == code || 0x456 == code)
+        offset = 8;
+    else if (0x2220d8 == code)
+    {
+        offset = 14;
+        offset2 = 8;
+    }
+    if (offset && in_buff)
+    {
+        data = HeapAlloc( GetProcessHeap(), 0, UPKEY_NKEY_DATA_SIZE );
+        if (data == NULL) return STATUS_NO_MEMORY;
+        saved_ptr = *(void**)((char *)in_buff + offset);
+        *(void**)((char *)in_buff + offset) = data;
+        if (offset2)
+            *(void**)((char *)in_buff + offset2) = data +
+                    (*(char**)((char *)in_buff + offset2) - (char *)saved_ptr);
+        process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, get_pid() );
+        if (process != NULL)
+            NtReadVirtualMemory( process, saved_ptr, data, UPKEY_NKEY_DATA_SIZE, NULL );
+    }
+
     irp = IoBuildDeviceIoControlRequest( code, device, in_buff, in_size,
             out_buff, *out_size, FALSE, NULL, &iosb );
     if (irp == NULL)
-        return STATUS_NO_MEMORY;
+    {
+        status = STATUS_NO_MEMORY;
+        goto end;
+    }
     irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation - 1;
     irp->RequestorMode = UserMode;
     irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
     irpsp->DeviceObject = device;
     device->CurrentIrp = irp;
 
-    /* HACK for UPKey.sys */
-    if (0x3fc == code) offset = 2;
-    if (0x222044 == code || 0x44c == code || 0x456 == code) offset = 8;
-    if (offset && in_buff)
-    {
-        saved_ptr = *(void**)((char *)in_buff + offset);
-        if (saved_ptr)
-        {
-            *(void**)((char *)in_buff + offset) = &data;
-            process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, get_pid() );
-            if (process != NULL)
-                NtReadVirtualMemory( process, saved_ptr, data, sizeof(data), NULL );
-        }
-    }
-
     KeQueryTickCount( &count );  /* update the global KeTickCount */
     status = IoCallDriver( device, irp );
+end:
     if (process)
     {
-        NtWriteVirtualMemory( process, saved_ptr, data, sizeof(data), NULL );
+        NtWriteVirtualMemory( process, saved_ptr, data, UPKEY_NKEY_DATA_SIZE, NULL );
         CloseHandle( process );
     }
+    if (data) HeapFree( GetProcessHeap(), 0, data );
     *out_size = (status >= 0) ? iosb.Information : 0;
     return status;
 }
-- 
1.6.3.1



Подробная информация о списке рассылки Wine-patches