win-pvdrivers

changeset 700:377647b4097a

First attempt at lower level hooking of DbgPrint and ASSERT.
Doesn't work under Windows 2003 x64 though - PatchGuard catches any attempt to hook interrupt vector 0x2D
author James Harper <james.harper@bendigoit.com.au>
date Wed Nov 25 21:39:51 2009 +1100 (2009-11-25)
parents bdabcc424aec
children c3e410ac288f
files xenpci/amd64/dbgprint_hook.asm xenpci/i386/dbgprint_hook.asm xenpci/sources xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_dbgprint.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xenpci/amd64/dbgprint_hook.asm	Wed Nov 25 21:39:51 2009 +1100
     1.3 @@ -0,0 +1,46 @@
     1.4 +
     1.5 +;nt!DebugPrint:
     1.6 +;mov     r9d,r8d
     1.7 +;mov     r8d,edx
     1.8 +;mov     dx,word ptr [rcx]
     1.9 +;mov     rcx,qword ptr [rcx+8]
    1.10 +;mov     eax,1
    1.11 +;int     2Dh
    1.12 +
    1.13 +public Int2dHandlerOld
    1.14 +
    1.15 +extrn Int2dHandlerProc: proc
    1.16 +
    1.17 +.code
    1.18 +Int2dHandlerNew proc
    1.19 +  ;pushf
    1.20 +  push rax
    1.21 +  push rcx
    1.22 +  push rdx
    1.23 +  push r8
    1.24 +  push r9
    1.25 +  push r10
    1.26 +  push r11
    1.27 +  sub rsp, 56
    1.28 +  mov QWORD PTR [rsp + 32], r9
    1.29 +  mov r9, r8
    1.30 +  mov r8, rdx
    1.31 +  mov rdx, rcx
    1.32 +  mov rcx, rax
    1.33 +  call Int2dHandlerProc
    1.34 +  add rsp, 56
    1.35 +  pop r11
    1.36 +  pop r10
    1.37 +  pop r9
    1.38 +  pop r8
    1.39 +  pop rdx
    1.40 +  pop rcx
    1.41 +  pop rax
    1.42 +  ;popf
    1.43 +  jmp QWORD PTR [Int2dHandlerOld]
    1.44 +Int2dHandlerNew endp
    1.45 +
    1.46 +.data
    1.47 +Int2dHandlerOld QWORD 1
    1.48 +
    1.49 +END
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xenpci/i386/dbgprint_hook.asm	Wed Nov 25 21:39:51 2009 +1100
     2.3 @@ -0,0 +1,33 @@
     2.4 +
     2.5 +.586P
     2.6 +.model	flat
     2.7 +
     2.8 +public _Int2dHandlerNew@0
     2.9 +public _Int2dHandlerOld
    2.10 +
    2.11 +extern _Int2dHandlerProc@20 : near
    2.12 +
    2.13 +.code
    2.14 +
    2.15 +_Int2dHandlerNew@0 proc
    2.16 +	pushfd
    2.17 +	push	eax
    2.18 +	push	ecx
    2.19 +	push	edx
    2.20 +	push	edi
    2.21 +	push	ebx
    2.22 +	push	edx
    2.23 +	push	ecx
    2.24 +	push	eax
    2.25 +	call	_Int2dHandlerProc@20
    2.26 +	pop edx
    2.27 +	pop ecx
    2.28 +	pop eax
    2.29 +	popfd
    2.30 +	jmp dword ptr cs:[_Int2dHandlerOld]
    2.31 +_Int2dHandlerNew@0 endp
    2.32 +
    2.33 +.data
    2.34 +_Int2dHandlerOld DWORD 1
    2.35 +
    2.36 +END
     3.1 --- a/xenpci/sources	Wed Nov 25 21:36:58 2009 +1100
     3.2 +++ b/xenpci/sources	Wed Nov 25 21:39:51 2009 +1100
     3.3 @@ -3,8 +3,12 @@ TARGETNAME=xenpci
     3.4  TARGETTYPE=DRIVER
     3.5  KMDF_VERSION_MAJOR=1
     3.6  NTTARGETFILES=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(TARGETNAME).inf
     3.7 -TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib $(DDK_LIB_PATH)\..\..\wlh\*\aux_klib.lib
     3.8 -AMD64_SOURCES=hypercall.asm
     3.9 -I386_SOURCES=tpr_emulate.asm
    3.10 +TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib \
    3.11 +           $(DDK_LIB_PATH)\..\..\wlh\*\aux_klib.lib
    3.12 +AMD64_SOURCES=hypercall.asm dbgprint_hook.asm
    3.13 +I386_SOURCES=tpr_emulate.asm dbgprint_hook.asm
    3.14  
    3.15 -SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c xenpci_dma.c evtchn.c gnttbl.c xenbus.c memory.c xenpci_device_interface.c xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c
    3.16 +SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c xenpci_dma.c evtchn.c \
    3.17 +        gnttbl.c xenbus.c memory.c xenpci_device_interface.c \
    3.18 +        xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c \
    3.19 +        xenpci_dbgprint.c
     4.1 --- a/xenpci/xenpci.c	Wed Nov 25 21:36:58 2009 +1100
     4.2 +++ b/xenpci/xenpci.c	Wed Nov 25 21:39:51 2009 +1100
     4.3 @@ -34,6 +34,7 @@ XenPci_EvtDeviceUsageNotification(WDFDEV
     4.4    FUNCTION_ENTER();
     4.5    
     4.6    UNREFERENCED_PARAMETER(device);
     4.7 +  UNREFERENCED_PARAMETER(is_in_notification_path);
     4.8  
     4.9    switch (notification_type)
    4.10    {
    4.11 @@ -562,28 +563,6 @@ XenPci_FixLoadOrder()
    4.12    return;
    4.13  }
    4.14  
    4.15 -KBUGCHECK_CALLBACK_RECORD callback_record;
    4.16 -
    4.17 -static VOID
    4.18 -XenPci_BugcheckCallback(PVOID buffer, ULONG length)
    4.19 -{
    4.20 -  NTSTATUS status;
    4.21 -  KBUGCHECK_DATA bugcheck_data;
    4.22 -  
    4.23 -  UNREFERENCED_PARAMETER(buffer);
    4.24 -  UNREFERENCED_PARAMETER(length);
    4.25 -  
    4.26 -  bugcheck_data.BugCheckDataSize  = sizeof(bugcheck_data);
    4.27 -  status = AuxKlibGetBugCheckData(&bugcheck_data);
    4.28 -  if(!NT_SUCCESS(status))
    4.29 -  {
    4.30 -    KdPrint((__DRIVER_NAME "     AuxKlibGetBugCheckData returned %08x\n", status));
    4.31 -    return;
    4.32 -  }
    4.33 -  KdPrint((__DRIVER_NAME "     Bug check 0x%08X (0x%p, 0x%p, 0x%p, 0x%p)\n",
    4.34 -    bugcheck_data.BugCheckCode, bugcheck_data.Parameter1, bugcheck_data.Parameter2, bugcheck_data.Parameter3, bugcheck_data.Parameter4));
    4.35 -}
    4.36 -
    4.37  NTSTATUS
    4.38  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    4.39  {
    4.40 @@ -602,7 +581,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    4.41    
    4.42    UNREFERENCED_PARAMETER(RegistryPath);
    4.43  
    4.44 -  KdPrint((__DRIVER_NAME " " VER_FILEVERSION_STR));
    4.45 +  KdPrint((__DRIVER_NAME " " VER_FILEVERSION_STR "\n"));
    4.46  
    4.47    FUNCTION_ENTER();
    4.48  
    4.49 @@ -612,12 +591,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    4.50      KdPrint((__DRIVER_NAME "     AuxKlibInitialize failed %08x - expect a crash soon\n", status));
    4.51    }
    4.52    
    4.53 -  KeInitializeCallbackRecord(&callback_record);
    4.54 -  if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
    4.55 -  {
    4.56 -    KdPrint((__DRIVER_NAME "     KeRegisterBugCheckCallback failed\n"));
    4.57 -  }
    4.58 -
    4.59 +  XenPci_HookDbgPrint();
    4.60 +  
    4.61    XenPci_FixLoadOrder();
    4.62  
    4.63    RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
     5.1 --- a/xenpci/xenpci.h	Wed Nov 25 21:36:58 2009 +1100
     5.2 +++ b/xenpci/xenpci.h	Wed Nov 25 21:39:51 2009 +1100
     5.3 @@ -463,6 +463,9 @@ XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTIO
     5.4  VOID
     5.5  XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
     5.6  
     5.7 +NTSTATUS
     5.8 +XenPci_HookDbgPrint();
     5.9 +
    5.10  struct xsd_sockmsg *
    5.11  XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
    5.12  char *
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xenpci/xenpci_dbgprint.c	Wed Nov 25 21:39:51 2009 +1100
     6.3 @@ -0,0 +1,183 @@
     6.4 +/*
     6.5 +PV Drivers for Windows Xen HVM Domains
     6.6 +Copyright (C) 2007 James Harper
     6.7 +
     6.8 +This program is free software; you can redistribute it and/or
     6.9 +modify it under the terms of the GNU General Public License
    6.10 +as published by the Free Software Foundation; either version 2
    6.11 +of the License, or (at your option) any later version.
    6.12 +
    6.13 +This program is distributed in the hope that it will be useful,
    6.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 +GNU General Public License for more details.
    6.17 +
    6.18 +You should have received a copy of the GNU General Public License
    6.19 +along with this program; if not, write to the Free Software
    6.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.21 +*/
    6.22 +
    6.23 +#include "xenpci.h"
    6.24 +#include <aux_klib.h>
    6.25 +
    6.26 +#pragma intrinsic(_enable)
    6.27 +#pragma intrinsic(_disable)
    6.28 +
    6.29 +#pragma pack(1)
    6.30 +#ifdef _AMD64_
    6.31 +typedef struct __KIDT_ENTRY
    6.32 +{
    6.33 +  USHORT addr_0_15;
    6.34 +  USHORT selector;
    6.35 +  USHORT access;
    6.36 +  USHORT addr_16_31;
    6.37 +  ULONG  addr_32_63;
    6.38 +  ULONG  reserved;
    6.39 +} IDT_ENTRY, *PIDT_ENTRY;
    6.40 +#else
    6.41 +typedef struct __KIDT_ENTRY
    6.42 +{
    6.43 +  USHORT addr_0_15;
    6.44 +  USHORT selector;
    6.45 +  USHORT access;
    6.46 +  USHORT addr_16_31;
    6.47 +} IDT_ENTRY, *PIDT_ENTRY;
    6.48 +#endif
    6.49 +#pragma pack()
    6.50 +
    6.51 +#pragma pack(2)
    6.52 +typedef struct _IDT
    6.53 +{
    6.54 +  USHORT limit;
    6.55 +  PIDT_ENTRY entries;
    6.56 +} IDT, *PIDT;
    6.57 +#pragma pack()
    6.58 +
    6.59 +//typedef void (*PDBGPRINT_CALLBACK_FUNCTION)(IN PANSI_STRING String, IN ULONG ComponentId, IN ULONG Level);
    6.60 +//typedef NTSTATUS (*PDBG_SET_DEBUGPRINT_CALLBACK)(PDBGPRINT_CALLBACK_FUNCTION Function, IN BOOLEAN Mode);
    6.61 +
    6.62 +KBUGCHECK_CALLBACK_RECORD callback_record;
    6.63 +
    6.64 +extern VOID Int2dHandlerNew(VOID);
    6.65 +extern PVOID Int2dHandlerOld;
    6.66 +
    6.67 +static VOID
    6.68 +XenPci_BugcheckCallback(PVOID buffer, ULONG length)
    6.69 +{
    6.70 +  NTSTATUS status;
    6.71 +  KBUGCHECK_DATA bugcheck_data;
    6.72 +  
    6.73 +  UNREFERENCED_PARAMETER(buffer);
    6.74 +  UNREFERENCED_PARAMETER(length);
    6.75 +  
    6.76 +  bugcheck_data.BugCheckDataSize  = sizeof(bugcheck_data);
    6.77 +  status = AuxKlibGetBugCheckData(&bugcheck_data);
    6.78 +  if(!NT_SUCCESS(status))
    6.79 +  {
    6.80 +    KdPrint((__DRIVER_NAME "     AuxKlibGetBugCheckData returned %08x\n", status));
    6.81 +    return;
    6.82 +  }
    6.83 +  KdPrint((__DRIVER_NAME "     Bug check 0x%08X (0x%p, 0x%p, 0x%p, 0x%p)\n",
    6.84 +    bugcheck_data.BugCheckCode, bugcheck_data.Parameter1, bugcheck_data.Parameter2, bugcheck_data.Parameter3, bugcheck_data.Parameter4));
    6.85 +}
    6.86 +
    6.87 +static BOOLEAN debug_port_enabled = FALSE;
    6.88 +
    6.89 +static void XenDbgPrint(PCHAR string, ULONG length)
    6.90 +{
    6.91 +  ULONG i;
    6.92 +  KIRQL old_irql = 0;
    6.93 +
    6.94 +  KeRaiseIrql(HIGH_LEVEL, &old_irql);
    6.95 +  for (i = 0; i < length; i++)
    6.96 +    WRITE_PORT_UCHAR(XEN_IOPORT_LOG, string[i]);
    6.97 +  KeLowerIrql(old_irql);
    6.98 +}
    6.99 +
   6.100 +VOID
   6.101 +Int2dHandlerProc(ULONG_PTR dbg_type, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
   6.102 +{
   6.103 +  CHAR buf[512];
   6.104 +
   6.105 +  switch (dbg_type)
   6.106 +  {
   6.107 +  case 1: /* DbgPrint */
   6.108 +    XenDbgPrint((PCHAR)arg2, (ULONG)(ULONG_PTR)arg3);
   6.109 +    break;
   6.110 +  case 2: /* ASSERT */
   6.111 +  case 3: /* ??? */
   6.112 +  case 4: /* ??? */
   6.113 +    break;
   6.114 +  default:
   6.115 +    RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "*** %d %08x %08x %08x %08x\n", dbg_type, arg2, arg3, arg4, arg5);
   6.116 +    XenDbgPrint(buf, (ULONG)strlen(buf));
   6.117 +    break;
   6.118 +  }
   6.119 +  return;
   6.120 +}
   6.121 +
   6.122 +static VOID
   6.123 +XenPci_DbgPrintCallback(PSTRING output, ULONG component_id, ULONG level)
   6.124 +{
   6.125 +  UNREFERENCED_PARAMETER(component_id);
   6.126 +  UNREFERENCED_PARAMETER(level);
   6.127 +  
   6.128 +  XenDbgPrint(output->Buffer, output->Length);
   6.129 +}
   6.130 +
   6.131 +NTSTATUS
   6.132 +XenPci_HookDbgPrint()
   6.133 +{
   6.134 +  NTSTATUS status = STATUS_SUCCESS;
   6.135 +#if (NTDDI_VERSION < NTDDI_VISTA)
   6.136 +#ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
   6.137 +  IDT idt;
   6.138 +  PIDT_ENTRY idt_entry;
   6.139 +  KIRQL old_irql;
   6.140 +#endif
   6.141 +#endif  
   6.142 +  if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
   6.143 +    || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
   6.144 +  {
   6.145 +    //#pragma warning(suppress:4055)
   6.146 +    //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
   6.147 +#if (NTDDI_VERSION >= NTDDI_VISTA)
   6.148 +    KdPrint((__DRIVER_NAME "     DbgSetDebugPrintCallback found\n"));
   6.149 +    DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, TRUE);
   6.150 +#else
   6.151 +    KdPrint((__DRIVER_NAME "     DbgSetDebugPrintCallback not found\n"));      
   6.152 +#ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
   6.153 +    idt.limit = 0;
   6.154 +    __sidt(&idt);
   6.155 +    idt_entry = &idt.entries[0x2D];
   6.156 +    _disable();
   6.157 +    KeRaiseIrql(HIGH_LEVEL, &old_irql);
   6.158 +    #ifdef _AMD64_ 
   6.159 +    Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16) | ((ULONG_PTR)idt_entry->addr_32_63 << 32));
   6.160 +    #else
   6.161 +    Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16));
   6.162 +    #endif
   6.163 +    idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerNew;
   6.164 +    idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerNew >> 16);
   6.165 +    #ifdef _AMD64_ 
   6.166 +    idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerNew >> 32);
   6.167 +    #endif
   6.168 +    KeLowerIrql(old_irql);
   6.169 +    _enable();
   6.170 +#endif
   6.171 +#endif
   6.172 +  }
   6.173 +  else
   6.174 +  {
   6.175 +    status = STATUS_UNSUCCESSFUL;
   6.176 +  }
   6.177 +  
   6.178 +  KeInitializeCallbackRecord(&callback_record);
   6.179 +  if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
   6.180 +  {
   6.181 +    KdPrint((__DRIVER_NAME "     KeRegisterBugCheckCallback failed\n"));
   6.182 +    status = STATUS_UNSUCCESSFUL;
   6.183 +  }
   6.184 +
   6.185 +  return status;
   6.186 +}